|
|
|
|
|
by kragen
4716 days ago
|
|
Oh, that extra nesting was stupid of me! Thank you. It should have been (defn cross [xs ys]
(mapcat (fn [x] (map (fn [y] (list x y)) ys)) xs))
and maybe in CL one would prefer (defun cross (xs ys)
(loop for x in xs
appending (loop for y in ys
collect (list x y))))
which of course has no equivalent in Clojure, Scheme, or really any other language I can think of.I'm not sure I agree on (recur...). You would need to use (recur...) if you were translating tail-recursive code that iterated over something other than a data structure and didn't produce new live objects on every iteration. But the code you gave wasn't tail-recursive, and what it iterated over was a data structure, and every iteration produced live objects that can't be garbage-collected. Even if you rewrote it to be tail-recursive, it wouldn't run out of stack for reasonably-sized output lists anyway; and for unreasonably-sized output lists, it would be likely to run out of heap for the output before it ran out of stack. I'm interested to hear if you manage to get it to stack-overflow. (It seems likely to be possible, but perhaps a bit of a challenge.) Regardless, I don't think it's reasonable to claim that languages that don't have tail-call elimination — which I suspect you may be on the point of doing — aren't Lisps. Many popular Lisps have had TCE, but many more Lisps haven't, and the CL standard doesn't require it. |
|
Python, for example: def cross(xs, ys): return [[x, y] for y in ys for x in xs]
LOOP in disguise :) (at least to my (very possibly faulty) understanding.)