• (defn name doc-string? attr-map? [params*] body)
  • (defn name doc-string? attr-map? ([params*] body) + attr-map?)
Same as (def name (fn [params* ] exprs*)) or (def
name (fn ([params* ] exprs*)+)) with any doc-string or attrs added
to the var metadata

4 Examples top

  • user=> (defn foo [a b c]
    	    (* a b c))
    #'user/foo
    user=> (foo 1 2 3)
    6
    
    user=> (defn bar [a b & [c]]
             (if c
               (* a b c)
               (* a b 100)))
    #'user/bar
    user=> (bar 5 6)
    3000
    user=> (bar 5 6 2)
    60
    
    user=> (defn baz [a b & {:keys [c d] :or {c 10 d 20}}]
             (* a b c d))
    #'user/baz
    user=> (baz 2 3)
    1200
    user=> (baz 2 3 :c 5)
    600
    user=> (baz 2 3 :c 5 :d 6)
    180
    
    user=> (defn boo [a b & {:keys [c d] :or {c 10 d 20} :as all-specified}]
              (println all-specified)
              (* a b c d))
    #'user/boo
    user=> (boo 2 3)
    nil
    1200
    user=> (boo 2 3 :c 5)
    {:c 5}
    600
    user=> (boo 1 2 :d 3 :c 4)
    {:c 4, :d 3}
    24
    
  • user=> (defn bar
             ([a b]   (bar a b 100))
             ([a b c] (* a b c)))
    #'user/bar
    user=> (bar 5 6)
    3000
    user=> (bar 5 6 2)
    60
    
  • ;; You can use destructuring to have keyword arguments. This would be a
    ;; pretty verbose version of map (in an example a bit more verbose than
    ;; the first above):
    
    (defn keyworded-map [& {function :function sequence :sequence}]
      (map function sequence))
    
    ;; You can call it like this:
    
    user=> (keyworded-map :sequence [1 2 3] :function #(+ % 2))
    (3 4 5)
    
    
    ;; The declaration can be shortened with ":keys" if your local variables 
    ;; should be named in the same way as your keys in the map:
    
    (defn keyworded-map [& {:keys [function sequence]}]
      (map function sequence))
    
  • (defn somefn
      [req1 req2 ;required params
       & {:keys [a b c d e] ;optional params
          :or {a 1 ;optional params with preset default values other than the nil default
                      ; b takes nil if not specified on call
                c 3 ; c is 3 when not specified on call
                d 0 ; d is 0 --//--
                      ; e takes nil if not specified on call
               }
          :as mapOfParamsSpecifiedOnCall ;takes nil if no extra params(other than the required ones) are specified on call
          }]
      (println req1 req2 mapOfParamsSpecifiedOnCall a b c d e)
      )
    
    => (somefn 9 10 :b 2 :d 4)
    ;9 10 {:b 2, :d 4} 1 2 3 4 nil
    nil
    => (somefn)
    ;ArityException Wrong number of args (0) passed to: funxions$somefn  ;clojure.lang.AFn.throwArity (AFn.java:437)
    => (somefn 9 10)
    ;9 10 nil 1 nil 3 0 nil
    nil
    => (somefn 9 10 :x 123)
    ;9 10 {:x 123} 1 nil 3 0 nil
    nil
    => (somefn 9 10 123)
    ;IllegalArgumentException No value supplied for key: 123  ;clojure.lang.PersistentHashMap.create (PersistentHashMap.java:77)
    => (somefn 9 10 123 45)
    ;9 10 {123 45} 1 nil 3 0 nil
    nil
    => (try 
         (somefn 9 10 123)
         (catch IllegalArgumentException e (println "caught:" e)))
    ;caught: #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: 123>
    nil
Log in to add / edit an example.

See Also top

Log in to add a see also.

Plus_12x12 Minus_12x12 Source clojure/core.clj:263 top

(def 

 ^{:doc "Same as (def name (fn [params* ] exprs*)) or (def
    name (fn ([params* ] exprs*)+)) with any doc-string or attrs added
    to the var metadata"
   :arglists '([name doc-string? attr-map? [params*] body]
                [name doc-string? attr-map? ([params*] body)+ attr-map?])
   :added "1.0"}
 defn (fn defn [&form &env name & fdecl]
        (let [m (if (string? (first fdecl))
                  {:doc (first fdecl)}
                  {})
              fdecl (if (string? (first fdecl))
                      (next fdecl)
                      fdecl)
              m (if (map? (first fdecl))
                  (conj m (first fdecl))
                  m)
              fdecl (if (map? (first fdecl))
                      (next fdecl)
                      fdecl)
              fdecl (if (vector? (first fdecl))
                      (list fdecl)
                      fdecl)
              m (if (map? (last fdecl))
                  (conj m (last fdecl))
                  m)
              fdecl (if (map? (last fdecl))
                      (butlast fdecl)
                      fdecl)
              m (conj {:arglists (list 'quote (sigs fdecl))} m)
              m (let [inline (:inline m)
                      ifn (first inline)
                      iname (second inline)]
                  ;; same as: (if (and (= 'fn ifn) (not (symbol? iname))) ...)
                  (if (if (clojure.lang.Util/equiv 'fn ifn)
                        (if (instance? clojure.lang.Symbol iname) false true))
                    ;; inserts the same fn name to the inline fn if it does not have one
                    (assoc m :inline (cons ifn (cons (clojure.lang.Symbol/intern (.concat (.getName ^clojure.lang.Symbol name) "__inliner"))
                                                     (next inline))))
                    m))
              m (conj (if (meta name) (meta name) {}) m)]
          (list 'def (with-meta name m)
                ;;todo - restore propagation of fn name
                ;;must figure out how to convey primitive hints to self calls first
                (cons `fn fdecl) ))))
Vars in clojure.core/defn:
Used in 0 other vars

Comments top

No comments for defn. Log in to add a comment.