I'm a bit confused by clojure's doc
.
The output is a specification of arguments, using the traditional basic regular expression markup, which is:
*
: 0..n instances of the marked-up preceding element ("many")?
: 0..1 instances of the marked-up preceding element ("optional")+
: 1..n instances of the marked-up preceding element ("at least one")Parentheses ()
and square brackets []
are, however, to be used "as given" to form the correct expression or form, and are not used for grouping of any regular expression elements.
And if there are several valid argument combinations, they are listed on several lines.
But observe for example the output for (doc fn)
:
clojure.core/fn
(fn name? [params*] exprs*)
(fn name? ([params*] exprs*) +)
([& sigs])
Special Form
params => positional-params* , or positional-params* & next-param
positional-param => binding-form
next-param => binding-form
name => symbol
Defines a function
Please see http://clojure.org/special_forms#fn
params => positional-params* , or positional-params* & next-param
positional-param => binding-form
next-param => binding-form
name => symbol
Defines a function
Spec
args: (cat :fn-name (? simple-symbol?) :fn-tail (alt :arity-1 :clojure.core.specs.alpha/params+body :arity-n (+ (spec :clojure.core.specs.alpha/params+body))))
ret: any?
nil
The first three lines make sense as:
(fn name? [params*] exprs*)
(fn name? ([params*] exprs*) +)
But then there is a non-indented ([& sigs])
. What's that about?
The subsequent output also seems to be in need of cleanup. And what's the "Spec"?
For (doc doc)
:
clojure.repl/doc
([name])
Macro
Prints documentation for a var or special form given its name,
or for a spec if given a keyword
nil
I don't understand the non-indented ([name])
.
Or let's try (doc letfn)
:
clojure.core/letfn
(letfn [fnspecs*] exprs*)
([fnspecs & body])
Special Form
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.
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.
nil
Again the meaning of ([fnspecs & body])
is unclear to me.
Those are the parameter lists for the functions.
From the source:
([& sigs])
says that it takes a variadic list of "(sig)natures". "Signature" in this case is referring to the example forms on the previous lines. Either ([params] body)
for creating a function with a single parameter list, or a list of (([params] body) ([other-params] body)
to create a function with multiple parameter lists.
The doc
one is just saying that doc
accepts a name
as an argument.
Finally, letfn
is saying that it takes a "fnspecs
" vector, and a variadic body
of expressions. You can see that in how it's used:
(letfn [(some-function [param] ; The vector on these two lines is "fnspecs"
(println param))]
(println "PRINTING!") ; These two lines are grouped into "body"
(some-function 1))
It has an outer set of parenthesis because it's showing a list of all the available parameter lists. doc
shows ([name])
(a list of one vector) because it only has one valid parameter list. If you look at the docs for a function like max
though:
clojure.core/max
([x] [x y] [x y & more])
Returns the greatest of the nums.
Its listing multiple parameter lists because max
has multiple arities.
As for why letfn
shows ([fnspec & body])
, that's the way that it's defined in the source:
fnspecs
is the first parameter, and any arguments supplied after that are grouped into the body
var-arg list. You may need to look over Clojure's var-arg syntax.