打印“评估前完全展开的形式”的 Clojure 函数?
A Clojure function that prints the “fully expanded form before evaluation”?
是否有 Clojure 函数可以为任何函数执行 macroexpand-all
为宏执行的操作?
在 SICP 中,Abelson & Sussman 对此进行了演示,他们称之为“linear recursive process”。
换句话说,如果我们给出:
(factorial 6)
该函数将打印(而不计算):
(* 6 (* 5 (* 4 (* 3 (* 2 (1))))))
本质上,我试图“看到”数据结构任何函数在评估之前“建立”。
我认为这对于初学者(就是我 :) 来说是一种有趣的方式,可以在 Reader(?) 将内容传递给 Evaluator 之前查看它正在构建的内容。 (我不确定我在这里使用的术语是否正确。)
这不存在,因为这不是评估的工作方式。 (* 6 (* 5 (* 4 (* 3 (* 2 1)))))
形式在计算 (factorial 6)
时从不存在,因此运行时不能只是“顺便”给你。
无需编程即可实现功能跟踪。例如,它在 Emacs 的 Cider 扩展中可用。 https://docs.cider.mx/cider/debugging/tracing.html
我已将我的阶乘程序加载到 Emacs 中,并将光标放在 factorial
函数上。
(ns factorial.core
(:gen-class))
(defn factorial [n]
(if (zero? n)
1
(* n (factorial (dec n)))))
(defn -main
"A factorial program."
[& args]
(let [n 6]
(println "The factorial of " n "is" (factorial n))))
M-x cider-jack-in
REPL: (in-ns 'factorial.core)
C-c M-t v, select factorial when prompted
(factorial 3)
你的问题实际上归结为函数是如何实现的。
例如,如果阶乘看起来像这样,(也可以用宏来完成)
(defn factorial
[n]
(if (<= n 1) 1 (concat `(~'* ~n) (list (factorial (dec n))))))
调用函数后,
(map #(-> % factorial) (range 10)) =>
(1
1
(* 2 1)
(* 3 (* 2 1))
(* 4 (* 3 (* 2 1)))
(* 5 (* 4 (* 3 (* 2 1))))
(* 6 (* 5 (* 4 (* 3 (* 2 1)))))
(* 7 (* 6 (* 5 (* 4 (* 3 (* 2 1))))))
(* 8 (* 7 (* 6 (* 5 (* 4 (* 3 (* 2 1)))))))
(* 9 (* 8 (* 7 (* 6 (* 5 (* 4 (* 3 (* 2 1)))))))))
这会被调用。
您可以将宏视为转换函数的函数。只有当函数 factorial 将表达式转换为看起来像上面的嵌套乘法时,宏展开才会给出您要查找的内容。
(map #(-> % factorial eval) (range 10)) ; will give the evaluated values
是否有 Clojure 函数可以为任何函数执行 macroexpand-all
为宏执行的操作?
在 SICP 中,Abelson & Sussman 对此进行了演示,他们称之为“linear recursive process”。
换句话说,如果我们给出:
(factorial 6)
该函数将打印(而不计算):
(* 6 (* 5 (* 4 (* 3 (* 2 (1))))))
本质上,我试图“看到”数据结构任何函数在评估之前“建立”。
我认为这对于初学者(就是我 :) 来说是一种有趣的方式,可以在 Reader(?) 将内容传递给 Evaluator 之前查看它正在构建的内容。 (我不确定我在这里使用的术语是否正确。)
这不存在,因为这不是评估的工作方式。 (* 6 (* 5 (* 4 (* 3 (* 2 1)))))
形式在计算 (factorial 6)
时从不存在,因此运行时不能只是“顺便”给你。
无需编程即可实现功能跟踪。例如,它在 Emacs 的 Cider 扩展中可用。 https://docs.cider.mx/cider/debugging/tracing.html
我已将我的阶乘程序加载到 Emacs 中,并将光标放在 factorial
函数上。
(ns factorial.core
(:gen-class))
(defn factorial [n]
(if (zero? n)
1
(* n (factorial (dec n)))))
(defn -main
"A factorial program."
[& args]
(let [n 6]
(println "The factorial of " n "is" (factorial n))))
M-x cider-jack-in
REPL: (in-ns 'factorial.core)
C-c M-t v, select factorial when prompted
(factorial 3)
你的问题实际上归结为函数是如何实现的。 例如,如果阶乘看起来像这样,(也可以用宏来完成)
(defn factorial
[n]
(if (<= n 1) 1 (concat `(~'* ~n) (list (factorial (dec n))))))
调用函数后,
(map #(-> % factorial) (range 10)) =>
(1
1
(* 2 1)
(* 3 (* 2 1))
(* 4 (* 3 (* 2 1)))
(* 5 (* 4 (* 3 (* 2 1))))
(* 6 (* 5 (* 4 (* 3 (* 2 1)))))
(* 7 (* 6 (* 5 (* 4 (* 3 (* 2 1))))))
(* 8 (* 7 (* 6 (* 5 (* 4 (* 3 (* 2 1)))))))
(* 9 (* 8 (* 7 (* 6 (* 5 (* 4 (* 3 (* 2 1)))))))))
这会被调用。 您可以将宏视为转换函数的函数。只有当函数 factorial 将表达式转换为看起来像上面的嵌套乘法时,宏展开才会给出您要查找的内容。
(map #(-> % factorial eval) (range 10)) ; will give the evaluated values