Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a meta/comment to a sequence defined via def in Clojure?

I had to comment out the line below (example is from http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci)

(def fib-seq
  ;"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=>
like image 744
Hamish Grubijan Avatar asked Dec 11 '10 17:12

Hamish Grubijan


2 Answers

(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.

like image 123
MayDaniel Avatar answered Nov 06 '22 18:11

MayDaniel


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
like image 4
bsteuber Avatar answered Nov 06 '22 19:11

bsteuber