换一种方式, ”好吧,代码就是数据...... http://groups.google.com/group/clojure/browse_thread/thread/554cdc59d8a46f01"
该线程解决了如何从源文件中读取的问题,但我想知道如何将已加载函数的 s 表达式放入我可以读取和操作的数据结构中。
换句话说,如果我说,
(defn example [a b] (+ a b))
我不能在运行时获取该列表吗?这难道不是“代码即数据”的全部意义吗?
这确实是一个常见的 Lisp 问题,但我正在 Clojure 中寻找答案。
您可以使用clojure.repl/source
获取符号源的宏:
user> (source max)
(defn max
"Returns the greatest of the nums."
{:added "1.0"
:inline-arities >1?
:inline (nary-inline 'max)}
([x] x)
([x y] (. clojure.lang.Numbers (max x y)))
([x y & more]
(reduce1 max (max x y) more)))
nil
但这只是答案的一部分。亚洲信息通信技术协会source
查找定义给定符号的源文件名和行号,然后从文件中打印源代码。所以,source
不适用于您没有源代码的符号,即 AOT 编译的 clojure 代码。
回到你原来的问题,你可以想到source
读取与给定符号关联的元数据并简单地打印它。 IE。这是作弊。它不会以任何方式将“代码作为数据”返回给您,其中代码是指编译后的 clojure 函数。
在我看来,“代码即数据”指的是 lisp 的特性,其中源代码实际上是 lisp 数据结构,因此它可以被 lisp 阅读器读取。也就是说,我可以创建一个有效的 lisp 代码的数据结构,并且eval
that.
例如:
user=> (eval '(+ 1 1))
2
Here '(+ 1 1)
是一个文字列表,由 clojure 阅读器读取,然后计算为 clojure 代码。
Update:Yehonathan Sharvit 在其中一条评论中询问是否可以修改函数的代码。以下代码片段读取函数的源代码,修改生成的数据结构,最后评估生成新函数的数据结构,my-nth
,定义为:
(eval
(let [src (read-string (str (source-fn 'clojure.core/nth) "\n"))]
`(~(first src) my-nth ~@(nnext src))))
The syntax-quote
行替换nth
with my-nth
in the defn
form.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)