letfn

added
1.0

ns
clojure.core

type
macro

(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"}}