Hi, to implement letrec in a language with eager evaluation strategy some kind of mutability is probably needed. Consider for example a self- referential definition such as
(let [fibo (lazy-cat [1 1] (map + fibo (rest fibo)))] (take 10 fibo)) This will not work since fibo is not in scope when the binding is established. The standard solution would probably be something like this (let [fibo (promise)] (deliver fibo (lazy-cat [1 1] (map + @fibo (rest @fibo)))) (take 10 @fibo)) Not as nice as the original version due to explicit dereferencing, but workable. As an alternative one could use a macro to expand to this and use a code walker (or symbol-macros) to automatically include the @ calls. The following is untested, but should be close: (defmacro letrec [binding & body] (let [[var expr] binding g-var (gensym)] `(let [~g-var (promise)] (symbol-macrolet [~var @~g-var] (deliver ~g-var ~expr) ~@body)))) and voila (letrec [fibo (lazy-cat [1 1] (map + fibo (rest fibo)))] (take 10 fibo)) produces (1 1 2 3 5 8 13 21 34 55). Best, Nils -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en