One thing I tend to miss in Clojure is lack of TCO. Most people(like me), come to Lisp from SICP, The Little Schemer and PG's books. Where recursion is not just emphasized, you are actually trained to think recursively.
I found lack of TCO to be a little like a stick in the neck when it comes to both Clojure and Emacs Lisp. It prevents you from thinking in the way you have been thinking in other Lisps.
I understand Clojure depends on JVM and JVM doesn't do tail call eliminations yet, and Rich Hickey is right in thinking that method calls are too much a platform thing and we shouldn't be working around this limitation with a hack. However lack of TCO in Emacs Lisp is a little not easy to live with. From what I understand patches have been submitted to Emacs to make this happen but haven't made it to the upstream.
TCO is very important for any language that sells functional programming these days. Apart from the performance advantages, Recursion is a thought framework. Limitations are not easy to live with.
I hope some day Clojure and Emacs Lisp get TCO.
On a tangential note, JVM is a great platform, its a also a widely used platform, so changes are going to come in very slowly. So I'm not holding my breath waiting for TCO.
Most mainline Lisps either never did support TCO or only in some restricted way. The reason for that is that it clashes with other widely used language features in typical Lisps. There is a cost to supporting TCO - also a less nice debugging experience. Many CL compilers tend to support it with some restrictions - CL interpreters often not. Lisp Machines did not support it. CL on the JVM does not support it. https://0branch.com/notes/tco-cl.html
I started with Scheme and Lisp (Standard Lisp, ZetaLisp, CL, ...) and wrote/used TCO a lot. I tend to view the use of TCO for basic iteration as a mistake, which makes code harder to read. I tend to like either higher-order iterative constructs or powerful iteration constructs like CL's ITERATE: https://common-lisp.net/project/iterate/
>>I tend to view the use of TCO for basic iteration as a mistake, which makes code harder to read.
I understand some one like you is far more experienced and has been around for a long time. So obviously you know better than I ever will. And you are right. Even with very minimal Lisp exposure, after using Scheme and Common Lisp, Clojure's TCO thing feels unacceptable.
In fact after using Common Lisp, and I'm a novice, even some one like me feels Common Lisp to be a far superior language compared to other Lisps around.
The issue is, like I said, I started learning lisp starting with Scheme, and I started recently. First book was SICP, second was 'The Little Schemer', third was 'The Seasoned Schemer'. At that point your brain is hard programmed to think in terms of recursion, and whenever I see loops my mind moves to recursion automatically. You have to trust me when I say this, when I read PG's ANSI Common Lisp book , I skipped the sections on iterations and loops, because I thought I would never use them anyway.
I have to say those Schemer books do their job really well.
May be I just need more practice, so I will develop more stuff in Clojure, now that its not even possible to do that Clojure, eventually that TCO addiction should go away.
The plain self-recursion part is not that great - especially one needs to write code in that TCO style. General TCO is a bit more - every tail call is a jump. I find it for example useful to have TCO code as low-level target for example for macros.
You have read a good selection of Scheme books. It's very useful to explore that style of programming and be able to really understand. Take it only as a hint, that there is more out there and that different styles and approaches exist. One can program with functions, one can program with linguistic abstractions, ... McCarthy called his paper: 'Recursive Functions of Symbolic Expressions and Their Computation by Machine' - this hints that one programs with recursive functions - but it enables also to compute with symbolic expressions - not only as data, but also as code. The evaluator as a recursive function, which implements Lisp.
I found lack of TCO to be a little like a stick in the neck when it comes to both Clojure and Emacs Lisp. It prevents you from thinking in the way you have been thinking in other Lisps.
I understand Clojure depends on JVM and JVM doesn't do tail call eliminations yet, and Rich Hickey is right in thinking that method calls are too much a platform thing and we shouldn't be working around this limitation with a hack. However lack of TCO in Emacs Lisp is a little not easy to live with. From what I understand patches have been submitted to Emacs to make this happen but haven't made it to the upstream.
TCO is very important for any language that sells functional programming these days. Apart from the performance advantages, Recursion is a thought framework. Limitations are not easy to live with.
I hope some day Clojure and Emacs Lisp get TCO.
On a tangential note, JVM is a great platform, its a also a widely used platform, so changes are going to come in very slowly. So I'm not holding my breath waiting for TCO.