3 ms·
Experience building open src projects crowdfunding site in Clojure (from Django)
- saurik 14y agoSome of the comments in here are inaccurate. Clojure actually does not have very good anonymous function syntax (as well evidenced by the confusion the author of this mailing list post had with returning vectors: that syntax isn't even really "anonymous functions" but is more "expression templates/lambadas"), which causes macros (a construct that isn't actually first-class in this kind of language, leading to bizarre and bothersome failures to compose primitives) to be used in many places where functional programming would serve better (as the core special forms--like if--take implicitly in evaluated arguments in a language that is otherwise strict call-by-value rather than anonymous functions, you then need macros to build syntax similar to them). In point of fact, using Python decorators solves the specific problem indicated by this article quite well (and that's how I was handling that same problem in Python before my recent switch to Clojure, which while not perfect by any stretch of the imagination is still one of my favorite languages to date).
- aaron-lebo 14y agoThanks for your comment. I'm not shocked if I stated some inaccurate things; I'm still very new to the language, and how and even why some things work the way they do is not obvious to me. So the #() syntax is a reader macro I'm assuming? That would explain a lot. I guess what I enjoyed about them is that they cut down on a lot of boilerplate. In javascript, passing in an anonymous function, you have to explicitly name the arguments. So you've got something like: map(function(item) {item + 2}, list)) In Clojure you can gut that down to: (map #(+ % 2) lst) This isn't that useful for small code snippets, but if you reuse that variable many times, or use multiple variables such as map-indexed, that %, %2, and so on syntax is really friendly. But I could see why there would be limitations. You can't nest them, for one. You probably are well-aware of these things, but my explanation might make some sense to those who haven't used the language.
- saurik 14y ago(Quick note: I had meant "unevaluated", but got iPhone-autocorrected with whatever it was I had typed to "in evaluated".) Right. However, #((+ % 2)) would be the same idea for functions instead of expressions, and would then have allowed you to use that syntax to build and return a vector. You can still build a vector, but you now have to realize that [] is a reader macro for (vector), so you can do #(vector 1 %) instead of #([1 %]). However, if there was really great anonymous function syntax (maybe {} declaring a function with no arguments), then if wouldn't be a special form: it would be an internal function that took a boolean and two functions. The result of that change would then trickle through all kinda of other macros (as they could then be implemented as functions instead), and soon you end up with a language that no longer relies on so much non-first-class syntax edits.