【发布时间】:2010-12-18 13:16:00
【问题描述】:
我有一个这样的地图(可以使用通常的布尔运算符嵌套,使用模块“布尔”和“数据”将包含适当的值,例如“左”、“右”和“运算符”将是“和”、“或”、“非”):
{ "data" { "name" "lang", "operator" "=", "value" "blue" },
"module" "impression_hint"}
我想要的是一个返回一个列表的函数,该列表可以插入到 (fn [context] ...) 列表中,在那里它将能够针对我们将抛出的内容执行。
给定上面的结构,最终的结果,在被插入到一个函数之后,应该是这样的:
(fn [context]
(= ((context :impression_hint) "lang") "blue"))
因此,我的解析/编译函数必须只返回 (= ...) 部分。我有一些非常接近的东西:
(defn- parse-internal [tree acc]
(cond
; other cases will go here
(= "impression_hint" (tree "module"))
(let [data (tree "data")
op (data "operator")
name (data "name")
value (data "value")]
`(~(symbol op) ((context :impression_hint) ~name) ~value))
:else
(throw (RuntimeException. (str "Unknown module: " (tree "module"))))))
在我的测试中,这会返回:
FAIL in (simple-shallow-rules-generate-simple-shallow-functions) (targeting.clj:10)
expected: (= (quote (= ((context :impression_hint) "name") "blue")) (bloom.adgear.targeting/parse {"data" {"name" "lang", "operator" "=", "value" "blue"}, "module" "impression_hint"}))
actual: (not (= (= ((context :impression_hint) "lang") "blue")
(= ((bloom.adgear.targeting/context :impression_hint) "lang") "blue")))
注意上下文参数?它已被命名空间,这就是我的测试失败的原因。我确定我可以做点什么,但是调用 symbol 会导致符号未定义,这是有道理的,因为该符号尚不存在。
关于 acc 参数:我怀疑我最终会从此函数中删除递归,并使用 acc 进行递归,将我的返回值放到累加器上。不过,这有点远。
【问题讨论】:
-
关于:上面倒数第二段的小评论。实际上,
symbol函数旨在生成可能尚不存在的符号。当然,如果程序文本读取(symbol foo),其中foo是一个符号,那么传递给symbol的就是foo的值——如果foo未绑定,则会引发异常。在任何一种情况下,foo-the-symbol 都是由阅读器创建的,因此它在将代码提供给编译器之前就存在。
标签: compiler-construction clojure higher-order-functions