如何在 Clojure 中通过 def 定义的序列添加元/注释?

发布于 2024-10-06 20:40:24 字数 806 浏览 2 评论 0原文

我必须注释掉下面的行(示例来自 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))

如果我把它留在里面,我会得到:

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

但是,我可以使用 defn 来做到这一点。示例(我知道,我正在为 even? 重新发明轮子已经定义):

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

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=>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

罪歌 2024-10-13 20:40:24

(def ^{:doc "延迟实现 Fib. 序列。"} fibs ...)

(:doc (meta (var fibs)))

; “延迟实现 Fib. 序列。”


编写宏非常简单,因此您可以编写 (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)))

; “实现斐波那契数列(从 0 开始)。”


另外,请注意,在使用 defn 的示例中,文档字符串应位于参数之前,否则它将不会与符号的相关联元数据。


或者,可以使用 clojure.contrib.def/ defvar

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

近箐 2024-10-13 20:40:24

这个问题已经在 Clojure 1.3 的新 alpha 版本中“修复”,其中 def 支持可选的文档字符串。

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

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
抚笙 2024-10-13 20:40:24

来自 http://clojure.org/special_forms#def

(def symbol init?) 创建并实习
或定位一个具有名称的全局变量
符号和值的命名空间
当前命名空间的。

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

(defn name doc-string? attr-map?
[参数*] 主体)
与添加任何文档字符串或属性的 (def name (fn [params* ] exprs*)) 相同
到 var 元数据。

因此,当您编写 (def fib-seq "your comment" (...)) 时,您试图定义一个值为“your comment”的符号 fib-seq,并且 clojure 抱怨参数太多。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文