Hacker News new | past | comments | ask | show | jobs | submit login

1. Scala certainly has a better in-place lambda syntax. Way better.

     //; someNumbers is a vector of numbers
     someNumbers.reduceLeft( _ + _ )
     (reduce #(+ %1 %2) someNumbers)

     //; A more complex example
     someNumbers.foldLeft(0)(_ + _ * 2)
     (reduce #(+ %1 (* 2 %2)) 0 someNumbers)
I'm fluent in prefix notation, but I still have to watch the clojure code that uses #() very carefully.

2. I think that Macros By Example would be a better tool for teaching macro than the raw compiler extensions that defmacro provides. MBE is easier, not harder. Defmacro is the machinery, not the interface for most tasks.

3. I won't name names, but I've had high-profile people in #clojure do exactly this to me. And when I barked back, I was told to not be rude. It was a terrible experience caused by a prominent member of #clojure who otherwise seems like a smart individual. I've since received commiserations from people who have faced similar condemnations.

(note: added simplified example)




> I'm fluent in prefix notation, but I still have to watch the clojure code that uses #() very carefully.

I think part of this is to encourage you to think about whether another approach would be more appropriate.

Any time I have a #() form with more than three or four tokens in it, it could almost always be better expressed as a private defn or a for expression. And sometimes comp or partial is more appropriate, provided it's still only a handful of functions involved.


I agree. The wildcard syntax from Scala breaks down just as quickly (and in fact allows fewer possible expressions since it doesn't appreciate nesting).

I see these restrictions and simplifications as a feature.


What is so unreadable about '#(+ %1 (* 2 %2))'? Can Scala use arguments in an order other than the order in which they're given? If not, then Scala's simplicity is at the cost of less flexibility.

If you find that too hairy, just write '(fn [a b] (+ a (* 2 b)))'. The shortcut syntax is intended for simple cases.


This kind of attitude is what frustrates me.

The clojure version is obviously more noisy. Your argument is that the #() syntax is more robust (i.e., allowing multiple references to a single argument, and repeats of an argument). While strictly true, you then go on to invalidate it by saying, "The shortcut syntax is intended for simple cases." I feel like this is a resistance to change that is more a product of the rivalry between Scala and Clojure than anything else (and please forgive me if I am projecting onto you, but that's how arguing on the internet goes).

Additional complexity or capability at the cost of a perlesque show should not be the mission of a convenience syntax. Scala has taken a lot of good ideas from Clojure, it seems only fair that Clojure pull back a little. What's more, it's not very hard to write a macro that does most of what the wildcard syntax does... but without access to the reader's symbol macros it's very difficult to make that kind of change grow into the community.


I don't see any resistance to change; it's more like Clojure folks are generally going to demand that changes be unequivocally positive. I remember the fixed-position args in Scala function literals being particularly irritating in certain circumstances; whatever one's gripe about the chosen sigils, being able to write #(%2 %) is damn handy.

This widespread Scala/Clojure rift is a myth AFAICT, outside of various spitball fights on Twitter.

Oh, and if you want to have userland reader macros in Clojure, have at it: http://briancarper.net/blog/449/clojure-reader-macros ;-)


I've been learning Scala and after being initially excited by Scala's _ notation, I'm disappointed by how often I end up resorting to the long form for expressions that feel simple.

Also, I think Clojure's syntax for the 1st argument, 2nd argument, etc. is more intuitive. I mean, the second _ doesn't refer to the same argument as the first _? That violates all my instincts as a programmer. I was completely baffled by it until it was explained to me, and it still seems very clunky, because it forces me to declare names for arguments more often than I would like to. In my opinion, the Clojure way is immediately obvious and more concise (because it can be used in many cases where Scala requires named arguments.) It's just better all around, for any expression more complicated than { _ + _ }.


I am not an accredited Clojure style expert, but I wouldn't (defensibly) use the shortcut syntax in an any more complicated way than calling a function, providing missing arguments and rearranging those that have been passed. So, something like this:

    (frob #(mumble :foo %2 %1) bar)
Anything more complicated, I'd either use `fn' or define a free-standing function.

I'm not disputing that the Clojure community has assholes, though I've hung out on #clojure a fair amount and no one springs to mind. But the `fn' shortcut sugar seems like a completely reasonable design. The design choice, however, does encourage the adoption of certain conventions.


your frustrated by people who have different priorities than you do? Who values you things differently?

when you start using words like 'obviously', it really doesn't speak well of the comments to follow. noisy? beautiful? elegant? these are all aesthetic judgements. for you to say something is obviously more noisy is to place your judgement about others and to discount the validity of their view- that kind of attitude frustrates me.


> someNumbers.reduceLeft( _ + _ )

> (reduce #(+ %1 %2) someNumbers)

In math, you can write:

  f(x,y)= x+2y
  A= {1,2,3}
  reduce(f, A)
A more readable syntax for people who did math at school could be:

  reduce(x+2y, SomeNumbers)


Frankly, I'd prefer:

    %1 + %2 * 2
Over:

    _ + _ * 2
With the former syntax, it's much more obvious what the function is doing.


Why?


Because _ and _ refer to two different values using the same name. Adding a third _ would refer to yet another value, etc.


Not to be excessively glib, but I can't resist pointing out that children successfully comprehend this notation daily, it's called "fill in the blank."


It's not a matter of it not being comprehensible once you know what's going on; it's a matter of consistency with the rest of the language. Everywhere else, each symbol refers to one and only one value within a given lexical context. Breaking from that expectation would require some compelling benefits.


Well, does it mean:

    (x, y) -> x + y
Or:

    (x) -> x + x
If I didn't know the language, I'd assume the latter, so it fails the principle of least surprise (at least for me).


1. Comon, that nip picking. The clojure one has more feature (reordering, %&) more and you have to write 3 more chars because of it. I think thats not a bad traid. How cares about these 3 chars?

2. I don't know what that is and I never saw a anouncment something like that on the mailing list. If somebody wirtes something like that and put it on the mailinglist im sure people will pick it up.

3. Im in #clojure often and I never even heard something like that. Sure often people say "macros should not be uses in that case" but often enought I saw how people heroiclly showed new programmers how to do macros.


Re: 1. In your Scala example the two underscores are placeholders for two different arguments. The underscore is also used in Scala for catch all clauses with 'match'. How is this syntax then way better than %1 and %2 for arguments in shorthand syntax in Clojure?


how does scala handle the case where the order of arguments to the lambda is not the same as the order in which they appear in its body?


It doesn't. Use a real lambda. Why? See: http://news.ycombinator.com/item?id=2468038


I've seen too much code where lambdas do little more than twiddle argument orders. I'd rather pay a tiny bit more visual weight for straightforward argument usage and be able to use the same tool to reorder them.

The Scala version seems (to me) like it praises its own purity over day-to-day utility.


I'm not a Clojure programmer but I disagree on point 1. My advise (if it's a huge sticking point) would be to allow both forms.


Sorry to pick nits but the clojure example could be:

    (reduce + some-numbers)


Sorry to pick nits, but you magnificently managed to completely miss his point.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: