我正在尝试使用Clojure doc
函数获取文档,但无法从REPL中识别它(我正在使用Emacs和SLIME)。以下序列描述了正在发生的事情(每行后紧跟错误信息):
gaidica.core> (doc first)
; Evaluation aborted.
Unable to resolve symbol: doc in this context
[Thrown class java.lang.Exception]
gaidica.core> (clojure.core/doc first)
; Evaluation aborted.
No such var: clojure.core/doc
[Thrown class java.lang.Exception]
user> (clojure.core/doc first)
; Evaluation aborted.
No such var: clojure.core/doc
[Thrown class java.lang.Exception]
user> (doc first)
-------------------------
clojure.core/first
([coll])
Returns the first item in the collection. Calls seq on its
argument. If coll is nil, returns nil.
nil
user>
如何引用doc
函数并将其识别为函数而不是变量?
ADDENDUM,2011年6月22日,问题发布后9小时
@kotarak发表了最相关的评论:“注意,clojure.core / doc是1.2及更早版本.clojure.repl / doc是1.3及更高版本。”果然,以下工作:
user> (clojure.repl/doc first)
-------------------------
clojure.core/first
([coll])
Returns the first item in the collection. Calls seq on its
argument. If coll is nil, returns nil.
nil
user>
我能够确认Clojure 1.3是否有效:
user> *clojure-version*
{:interim true, :major 1, :minor 3, :incremental 0, :qualifier "master"}
user>
但这也令人困惑 - 我的Leiningen project.clj指定了Clojure 1.2!
根据我自己的经验,我曾经注意到即使在我更改了相关目录的内容之后,基于SLIME的REPL仍然“挂起”了Java类路径值。然后解决方案是退出Emacs和lein swank
,然后重新输入两个并重试。我尝试了同样的结果,得到了以下结果:
user> *clojure-version*
{:major 1, :minor 2, :incremental 0, :qualifier ""}
user>
我能做出的唯一结论是我之前的REPL一直在使用Clojure 1.3。我在之前工作过的项目使用了Clojure 1.3快照,所以我猜测REPL已经“挂起”了Clojure 1.3。
问题解决了,经验教训等等。对于奖励积分,任何人都可以解释发生了什么的原因(使用Clojure 1.2 vs. 1.3)?
感谢所有贡献者。
答案 0 :(得分:12)
一些纠正。首先,doc是一个宏而不是一个函数。函数和宏也可以存储在var中。其次,在clojure 1.3中,可能是您使用的版本,doc存储在var clojure.repl / doc中,而不是clojure.core / doc(因为它在1.2中)。在命名空间用户中,doc是“used”,也就是说有一个隐含的“(使用[clojure.repl:only [doc])”。当你转到一个新的命名空间,或者甚至用ns创建一个命名空间时,不会自动添加clojure.repl / doc,这与'user。
不同。更明确地提出问题:
为什么REPL将clojure.core / doc视为var?
clojure中的函数,宏和值要么存储在变量中,要么绑定到符号,例如let或function。 clojure.core / doc是包含执行doc操作的宏的var。
如何引用doc函数并将其识别为函数,而不是变量?
与所有lisps一样,无论是函数还是宏,都必须将函数/宏放在列表的第一个位置。
(<fn/macro> *args)
因此,要调用宏文档,您可以这样做:
(doc doc)
答案 1 :(得分:1)
doc for doc显示了一个宏,所以用macroexpand扩展它就是这样 期望包含函数的var的名称。所以对你的问题的简短回答是“命名空间中的函数包含在变量中”。
在像这样的情况下,macroexpand-1可以是一个很好的起点:
(macroexpand-1 '(doc doc))
(clojure.core/print-doc (var doc))
sso-config.core> (doc doc)
-------------------------
clojure.core/doc
([name])
Macro
Prints documentation for a var or special form given its name