fdef

added

ns
clojure.spec

type
macro

(fdef fn-sym & specs)

Takes a symbol naming a function, and one or more of the following:

:args A regex spec for the function arguments as they were a list to be
passed to apply - in this way, a single spec can handle functions with
multiple arities
:ret A spec for the function's return value
:fn A spec of the relationship between args and ret - the
value passed is {:args conformed-args :ret conformed-ret} and is
expected to contain predicates that relate those values

Qualifies fn-sym with resolve, or using *ns* if no resolution found.
Registers an fspec in the global registry, where it can be retrieved
by calling get-spec with the var or fully-qualified symbol.

Once registered, function specs are included in doc, checked by
instrument, tested by the runner clojure.spec.test/check, and (if
a macro) used to explain errors during macroexpansion.

Note that :fn specs require the presence of :args and :ret specs to
conform values, and so :fn specs will be ignored if :args or :ret
are missing.

Returns the qualified fn-sym.

For example, to register function specs for the symbol function:

(s/fdef clojure.core/symbol
:args (s/alt :separate (s/cat :ns string? :n string?)
:str string?
:sym symbol?)
:ret symbol?)

                ;; Example of speccing a higher order function
;; Taken from https://clojure.org/guides/spec

;; adder returns a function
(defn adder [x] #(+ x %))

;; so on :ret, you can use fspec to spec the function it returns
(s/fdef adder
  :args (s/cat :x number?)
  :ret (s/fspec :args (s/cat :y number?)
                :ret number?)
  :fn #(= (-> % :args :x) ((:ret %) 0)))
            
                (defn add [a b] (+ a b))

(s/fdef add
  :args (s/cat :a number? :b number?)
  :ret number?)