Skip to content

Instantly share code, notes, and snippets.

Created July 23, 2010 01:21
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
a letrec macro for Clojure
(defmacro letrec [bindings & body]
(let [bcnt (quot (count bindings) 2)
arrs (gensym "bindings_array")
arrv `(make-array Object ~bcnt)
bprs (partition 2 bindings)
bssl (map first bprs)
bsss (set bssl)
bexs (map second bprs)
arrm (zipmap bssl (range bcnt))
btes (map #(walk/prewalk (fn [f]
(if (bsss f)
`(aget ~arrs ~(arrm f))
`(let [~arrs ~arrv]
~@(map (fn [s e]
`(aset ~arrs ~(arrm s) ~e))
(let [~@(mapcat (fn [s]
[s `(aget ~arrs ~(arrm s))])
(letrec [ev? (fn [n] (if (zero? n) true (od? (dec n))))
od? (fn [n] (if (zero? n) false (ev? (dec n))))]
(ev? 11))
;; ...and the same with 10
(letrec [xs (lazy-seq (filter even? ys)) ys (range 10)] xs)
;; see
(letrec [NY (list "NY" (delay [London Paris]))
Paris (list "Paris" (delay [NY]))
London (list "London" (delay [NY]))]
(ffirst @(first (nfirst @(second NY)))))
Copy link

New version based on tools.macro's symbol-macrolet available @

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment