Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@michalmarczyk
Created July 23, 2010 01:21
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save michalmarczyk/486880 to your computer and use it in GitHub Desktop.
Save michalmarczyk/486880 to your computer and use it in GitHub Desktop.
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))
f))
%)
bexs)]
`(let [~arrs ~arrv]
~@(map (fn [s e]
`(aset ~arrs ~(arrm s) ~e))
bssl
btes)
(let [~@(mapcat (fn [s]
[s `(aget ~arrs ~(arrm s))])
bssl)]
~@body))))
(comment
(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 http://stackoverflow.com/questions/2761253/graph-representation-in-dr-scheme/2761677#2761677
(letrec [NY (list "NY" (delay [London Paris]))
Paris (list "Paris" (delay [NY]))
London (list "London" (delay [NY]))]
(ffirst @(first (nfirst @(second NY)))))
)
@michalmarczyk
Copy link
Author

New version based on tools.macro's symbol-macrolet available @ https://gist.github.com/michalmarczyk/3c6b34b8db36e64b85c0

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