Thanks for all of the comments on ease of learning Python vs. Clojure. The jury’s still out …
On whether Clojure might, in theory, be as easy to learn as Python–well I still don’t really know Python, but I have given further thought to what’s involved in learning Clojure. I now think that there isn’t a simple answer to a question about how easy or hard Clojure is to learn. It depends on what part of the language you’re talking about. Here are some illustrations, all my own opinions, of course.
Background: In other languages, assignment is a simple concept: Change the value of something–that’s simple. Arrays are simple concepts: how far into a sequence is it? Looping by incrementing an index is a little more complicated, but you already had to understand the basic tools you need for a simple loop. More complex loops are more complicated, but that can’t be helped.
Now for Clojure:
Functional updating of defrecords
and maps: I think this is simple. It’s confusing at first if you’re used to assignment, but I think that’s an artifact of learning imperative languages first.
Functional updating of sequences, in general: I’d make the same point.
reduce
is not a simple concept, and you can’t understand it without understanding all of its parts at once.
map
is simpler, but still not as conceptually simple as assignment; you have to understand that the “same” thing, in some sense, will be done to each element of a sequence.
conj
: This is a little confusing, because you have to know what you’re operating on to know where you’re adding the element, but the idea of adding an element to a sequence is utterly simple.
next
vs. rest
: Yeah, that’s confusing. But the underlying concept that they share is simple.
range
and a large collection of sequence processing functions: iterate
, repeat
, repeatedly
, take
, drop
, cycle
, partition
, etc. Most of these are pretty simple, and though some are a little bit complex, that’s just because what they do is complex. You do have to remember (or look up) the names, but I don’t see how one could have names that were much better, unless you want to replace the names with names such as
repeat-the-same-object-as-is-in-a-sequence
sequence-composed-of-results-of-applying-the-same-no-arg-function-repeatedly
sequence-composed-of-the-results-of-iteratively-applying-a-function-to-the-previous-element-of-the-sequence
Laziness: Definitely confusing–if not at first, then soon, when it bites you. And keeping track of whether you’re holding onto the head of a large sequence feels like keeping track of state in an imperative program. I’m not saying that it’s the same thing, but the mental energy required seems similar to me.
Recursion: I know this confuses a lot of people at first–I have known pretty good programmers who were afraid of it–but with a good introduction like The Little Schemer, it’s not hard to get the hang of it. And explicit, full-fledged recursion isn’t that common in Clojure, I think. loop/recur
, as its name indicates, can be understood either as a loop or as recursion.
(I agree that function naming matters, but I personally don’t think Clojure is bad in that regard. Not perfect, but not bad. Compared to Common Lisp, Clojure is close to perfect. A lot of the useful functions do things that, in English, might be described in a similar way, so some arbitrariness is unavoidable.)