5 ms·
Oddly, as someone who was reasonably into Common Lisp, what really viscerally turned me off to Clojure was the use of square brackets. This sounds petty but I
by phs2501 9y ago
Oddly, as someone who was reasonably into Common Lisp, what really viscerally turned me off to Clojure was the use of square brackets.
This sounds petty but I actually have some rationalization for it. Once you learn to read Lisp (mostly looking at the indentation and ignoring the parens) it's really nice that there's only one kind of delimiter in the language. It allows a lot of easy structure editing with a decent editor. I had emacs set up to use the unshifted square bracket keys to create and exit balanced parenthesis pairs. Once you got used to this, this was really pleasant to write and mutate code.
As soon as I saw Clojure, I knew that my setup would unavoidably get twice as complicated because they added another delimiter that's used in random places in the code. (Why are function arguments a vector instead of a list? Just because the designer thinks it looks better? Why are let bindings a vector? Why are ordinary function calls and function bodies a list? It just feels arbitrary.) That in and of itself really turned me off. (The fact that it's the JVM really didn't help either, but that was actually secondary to the above.)
Other issues for me were the lack of two layers in the LET statement (i.e. it's (let [a 1 b 2] ...) rather than (let ((a 1) (b 2)) ...). To some that probably "looks better" but it kills the ability to use emacs's transpose-sexps to swap the order of your let bindings around.
All in all the syntax just didn't seem well thought out to me. OTOH to non-lispers it probably looked better, so maybe that was the goal.
- deleted 9y ago[deleted]
- dragandj 9y agoRegarding the second point, why didn't you just define your own let macro? As a Java->Clojure guy I find better readability of Clojure's let compared to CL's support of transpose an acceptable tradeoff, but the point of being a lisp is that you are not constrained by all decisions of the boss?
- phs2501 9y agoWell yes, in theory, but it's generally considered in somewhat bad taste to replace fundamental basics of the language. At that point you're not really writing Clojure anymore, it's hard to read other people's code, it's hard for other people to read your code, etc. See the somewhat controversial Allegro CL IF* macro for an example of this (I think that's what it was called; turns out that's really hard to search for). It's a little different if you're either creating a domain-specific language (at that point you've already made the decision to have a new language, so go nuts) or if you're adding new control structures that you can't have in the base language without excessive boilerplate (see for example the somewhat common AIF macro, which binds its conditional result to a variable). But I'd consider making a new MY-LET macro because I don't like what the built-in LET looked like to be a bit gauche. Regardless, I just decided to stick with the Lisp dialect that already worked the way I wanted.
- saurik 9y agoUsing an entirely different language because you don't want to use the macro features of the language you are using to modify a small detail due to it feeling "a bit gauche" seems much more extreme to me than just making that change... FWIW, I work with an old-school Lisp/Scheme hacker who learned at MIT and worked with some of "the greats", and he has often argued that if I really wanted Lisp to look like anything I said I liked that day I should have just done that with Lisp as at least then we would be using the same underlying execution engine, and he never seemed to feel it was "a bit gauche".
- tjalfi 9y agoThe source to if* is at (https://franz.com/~jkf/ifstar.txt https://franz.com/~jkf/ifstar.txt).
- kbp 9y agoI agree, the decrease in editor-friendliness is really frustrating, coming from Lisp. The lack of parens around cond clauses is also annoying to me, because it makes it so that you can't really insert a newline after a predicate for legibility, since it makes the then-part flush with the other predicates (and similarly for let bindings).
- saurik 9y agoI don't understand: why can't you add a newsline andan indent? (cond (whatever) (thing) (something) (more))
- kbp 9y agoThere's nothing preventing you from manually doing that when you type the code, but editors and pretty-printers won't know about it. Special-casing them to have "if the car of a list is cond, or this vector was preceded by let, ..., then every second element gets extra indentation if it's on a different line" vs just using the regular list formatting rules just squicks me.
- saurik 9y agoFWIW, running code through machine-formatting is an idea that squicks me enough that I hadn't even considered that you would be trying to do that... :(.
- _halgari 9y agoWhat's interesting is that for me Clojure was my first lisp. One of the main reasons I never learned lisp before Clojure was all the parens that made the language impossible to read. Clojure cleans up the "normal" lisp syntax quite a bit, and that made it a lot more palatable. Beauty is in the eye, and all that, but CL code still makes me want to claw my eyes out.
- TeMPOraL 9y agoDim the parens in your editor. It helps if you're not used to them already.
- agentgt 9y agoPeople complain about the parens in Lisp but what kills me about Lisp in general is not the parens but the fact your brains has to read the code from bottom to top and/or right to left. This is because of prefix notation. And while I do not like object oriented languages its far more natural to English readers such as myself to write and read things from top to bottom and left to write. Now of course some FP languages have operators to (Haskell, F#) to allow left to right function application and you could of course make macros in Lisp in whole it doesn't really fix the problem entirely. You can also of course mitigate the above with judicious use of let expressions but more often than not people inline anyway.
- agumonkey 9y agoI feel the same. Clojure had lots of valuable reasons for using [] but it made it step one foot aside from the lispiness I got to like; and it's not really about editor support it's something else.. I kinda loved the idea of sexp being 99% of the idea of lisp.
- justinhj 9y agoAs a former CL dabbler I didn't mind the square brackets in let but I really liked the use of them for vector and curly braces for map. To me bringing two useful data structures beyond lists into the language syntax felt very powerful and simple.
- kbp 9y agoCommon Lisp does have syntax for vectors, they're written #(1 2 3). It doesn't have literal syntax for hash tables, but it's a trivial read-macro if you can't live without it (although alists have some other nice properties like easy shadowing/popping of bindings, and the kind of associations you would want to write as literals are generally small enough that their O(n) lookup isn't a problem). CLTL2 gives a rationale for using #(...) instead of [...] for vectors: Many people have suggested that brackets be used to notate vectors, as [a b c] instead of #(a b c). This notation would be shorter, perhaps more readable, and certainly in accord with cultural conventions in other parts of computer science and mathematics. However, to preserve the usefulness of the user-definable macro-character feature of the function read, it is necessary to leave some characters to the user for this purpose. Experience in MacLisp has shown that users, especially implementors of languages for use in artificial intelligence research, often want to define special kinds of brackets. Therefore Common Lisp avoids using brackets and braces for any syntactic purpose.