declare

added
1.0

ns
clojure.core

type
macro

(declare & names)

defs the supplied var names with no bindings, useful for making forward declarations.

                user=> (defn foo []
         (undefined-func))
; Evaluation aborted. Unable to resolve symbol: undefined-func in this context
nil

user=> (declare undefined-func)
#'user/undefined-func

user=> (defn foo []
         (undefined-func))
#'user/foo

            
                user=> (declare show)
#'user/show
user=> (defn welcome [user-name] (prn (show) user-name))
#'user/welcome
user=> (defn show [] (prn "welcome "))
#'user/show
user=> (welcome "lu4nx")
"welcome "
nil "lu4nx"
nil
user=>
            
                ; def will do too.
user=> (def show)
#'user/show
user=> (defn welcome [user-name] (prn (show) user-name))
#'user/welcome
user=> (defn show [] (prn "welcome"))
#'user/show
user=> (welcome "lu4nx")
"welcome"
nil "lu4nx"
nil
            
                ;;Declare (like "def") has a natural partner in "var".
;;Consider trying to embed a to-be-defined function in a data structure:

(declare foo)
(def bar {:handy-fn foo})
(defn foo [] 42)
((:handy-fn bar))
;;IllegalStateException Attempting to call unbound fn: #'user/foo  clojure.lang.Var$Unbound.throwArity (Var.java:43)

;;:handy-fn in bar is now permanently linked to the unbound var
;; present when the def was evaluated. This can be avoided
;; by not evaluating foo when creating bar.

(declare foo)
;;(def bar {:handy-fn (var foo)})
(def bar {:handy-fn #'foo})
(defn foo [] 42)
((:handy-fn bar))
;; 42