I had to comment out the line below (example is from http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci)
(def fib-seq
开发者_C百科 ;"Implements Fibonacci sequence (starts with 0)."
((fn rfib [a b]
(lazy-seq (cons a (rfib b (+ a b)))))
0 1))
If I left it in, I would get:
Clojure 1.2.0
java.lang.Exception: Too many arguments to def (Problem1.clj:1)
1:1 user=>
I can do this with defn
, however. Example (I know, I am reinventing the wheel for even?
is already defined):
(defn is-even? [n]
"Returns true if the number is even, false otherwise."
(== (mod n 2) 0))
Clojure 1.2.0
1:1 user=> (is-even? 3)
false
1:2 user=> (is-even? 4)
true
1:3 user=>
(def ^{:doc "Implements Fib. sequence lazily."} fibs ...)
(:doc (meta (var fibs)))
; "Implements Fib. sequence lazily."
It's simple enough to write a macro so you could write (def-with-docs foo "doc" 1)
.
(defmacro def-with-docs [name docstring value]
`(def ~(with-meta name {:doc docstring}) ~value))
(def-with-docs fib-seq "Implements Fibbonaci sequence (starts with 0)."
((fn rfib [a b] (lazy-seq (cons a (rfib b (+ a b))))) 0 1))
(:doc (meta (var fib-seq)))
; "Implements Fibbonaci sequence (starts with 0)."
Also, note that with your example use of defn
, the docstring should precede the arguments, else it won't be associated with the symbol's metadata.
Alternatively, one can use clojure.contrib.def/defvar.
This issue is "fixed" already in the new alpha releases for Clojure 1.3, where def supports an optional docstring.
user> (clojure-version)
"1.3.0-alpha3"
user> (def answer "the answer to the final question" 42)
#'user/answer
user> (doc answer)
-------------------------
user/answer
nil
the answer to the final question
nil
From http://clojure.org/special_forms#def
(def symbol init?) creates and interns or locates a global var with the name of symbol and a namespace of the value of the current namespace.
From http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/defn
(defn name doc-string? attr-map? [params*] body) is the same as (def name (fn [params* ] exprs*)) with any doc-string or attrs added to the var metadata.
So, when you write (def fib-seq "your comment" (...)), you are trying to define a symbol fib-seq with value "your comment", and clojure complains there are too many arguments.
精彩评论