6 ms·
The author claims this first article is satire, but in case you were tempted to take it literally, allow me to rebut: Why not simply add support for concurrent
by aphyr 14y ago
The author claims this first article is satire, but in case you were tempted to take it literally, allow me to rebut:
Why not simply add support for concurrent programming as a library instead?
Clojure's concurrency primitives are libraries. You don't have to use them; it's perfectly OK to use, say, kilim or java.util.concurrent, and many do.
Why not provide both immutable and mutable versions of the same data types?
The mutable variants of these structures are already there in java.util, and the stdlib is designed to interact well with java interfaces like List, Map, etc. [1]
Also when writing real-world software, what about the effort required to align the multitude of Java libraries that assume an imperative environment with Clojure?
I've used nontrivial Java libraries in Clojure: it looks about the same as the Java code, only shorter and with fewer parentheses. Yes, fewer.
Can these libraries be used easily, safely and with the same performance?
Yes. Obviously the Clojure parts won't run quite as fast as the Java parts, but interop is complete, concise, and well-designed. InvokeVirtual is InvokeVirtual either way.
Meanwhile Clojure makes obvious improvements over CL in reader forms for readability: the vector, set, map, and regex literals make it much easier to write and understand. It may not be as pure as some other Lisps, but it's a competent addition to the family.
[1] A property I miss in Scala. :-(
- agentultra 14y agoMeanwhile Clojure makes obvious improvements over CL I would beg to differ. The features you note are pretty subjective and not obvious improvements at all. I've done a few small non-trivial prototypes in Clojure. I cannot stand the syntax for literals. Or the mangled hell that is the literal for lambda. At least CL lets you define your own reader macros -- something that Clojure cannot do (yet). These features you mention are not improvements over CL IMO.
- aphyr 14y agoHuh, I find the syntax for literals a breath of fresh air--but I also grew up in languages with rich data structure literals and find the {}, (), [], #"", #{} distinctions make it much easier for me to understand, at a glance, the shape of a structure. I also prefer the vector notation for arguments in (fn [arg1 arg2 & friends])--the brackets make it easier to recognize the argument boundaries, especially in one-liners. In general, Clojure code seems to have less nesting, which makes it easier for me to read and parse. You're honestly the first person I've heard express a dislike for the reader forms, so I thought it was universally liked. I think you're right: a lack of configurable reader macros is a problem. I'd also point to the lack of tail recursion (and consequent mucking about with (recur) and (trampoline) as a notable flaw in Clojure. Its error messages are pathologically malicious. On the other hand, I think Clojure's packaging environment, thanks to lein and clojars, is quite good. There also seems to be more consistency in Clojure coding... style? preference? than in CL, which I attribute partly to its young age and small user base, but also, perhaps, to a more opinionated set of attitudes around mutability and types. Regarding the #() form, I almost never reach for it, partly because it never seems to work as expected. (fn) and (partial) feel more natural to me, so I've never taken the time to understand how #() works. I also prefer Lisp-1s in general, although I understand that's a more contentious differentiation. Either way, my CL experience is minimal, so it was wrong of me to claim these as obvious improvements. I'll defer to your expertise here: it sounds like you've used CL enough to understand it better.