Remix.run Logo
pfdietz an hour ago

Even SBCL doesn't do TCO at all times. Compiling at (debug 3) means no TCO.

Another related footgun is deep recursion of other kinds, for example when recursively traversing down lists. For long lists it's easy to exceed the stack size limit. The common idiom is to recur on list elements, but iterate or map to go along a list.

guenthert an hour ago | parent [-]

> Even SBCL doesn't do TCO at all times. Compiling at (debug 3) means no TCO.

Presumably one intends to debug the code, when setting (debug 3). Then it'll be helpful to see the stack, no?

> Another related footgun is deep recursion of other kinds, for example when recursively traversing down lists. For long lists it's easy to exceed the stack size limit. The common idiom is to recur on list elements, but iterate or map to go along a list.

Not going to argue with seasoned lispers here, but IMHO recursive code makes most sense when accessing recursive data structures.

pfdietz 40 minutes ago | parent [-]

One place where this shows up is in parse trees. The grammar for a list of things may involve productions that look like list constructors. This, directly translated into a data structure, would give a very long chain of parse tree nodes dangling off to the right. It's a recursive data structure, but a very deep one for large lists, and traversing it recursively can use a lot of stack.

This can also be seen as an argument against building parse trees that way. Instead, have a node with an unbounded number of children, the elements of the list.