gpt4 book ai didi

reflection - 你能在 Clojure 中获取加载函数的 "code as data"吗?

转载 作者:行者123 更新时间:2023-12-02 23:53:08 31 4
gpt4 key购买 nike

换句话说,“Okay, so code is data...

该线程解决了如何从源文件中读取数据的问题,但我想知道如何将已加载函数的 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

但这只是答案的一部分。 AFAICT source 查找定义给定符号的源文件名和行号,然后从文件中打印源代码。因此,source 不适用于您没有源代码的符号,即 AOT 编译的 clojure 代码。

回到您最初的问题,您可以将 source 视为读取与给定符号关联的元数据并简单地打印它。 IE。这是作弊。它不会以任何方式向您返回“代码即数据”,其中代码是指编译后的 clojure 函数。

在我看来,“代码即数据”指的是 lisp 的特性,其中源代码实际上是一种 lisp 数据结构,因此它可以被 lisp 阅读器读取。也就是说,我可以创建一个有效的 Lisp 代码数据结构,并对其进行eval

例如:

user=> (eval '(+ 1 1))
2

这里 '(+ 1 1) 是一个文字列表,由 clojure 阅读器读取,然后计算为 clojure 代码。

更新: Yehonathan Sharvit 在其中一条评论中询问是否可以修改函数的代码。以下代码片段读取函数的源代码,修改生成的数据结构,最后评估数据结构,从而定义一个新函数 my-nth:

(eval
(let [src (read-string (str (source-fn 'clojure.core/nth) "\n"))]
`(~(first src) my-nth ~@(nnext src))))

syntax-quote 行将 defn 形式中的 nth 替换为 my-nth

关于reflection - 你能在 Clojure 中获取加载函数的 "code as data"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9217911/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com