store/[org.clojure/clojure "1.8.0"] clj::clojure.core/fn

Official Documentation

Add notes
Arities
==================================================
   [& sigs]

Docstring
==================================================
  params => positional-params* , or positional-params* & next-param
  positional-param => binding-form
  next-param => binding-form
  name => symbol

  Defines a function

Source

(defmacro fn
  "params => positional-params* , or positional-params* & next-param
  positional-param => binding-form
  next-param => binding-form
  name => symbol

  Defines a function"
  {:added "1.0", :special-form true,
   :forms '[(fn name? [params* ] exprs*) (fn name? ([params* ] exprs*)+)]}
  [& sigs]
    (let [name (if (symbol? (first sigs)) (first sigs) nil)
          sigs (if name (next sigs) sigs)
          sigs (if (vector? (first sigs)) 
                 (list sigs) 
                 (if (seq? (first sigs))
                   sigs
                   ;; Assume single arity syntax
                   (throw (IllegalArgumentException. 
                            (if (seq sigs)
                              (str "Parameter declaration " 
                                   (first sigs)
                                   " should be a vector")
                              (str "Parameter declaration missing"))))))
          psig (fn* [sig]
                 ;; Ensure correct type before destructuring sig
                 (when (not (seq? sig))
                   (throw (IllegalArgumentException.
                            (str "Invalid signature " sig
                                 " should be a list"))))
                 (let [[params & body] sig
                       _ (when (not (vector? params))
                           (throw (IllegalArgumentException. 
                                    (if (seq? (first sigs))
                                      (str "Parameter declaration " params
                                           " should be a vector")
                                      (str "Invalid signature " sig
                                           " should be a list")))))
                       conds (when (and (next body) (map? (first body))) 
                                           (first body))
                       body (if conds (next body) body)
                       conds (or conds (meta params))
                       pre (:pre conds)
                       post (:post conds)                       
                       body (if post
                              `((let [~'% ~(if (< 1 (count body)) 
                                            `(do ~@body) 
                                            (first body))]
                                 ~@(map (fn* [c] `(assert ~c)) post)
                                 ~'%))
                              body)
                       body (if pre
                              (concat (map (fn* [c] `(assert ~c)) pre) 
                                      body)
                              body)]
                   (maybe-destructured params body)))
          new-sigs (map psig sigs)]
      (with-meta
        (if name
          (list* 'fn* name new-sigs)
          (cons 'fn* new-sigs))
        (meta &form))))

Example 1

Edit
;; simple anonymous function passed to (map )
(map (fn [x] (* x x)) (range 1 10))
;; => (1 4 9 16 25 36 49 64 81)

;; anonymous function with a name.  not so anonymous now is it?
;; this is useful in stack traces
(fn add [a b] (+ a b))

;; anonymous function with two params, the second is destructed
(reduce (fn [m [k v]] (assoc m v k)) {} {:b 2 :a 1 :c 3})
;; => {2 :b, 1 :a, 3 :c}

;; define and instantly call an anonymous function
((fn [a b c] (+ a b c)) 2 4 6)
;; => 12

;; define and instantly call an anonymous variadic function
;; "nums" is a list here
((fn [& nums] (/ (apply + nums) (count nums))) 1 2 3 4)
;; => 5/2

;; define and instantly call an anonymous mixed function
;; "nums" is a list, while "int" is a number
((fn [int & nums] (+ int (/ (apply + nums) (count nums)))) 10 1 2 3 4)
;; => 25/2

;; define and instantly call an anonymous overloaded function
;; even though it is quite pointless
((fn ([a] (inc a)) ([a b] (+ a b))) 3)
;; => 4

Example 2

Edit
;; the shortcut form for (fn [arg1 arg2 ...] (...)) is #(...)
;; where parameters are referred by their index with the prefix %
;; and the number of argN depends on how many %N you have in the body

;; the equivalent of 
((fn [a b c] (+ a b c)) 2 4 6)
;; => 12

;; is
(#(+ %1 %2 %3) 2 4 6)
;; => 12

Uses on crossclj