Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I think they consider that recursive.

However, all the major implementations (SBCL, Clozure CL, Franz Allegro, LispWorks, CMUCL, and I think even ECL) do tail-call elimination on local calls. (A local call is a call to a function whose definition is lexically visible, such as the calls to 'helper' in your example.) The document says that TCE depends on optimization settings, but for local calls, I'm not sure even that is true. Anyway, the practical upshot, in my experience, is that there's no reason not to write loops recursively using LABELS when that is the most elegant expression of the particular loop in question.

(There was once a major implementation that never did TCE -- Genera -- but even for die-hard Lisp Machine lovers like myself, it has long since been relegated to a historical curiosity.)



Thanks for that Scott, I've never heard of TCE -- learn something every day reading HN.

Just did a quick comparison (SBCL) between the above and the textbook version:

(defun sum (list) (if (null list) 0 (+ (car list) (sum (cdr list)))))

This version quickly dumped Heap Exhaustion. The LABELS version does not, and can handle summation over lists much faster as well.

What does this mean? TCE only applies applies to local calls, therefore we should never write a "raw" recursive function? (which is a tad more elegant, imo). I haven't delved into TCOs deep enough to understand, but I had hoped that a smart compiler would be able to optimize the latter?




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

Search: