请考虑以下宏:
(defmacro somemacro []
(list 'let ['somevar "Value"] 'somevar))扩展它会产生以下结果:
(macroexpand '(somemacro))结果:
(let* [somevar "Value"] somevar)我有两个关于let* (星号)的问题:
不幸的是,我找不到任何关于let*的“正式”文档,这就是我在这里问的原因。
我已经考虑过的消息来源:
(doc let*) ; --> nil
(source let*) ; --> source not found但如果是这样的话,问题仍然存在,究竟有什么不同?
发布于 2015-07-27 19:42:26
let*是一个内部实现细节。let是一个用let*实现的宏。https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L4301
宏let将参数毁伤添加到let*。这是Clojure中xyz和xyz*的标准模式,*版本没有文档化。list和list*是一个例外。
发布于 2016-03-14 21:54:19
我想补充一点,macroexpand返回let*而不是let的原因可以在macroexpand中找到。
在窗体上反复调用宏展开-1,直到它不再表示宏窗体,然后返回它。
因此,macroexpand-1的第一个调用返回(let [somevar "Value"] somevar),第二个调用将let扩展为let*。
的确,
user=> (println (clojure.string/join "\n" (take 3 (iterate macroexpand-1 '(somemacro)))))
(somemacro)
(let [somevar "Value"] somevar)
(let* [somevar "Value"] somevar)
nil如果要在宏中使用析构,则输出将更有趣:
user=> (defmacro destructuring-macro [] `(let [[x y z] [:x :y :z]] y))
#'user/destructuring-macro
user=> (println (clojure.string/join "\n" (take 3 (iterate macroexpand-1 '(destructuring-macro)))))
(destructuring-macro)
(clojure.core/let [[testing.core/x testing.core/y testing.core/z] [:x :y :z]] testing.core/y)
(let* [vec__8356 [:x :y :z] x (clojure.core/nth vec__8356 0 nil) y (clojure.core/nth vec__8356 1 nil) z (clojure.core/nth vec__8356 2 nil)] testing.core/y)
nil注意,let被语法引号完全限定,因为它不是一个特殊的形式(尽管它的文档说明它是)。底层的特殊形式是let*,它不是由语法引号完全限定的。
https://stackoverflow.com/questions/31661187
复制相似问题