(letfn fnspecs & body)
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.
(letfn [(twice [x]
(* x 2))
(six-times [y]
(* (twice y) 3))]
(println "Twice 15 =" (twice 15))
(println "Six times 15 =" (six-times 15)))
;; Twice 15 = 30
;; Six times 15 = 90
;;=> nil
;; Unable to resolve symbol: twice in this context
(twice 4)
;; Evaluation aborted.
;; Unable to resolve symbol: six-times in this context
(six-times 100)
;; Evaluation aborted.
;; A contrived example of mutual recursion
(defn even2? [n]
(letfn [(neven? [n] (if (zero? n) true (nodd? (dec n))))
(nodd? [n] (if (zero? n) false (neven? (dec n))))]
(neven? n)))
;;using to create comparator
(defn compartr [s1 s2]
(letfn [ (inner-author [author] ((juxt :lname :fname) author))]
(compare (inner-author s1) (inner-author s2))))
=> #'user/compartr
(sorted-set-by compartr
{:fname "Steve" :lname "Smith"}
{:fname "David" :lname "Smith"})
=> #{{:fname "David", :lname "Smith"} {:fname "Steve", :lname "Smith"}}