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

I'm not sure why Yegge is talking about the Shangri-la of non-local exits, but... He is right that the culture of Clojure has some issues and often rejects ideas even when they're obvious, and it's not clear why.

Examples I've run into:

1. The current clojure lambda shortcut-syntax is atrocious, and we can do better. Why don't we do better?

2. Clojure could really benefit from a scheme-esque Macro-by-example library. A few exist but they seem largely ignored by the community; despite well-known-benefits to such a system in the normal daily use of macros.

3. A strange hatred of macros. Yes, some people are reasonable and argue that functions should have primacy over macros because of composability (and they're right). But then there are people who will tell you macros are always bad, and if you show up in freenode #clojure to ask for help with them they will actively laugh at you.

I love Clojure and I feel like I know it pretty well, so I'm not trying to say Clojure is considered harmful, etc. But I do think that some of Yegge's criticisms—while poorly delivered and sometimes poorly expressed—have an element of truth to them.

* Full disclosure: I was involved in an effort to write a Clojure book for O'Reilly until I got involved with a new startup and had to terminate my involvement in the effort. I may not be the most unbiased judge of Clojure.




if you show up in freenode #clojure to ask for help with them they will actively laugh at you

Oh dear. That is a bad sign. It has always seemed to me that building a healthier community from the ground up was the biggest thing a successful new Lisp would have to offer. The behavior you describe is all too reminiscent. No one should ever be "actively laughed at" for asking an honest question, and Clojure experts (if they know what's good for them) ought to take an aggressive stance against that kind of behavior. These communities are delicate things. They can become diseased.

It makes me mad to see anyone get "actively laughed at", let alone by bullies who assuage the beast of their own insecurity by doing the intellectual equivalent of beating up children.

Edit: oh, and: they're being laughed at for asking about macros? This is a Lisp, right?


The best way to deal with trolls is to simply not feed them. My experience on Clojure IRC the past 3 years is that its orders of magnitude less condescending than the Python, Ruby, or Node.js IRC channels.


I won't name names, but you'd know the names I could name. It is true that, so long as you stay away from a few key third rails, the #clojure channel is generally a great place. One need only to go to #scala on a bad day to see what a few bad actors can do to make a place feel oppressive.

There's no value in such arguments tho. It's an undeniable truth that the Clojure community (and its libraries) are far less macro-friendly and macro-centric than other lisps. Even PLT Scheme seems more comfortable with defmacro usage.


There's a joke here about Scala and actors, I'm just sure of it.


Oh good. That's exactly what I was hoping someone who knows would say.

Edit: I'm not talking about trolls, though, but about respected members of a community acting this way. If bullying is confined to trolls, along with all the other bad things trolls do, that's a healthy sign.


> if you show up in freenode #clojure to ask for help with them they will actively laugh at you.

#clojure has consistently been one of the most helpful resources for me, and the most helpful IRC channel I've ever been in. I've never seen anyone laughed at there.


That is a silly thing to say. I've never seen a language that had such a friendly community. I don't think that in my two years of being active in the Clojure community, I have ever seen a single person get 'laughed at' for any reason at all.

Sure, there are trolls every now and then. You can't control everybody. The ratio of trolls to helpful participants is excellent and always has been.


1. I'm curious as to what you think would be better?

2. Would be nice, but I think a high level of macro-understanding is not broadly distributed yet in the Clojure community, so scheme-esque macro libraries for most people seem like "yet another thing to learn".

3. I don't find this to be the case in general at all.


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.


Within any culture there are individuals who will act like dickweeds. Likewise, not every feature that you propose is likely to be accepted. Are these cultural problems?


I'm not saying someone in #clojure was a meanie, therefore clojure is doomed.


I'm not trying to give you a hard time, I really am curious about the answer. These kinds of discussions tend to be anecdotal (understandably so) or too nebulous and so I'm trying to dive deeper.


Examples:

I'll be honest: the direction 1.3 went was not a direction I saw as valuable.

Similarly, I felt like the 1.2 work on protocols and datatypes was about 3/5 of what a person would need to use them in general programming. I've talked with some people I consider experts in Clojure and they suggested to me they have some similar feelings.

The community dislike of macros, and a curious insistance on using the most difficult and bug-prone version (not to mention least debuggable) of a macro implementation is another example of a troubling bias in the direction of clojure.

I am not a genius, nor do I claim to have superior information on which direction Clojure should go. All I have is my biases and intuitions, but I don't think I'm alone in their current values.


What exactly did you not like about 1.3? It's faster and a lot numeric stuff no longer needs to be written Java.

As far as 1.2, the only thing I find lacking around protocols and datatypes is reader support and a default constructor fn.

As far as community dislike of macros, I'm not convinced.

I also don't see anything stopping anyone from submitting their CA and pitching a friendlier macro front-end. But as far I can tell most people in the Clojure community are not familiar with Scheme style macros. You'd have to come up with the code, write the tutorials, and market your approach. That it's a lot of work is the only reason I see that it hasn't been done yet - not because anyone is against the idea.


There is a spike of scheme-esque macros for Clojure here:

https://github.com/qbg/syntax-rules

Not sure of the status/quality of that impl, but there you go.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: