为什么REPL将clojure.core/doc视为var?

Gre*_*ams 5 emacs clojure slime read-eval-print-loop

我正在尝试使用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> 
Run Code Online (Sandbox Code Playgroud)

我如何引用该doc函数并将其识别为函数,而不是变量?


问题发布后9小时,2011年6月22日,ADDENDUM

@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>
Run Code Online (Sandbox Code Playgroud)

我能够确认Clojure 1.3是活跃的:

user> *clojure-version*
{:interim true, :major 1, :minor 3, :incremental 0, :qualifier "master"}
user> 
Run Code Online (Sandbox Code Playgroud)

但这也令人困惑 - 我的Leiningen project.clj指定了Clojure 1.2!

根据我自己的经验,我曾经注意到,即使在我更改了相关目录的内容之后,基于SLIME的REPL"挂起"了Java类路径值.然后解决方案是退出Emacs lein swank,然后重新输入两个并重试.我尝试了同样的结果,得到了以下结果:

user> *clojure-version*
{:major 1, :minor 2, :incremental 0, :qualifier ""}
user> 
Run Code Online (Sandbox Code Playgroud)

我能得出的唯一结论是我之前的REPL一直在使用Clojure 1.3.我以前来这工作该项目已经使用Clojure的1.3快照,所以我猜的REPL有"挂到" Clojure的1.3莫名其妙.

问题解决,经验教训等.对于奖励积分,任何人都可以解释发生的事情的原因(使用Clojure 1.2 vs. 1.3)?

感谢所有贡献者.

bmi*_*are 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)
Run Code Online (Sandbox Code Playgroud)

因此,要调用宏文档,您可以:

(doc doc)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`clojure.core/doc`是1.2及更早版本.`clojure.repl/doc`是1.3及更高版本. (3认同)