【问题标题】:Why isn't this clojure function executing?为什么这个 clojure 函数没有执行?
【发布时间】:2014-06-20 17:42:18
【问题描述】:

我正在研究一些来自 braveclojure 的 clojure 示例:

http://www.braveclojure.com/writing-macros/

目前我正在尝试执行此操作

(ns turtle (:use clojure.pprint))

(def criticisms {:good "good code:" :bad "bad code:"})

(defn criticize-code
    [[critkey code]]
    `(println (~critkey criticisms) (quote ~code)))

(defmacro code-critic
    [code-evaluations]
    `(do ~@(map criticize-code code-evaluations)))

(println "executed code critic")
(code-critic {:good (+ 1 1) :bad (1 + 1)})
(println "code critic expansion")
(pprint (macroexpand '(code-critic {:good (+ 1 1) :bad (1 + 1)})))

;why isn't this executing?
(println "criticize code expansion")
(criticize-code [:good '(+ 1 1)])

基本上,我可以通过println 验证criticize-code 返回格式正确的代码;但我实际上无法执行它...有人可以告诉我我做错了什么吗?

谢谢!

【问题讨论】:

    标签: macros clojure


    【解决方案1】:

    函数criticize-code 正在被调用。函数体中的准引号 ` 是语法引用的读取器宏,这意味着下面的println 形式在通过语法引用读取器之后,将作为数据结构返回而不是执行. criticize-code 函数在语义上等价于

    (defn criticize-code
      [[critkey code]]
      (list 
        'clojure.core/println 
        (list critkey 'turtle/criticisms) 
        (list 'quote code)))
    

    如果要将生成的数据结构视为 REPL 中的代码,可以直接eval

    turtle=> (criticize-code [:good '(+ 1 1)])
    (clojure.core/println (:good turtle/criticisms) (quote (+ 1 1)))
    turtle=> (eval (criticize-code [:good '(+ 1 1)]))
    good code: (+ 1 1)
    nil
    

    那么你为什么想要一个像这样工作的函数呢?作为宏的助手,就像这里的code-critic。宏处理代码即数据即代码。因此,如果您在as-data 阶段坚持使用辅助函数,它将需要将其结果作为数据返回。否则,您要编译的代码只会在“编译”时执行,并编译其返回值(println 返回nil)。

    【讨论】:

      猜你喜欢
      • 2011-01-06
      • 2023-03-13
      • 1970-01-01
      • 2011-12-21
      • 1970-01-01
      • 2016-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多