Why does REPL treat clojure.core/doc as a var?

邮差的信 提交于 2019-12-05 09:09:59

Couple of corrections. First, doc is a macro not a function. Also functions and macros can be stored in a var. Second, in clojure 1.3, which is likely the version you are using, doc is stored in the var clojure.repl/doc, not clojure.core/doc (as it is in 1.2). In the namespace user, doc is "used", aka there is an implicit "(use [clojure.repl :only [doc])". When you goto a new namespace, or even create one with ns, clojure.repl/doc is not automatically added, unlike it is with 'user.

To be more explicit about the questions:

Why does REPL treat clojure.core/doc as a var?

Functions, macros and values in clojure are either stored in vars or bound to a symbol such as in a let or function. clojure.core/doc is the var that holds the macro that does what doc does.

How do I refer to the doc function and get it recognized as a function, not a variable?

Like in all lisps, to do a call, whether a function or a macro, you must put the function/macro in the first position of a list.

(<fn/macro> *args)

So to call the macro doc on itself, you would do:

(doc doc)

The doc for doc shows its a macro so expanding it with macroexpand shows that is expecting the name of a var containging a function. so the very short answer to your question would be "functions in a namespace are contained in vars".

in situations like this macroexpand-1 can be a good place to start:

(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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!