我想在数据结构中预先存储一系列函数调用,然后在另一个函数中评估/执行它们。
这与在命名空间级别为
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条语句的结果,我对确定/失败行进行了特定的注释/取消注释,然后调用
(runit)
来自RePL。
我能保证得到一个简单的解决办法吗
eval
D
quote
d调用函数来为另一个函数内定义的函数工作?
更新:
这(基于丹磊的建议)
做
工作。让我们看看我是否能在“现实生活”中使用这种方法。
(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
所以我可以用一个简单的
埃瓦
. 这看起来更优雅,“lisp-y”。但是,这些函数中的每一个都需要访问我的域数据(命名为
vars
,并且随着程序的运行,这些数据会不断变化。我不想通过引入一个额外的论点来破坏我的规则,所以我想
瓦尔斯
提供给
埃瓦
'D通过动态范围界定功能。
我现在了解到,可以使用
binding
但它也需要
declare
.