Skip to content

Instantly share code, notes, and snippets.

@hiredman
Created August 29, 2011 18:37
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiredman/1179073 to your computer and use it in GitHub Desktop.
Save hiredman/1179073 to your computer and use it in GitHub Desktop.
(defmacro letfn- [fn-bindings & body]
(let [fn-names (map first fn-bindings)
fn-gensyms (into {} (for [f fn-names]
[f (gensym f)]))
delayed-bindings (for [f fn-names
x [(fn-gensyms f)
`(delay (~f ~@fn-names))]]
x)
forced-bindings (for [[n v] fn-gensyms
x [n `(force ~v)]]
x)
fn-bindings (for [form fn-bindings
:let [form (if (vector? (second form))
(list (first form) (rest form))
form)]
x [(first form)
`(fn* ~(vec fn-names)
(let ~(vec delayed-bindings)
(fn ~@(for [f (rest form)
:let [[args & body] f]]
`(~args (let ~(vec forced-bindings)
~@body))))))]]
x)]
`(let ~(reduce into (vec fn-bindings) [delayed-bindings forced-bindings])
~@body)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment