你能在 Clojure 中获取加载函数的“代码即数据”吗?

2024-05-25

换一种方式, ”好吧,代码就是数据...... 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(使用前将#替换为@)

你能在 Clojure 中获取加载函数的“代码即数据”吗? 的相关文章

  • 调用泛型类的方法

    这是上下文 我尝试编写一个映射器来动态地将域模型对象转换为 ViewModel 对象 我遇到的问题是 当我尝试通过反射调用泛型类的方法时 出现此错误 System InvalidOperationException 无法对 Contains
  • 与doseq(或for)并行遍历集合的有效方法?

    doseq e coll1 myfunc e 如果您只关心副作用 那么速度非常快 如果我想要怎么办myfunc 并行 地从多个集合中获取元素 即 applymyfunc到每个集合的第一个元素 然后到所有第二个元素 然后到所有第三个元素 依此
  • 从 GUID 获取类型

    由于种种原因 我需要在C 中实现类型缓存机制 幸运的是 CLR 提供了Type GUID来唯一标识一个类型 不幸的是 我找不到任何方法来根据此 GUID 查找类型 有Type GetTypeFromCLSID 但根据我对文档 和实验 的理解
  • 如何检查spec/col-of中的不同ID

    s def users s coll of user distinct true 上面的规范要求每个用户映射都是不同的 但是我如何指定它来检查不同的 user ids only 不应允许以下集合 id 10 name Jessica id
  • 获取同名方法的集合

    我有一些代码 用于帮助 url 路由 尝试在控制器中查找操作方法 我的控制器看起来像这样 public ActionResult Item int id MyViewModel model new MyViewModel id return
  • PostSharp 如何在运行时知道某个方面是否应用于方法?

    我正在实现 PostSharp 方面库 但无法找到以下问题的解决方案 假设我们有一个方面将应用于某些方法 而不会应用于其他方法 我需要某种可以在运行时使用的机制来了解某个方面是否应用于方法 具体来说 在运行时确定某些方面是否应用于由 a 给
  • 使用反射创建 Action<'T> 的实例

    我将如何创建一个实例Action lt T gt 使用反射 这是我所拥有的 let makeAction typ Type f T gt unit let actionType typedefof
  • .NET 4.5 CustomReflectionContext:它有什么用?

    NET Framework 4 5 开发者预览版中的新增功能 http msdn microsoft com library ms171868 28v vs 110 29 aspx提及 能够自定义反射上下文以覆盖默认值 反射行为通过自定义R
  • Clojure 的分析工具?

    有谁知道 Clojure 有一个好的分析工具或库吗 我更喜欢可以从 REPL 中使用的东西 类似于 with profiling 过去是在 Allegro Common Lisp 中 有什么类似的事情吗 或者您是否有过与 Clojure 配
  • 使用反射来检查部分方法是否已实现

    背景 我正在使用 Linq to SQL 因此生成了一个包含自动生成的类的 DBML 文件 部分生成过程为某些操作创建部分方法 在我的例子中 我感兴趣的两个方法与表记录的插入和更新相关 这些部分方法是根据 DBML 设计器中创建的每个表生成
  • 在运行时修改方法/函数

    我一直在研究 php 反射方法 我想做的是在方法打开之后和任何返回值之前注入一些代码 例如我想更改 function foo bar foo bar return foo 并向其中注入一些代码 例如 function foo bar som
  • 如何动态计算 C# 表达式?

    我想做相当于 object result Eval 1 3 string now Eval System DateTime Now ToString as string 关注比里斯link http www codeproject com
  • Scala:在运行时获取 mixin 接口

    我需要在运行时从给定的类获取所有接口 全部加载在类加载器中 例如 如果一个类是这样声明的 trait B trait C trait D class A extends B with C with D 我想在运行时获取这些信息 A 取决于
  • 改进绩效反思 - 我应该考虑哪些替代方案?

    我需要动态地设置对象上的一堆或属性的值 将其称为传输对象 将在短时间内创建相当数量的此类传输对象并设置其属性 我想避免使用反射 还有其他选择吗 如果是的话 有我可以查看的示例实现吗 Use Delegate CreateDelegate h
  • 为什么我不能将表达式主体转换为 MethodCallExpression

    给定以下课程 public class MyClass private readonly UrlHelper urlHelper constructor left out for brevity this is one of many ov
  • 如何提高 Field.set 的性能(也许使用 MethodHandles)?

    我正在编写一些调用的代码Field set https docs oracle com en java javase 11 docs api java base java lang reflect Field html set java l
  • 为什么多种方法不能用作试剂/重新构建的功能?

    在我正在构建的使用 Reagent 和 Re frame 的小型应用程序中 我使用多种方法来根据应用程序状态中的值分派应显示哪个页面 defmulti pages name defn main panel let current route
  • 如何在 REPL 中显示 Clojure 中函数的定义?

    我正在寻找让 REPL 打印函数当前定义的能力 有什么办法可以做到这一点吗 例如 给定 defn foo if true true 我想说类似的话 print definition foo 并得到一些类似的东西 foo if true tr
  • 在 Clojure 中检测操作系统

    是否有与 Common Lisp 相当的东西 features 在Clojure中 这样你就可以检测操作系统和其他环境配置 或者我只是通过 Java API 来实现这一点 可能使用Java API 这很容易 没有必要重新发明轮子 user
  • 当参数是大映射时跟踪函数

    当我跟踪一个函数时 如果其中一个参数是包含大量元素的嵌套映射 则跟踪会充满混乱 这是一个典型的例子 TRACE t36705 get value nodeclass simple nodeid simple25 dock constan t

随机推荐