Hacker News new | past | comments | ask | show | jobs | submit login

Lisp != Common Lisp. The very thought that you can cut-n-paste code from one Lisp dialect to another is daft. The author obviously didn't take the time to acquaint themselves with the basics of Clojure.

The lack of TCO in JVM hosted languages is besides the point.

It is also possible for the Clojure compiler to do TCO in certain cases: Rich Hickey made the conscious decision to not do it.




Lisp absolutely means Common Lisp, that was the whole point of Common Lisp. (Naggum rant on this: http://www.xach.com/naggum/articles/3224964049435643@naggum....) Certainly we can talk about the "Lisp Family", or "dialects within the Lisp Family" when things are close enough, and I disagree with Naggum in that I think it's not a totally useless thing to consider. But to me it's not all that useful either, since as far as I can tell the minimal thing to qualify membership to the family is to be s-exp based like [Common] Lisp, Clojure, or Scheme. I'd hesitate to call the FFP language as defined by Backus "Lisp", or even "a Lisp", however, even if a program looks like (+ :<4, 6, 8>). It's missing a lot of other things. So while Clojure, Scheme, and Lisp definitely seem closer to each other than to languages like Python or C that it might be sort of useful to group them into a family, it's a stretch to call them true dialects of each other. I can say the same things more or less with the same effort in different dialects, but how can I trivially talk Lisp conditions and restarts or Reader Macros or CLOS in Clojure or Scheme, let alone any of the other "dialects" out there? Those things aren't just "jargon" that can be interchanged or minimally expanded out, they are huge implementation details. You'd sell me more on the dialects thing if we were talking about Scheme as implemented by the Racket guys vs. Guile vs. al., or Common Lisp implemented by SBCL vs. Clozure vs. al., or Clojure as implemented on the JVM, CLR, or JavaScript runtime.


It is also possible for the Clojure compiler to do TCO in certain cases: Rich Hickey made the conscious decision to not do it.

If I read your statement as Rich Hickey having the opportunity but passed on it, I'd reply that he did that with recur. Unless you mean silent TCO like e.g. Scheme does.


Yes, silent TCO. Isn't that what most people mean about TCO when applied to recursion?


Perhaps, but that doesn't mean it's accurate. TCO literally just says tail calls are optimized, and I personally see an advantage to making your intent to make a TCO-ed tail call explicit, so like in Clojure you get a compilation error rather than blowing your stack at runtime.

It certainly looks more elegant to do it silently, but Clojure doesn't strive for that sort of elegance.


TCO is broader than what recur does. Recur only optimises recursive tail-calls to the function you are in, TCO generally implies that any tail-calls (recursive or not) can be optimised (including mutually recursive calls, for which clojure made the trampoline function or just calling one function at the tail of another).

Personally, I like clojure's approach as IMHO recur makes intent clear, but recur is a subset of what TCO optimises in other languages.


You can use the recur special form to enforce recursion from the tail position in Clojure.


True, but that's not TCO (or tail call elimination). That would mean that every single tail call is optimized to eliminate that stack overhead.

    (defun foo () (foo)) ;<- tail call

    (defun bar () (bar)) ;<- tail call

    (defun baz (a b) (+  ;<- tail call
                        (* a 2)
                        (* b 3)))


This.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: