Skip to content

Instantly share code, notes, and snippets.

@SegFaultAX
Created November 24, 2013 18:10
Show Gist options
  • Save SegFaultAX/7630307 to your computer and use it in GitHub Desktop.
Save SegFaultAX/7630307 to your computer and use it in GitHub Desktop.
letfn/letfn*
user=> (source letfn)
(defmacro letfn
"fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+)
Takes a vector of function specs and a body, and generates a set of
bindings of functions to their names. All of the names are available
in all of the definitions of the functions, as well as the body."
{:added "1.0", :forms '[(letfn [fnspecs*] exprs*)],
:special-form true, :url nil}
[fnspecs & body]
`(letfn* ~(vec (interleave (map first fnspecs)
(map #(cons `fn %) fnspecs)))
~@body))
;; letfn*: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L5816
user=> (letfn [(a [n] (when (> n 0) (b (dec n)))) (b [n] (when (> n 0) (a (dec n))))] (a 1000))
nil
user=> (letfn [(a [n] (when (> n 0) (b (dec n)))) (b [n] (when (> n 0) (a (dec n))))] (a 10000))
StackOverflowError clojure.lang.Numbers.gt (Numbers.java:3747)
user=> (letfn [(a [n] (when (> n 0) #(b (dec n)))) (b [n] (when (> n 0) #(a (dec n))))] (trampoline a 10000))
nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment