2010-12-11 75 views
4

j'ai dû commenter la ligne ci-dessous (exemple de http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci)Comment ajouter un méta/commentaire à une séquence définie via def dans Clojure?

(def fib-seq 
    ;"Implements Fibonacci sequence (starts with 0)." 
    ((fn rfib [a b] 
    (lazy-seq (cons a (rfib b (+ a b))))) 
    0 1)) 

Si je partais dans, je recevrais:

Clojure 1.2.0 
java.lang.Exception: Too many arguments to def (Problem1.clj:1) 
1:1 user=> 

Je peux le faire avec defn, cependant. Exemple (je sais, je suis réinventer la roue pour even? est déjà défini): (symbole DEF initialisation)

(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=> 
+0

Vous devriez marquer la réponse de MayDaniel comme correcte. – semperos

Répondre

4

(def ^{:doc "Implements Fib. sequence lazily."} fibs ...)

(:doc (meta (var fibs)))

; "Implements Fib. sequence lazily."


Il est assez simple d'écrire une macro pour que vous puissiez écrire (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)."


Notez également que votre exemple d'utilisation defn, l'docstring doit précéder les arguments, sinon il ne sera pas associé aux métadonnées du symbole.


Alternativement, on peut utiliser clojure.contrib.def/defvar.

+1

Voir clojure.contrib.def/defvar pour une macro existante –

0

De http://clojure.org/special_forms#def

crée et stagiaires ou localise une variable globale avec le nom du symbole et un espace de noms de la valeur de l'espace de noms actuel.

De http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/defn

(defn nom doc-string? Attr-carte? [params *] corps) est le même que (le nom def (fn [params *] exprs *)) avec toute doc-chaîne ou attr ajouté à la métadonnée var.

Donc, quand vous écrivez (def Fib-seq « commentaire » (...)), vous essayez de définir un symbole FIB-seq avec la valeur « commentaire », et se plaint clojure il y a trop beaucoup d'arguments.

+0

Ok, alors comment ajouter un commentaire/une documentation à ce moment-là? –

4

Ce problème est déjà résolu dans les nouvelles versions alpha de Clojure 1.3, où def supporte une docstring optionnelle.

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 
+0

Merci quand cette version sera-t-elle stable? –