【问题标题】:Testing higher order function that compiles structures to function-like lists测试将结构编译为类函数列表的高阶函数
【发布时间】: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


【解决方案1】:

问题在于,语法引用形式(以反引号开头)中的无命名空间文字符号会根据语法引用形式词法出现的位置来填充命名空间组件。你的似乎出现在定义 bloom.adgear.targeting 命名空间的文件中,所以这就是附加到 context 的文件。

大多数时候,这是一个很酷的功能,但是当你需要避免它时,你可以使用~' 技巧:

`foo
; => some-ns/foo
`~'foo
; => foo

波浪号取消对下一个形式的引用,因此它不受语法引用的魔力(包括自动解析符号)的影响;但随后它会被评估,因此需要引用以便您返回原始表单(符号 foo)而不是其值(无论 foo 当前绑定到什么)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多