gpt4 book ai didi

binding - 在 Clojure 中执行动态绑定(bind)函数

转载 作者:行者123 更新时间:2023-12-04 17:58:59 25 4
gpt4 key购买 nike

我想在数据结构中预先存储一堆函数调用,然后在另一个函数中评估/执行它们。

这对在命名空间级别定义的函数按计划工作,defn (即使函数定义是在我创建数据结构之后出现的)但不适用于 let [name (fn 定义的函数或 letfn函数内部。

这是我的小型独立示例:

(def todoA '(funcA))
(def todoB '(funcB))
(def todoC '(funcC))
(def todoD '(funcD)) ; unused

(defn funcA [] (println "hello funcA!"))

(declare funcB funcC)

(defn runit []
(let [funcB (fn [] (println "hello funcB"))]
(letfn [(funcC [] (println "hello funcC!"))]
(funcA) ; OK
(eval todoA) ; OK
(funcB) ; OK
(eval todoB) ; "Unable to resolve symbol: funcB in this context" at line 2
(funcC) ; OK
(eval todoC) ; "Unable to resolve symbol: funcC in this context" at line 3
)))

如果您想知道我的测试设置,要查看这 6 条语句的结果,我注释/取消注释特定于 OK/Failing 行,然后调用 (runit)来自 REPL。

是否有一个简单的修复方法可以让我得到 eval 'd quote d 调用函数来为另一个函数中定义的函数工作?

更新:

这(基于danlei的建议)确实有效。让我们看看我是否可以让这种方法在“现实生活”中发挥作用!
(def todoB '(funcB))
(declare funcB)

(defn runit []
(binding [funcB (fn [] (println "hello funcB"))]
(funcB)
(eval todoB) ; "Unable to resolve symbol: funcB in this context" at line 1!
))

更新:

此代码将进入我的解决方案 Constraint Satisfaction Problem - 我想知道 who owns the zebra !我对 Clojure 非常陌生,尤其是函数式编程,这使得练习变得非常具有挑战性。我掉进了很多坑,但我可以接受,因为这是学习经历的一部分。

我曾经将约束指定为一堆简单的向量,如下所示:
[:con-eq :spain :dog]
[:abs-pos :norway 1]
[:con-eq :kools :yellow]
[:next-to :chesterfields :fox]

其中每个向量的第一个将指定约束的类型。但这导致我对这些规则的调度机制进行了尴尬的实现,因此我决定将它们编码为(引用的)函数调用:
'(coloc :japan :parliament) ; 10
'(coloc :coffee :green) ; 12
'(next-to :chesterfield :fox) ; 5

所以我可以用一个简单的 eval 发送约束规则.这似乎更加优雅和“lisp-y”。但是,这些函数中的每一个都需要访问我的域数据(名为 vars ),并且这些数据会随着程序的运行而不断变化。我不想通过引入额外的参数来破坏我的规则,所以我想要 vars提供给 eval 'd 通过动态作用域起作用。

我现在了解到动态范围可以使用 binding 来完成。 , 但它也需要一个 declare .

最佳答案

你的意思是这样的吗?

(def foo '(bar))
(declare bar)

(binding [bar (fn [] (println "hello bar"))]
(eval foo))

如果是,那么您的问题会简化为:
(let [foo 1]
(eval 'foo))

这是行不通的,因为 eval 不在词法环境中求值。您可以使用 vars 解决这个问题:
(declare foo)

(binding [foo 1]
(eval 'foo))

就这一点而言,Clojure 似乎与 CL 具有相似的语义,参见。 CLHS :

Evaluates form in the current dynamic environment and the null lexical environment.

关于binding - 在 Clojure 中执行动态绑定(bind)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2575262/

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