我想在数据结构中预先存储一堆函数调用,然后从另一个函数中评估/执行它们。
对于在命名空间级别定义的函数,这按计划工作defn
(即使函数定义是在我创建数据结构之后出现的)但不适用于由let [name (fn
or 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/失败行,然后调用(runit)
来自 REPL。
我可以采取简单的修复方法吗eval
'd quote
d 调用函数来为另一个函数内定义的函数工作?
Update:
这个(根据丹雷的建议)does工作。让我们看看我能否让这种方法在“现实生活”中发挥作用!
(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!
))
Update:
这段代码将进入我的解决方案约束满足问题 https://stackoverflow.com/questions/2500504/constraint-satisfaction-problem- 我想知道谁拥有斑马 https://stackoverflow.com/questions/318888/solving-who-owns-the-zebra-programmatically!我对 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
。这看起来更加优雅和“口齿不清”。但是,这些函数中的每一个都需要访问我的域数据(名为vars
),并且该数据随着程序运行而不断变化。我不想引入额外的参数来破坏我的规则,所以我想要vars
可供eval
'd 通过动态作用域发挥作用。
我现在了解到可以使用动态范围界定binding
,但它还需要一个declare
.