我一直在阅读 sicp 试图理解方案,特别是宏。我注意到 sicp 根本不谈论宏。我在 Paul Graham 的网站上看到:
The source code of the Viaweb editor was probably about 20-25% macros. Macros are harder to write than ordinary Lisp functions, and it's considered to be bad style to use them when they're not necessary. So every macro in that code is there because it has to be.
所以我非常想知道如何编写宏以及它们的用途,所以我阅读了这个关于宏的网站:http://www.willdonnelly.net/blog/scheme-syntax-rules/
但是该站点只是解释了如何编写“for”宏。我认为 Paul Graham 谈论 CL 而另一个博客谈论方案,但它们部分相同。 那么,wat 可以作为普通程序无法完成而必须使用宏来完成的示例吗?
编辑:我已经看到类似的 question ,但想问一下是否有某种疯狂的算法可以用宏来做,而这些算法不可能用过程来完成(除了那个问题的答案中描述的语法糖)。
宏是一个棘手的主题,我个人已经不止一次地改变了自己的观点,所以对所有事情都持保留态度。
如果您刚刚熟悉宏,您会发现最有帮助的是那些澄清或加速现有表达式的宏。
您可能接触过的一个这样的宏是 anaphoric 宏,它在今天仍然像 Paul Graham 创造这个词的那一天一样流行:
(define-syntax (aif x)
(syntax-case x ()
[(src-aif test then else)
(syntax-case (datum->syntax-object (syntax src-aif) '_) ()
[_ (syntax (let ([_ test]) (if (and _ (not (null? _))) then else)))])]))
这些宏引入了“照应”变量,即 it
,您可以在 if 语句的后续和替代子句中使用它,例如:
(aif (+ 2 7)
(format nil "~A does not equal NIL." it)
(format nil "~A does equal NIL." it))
这为您省去了键入 let 语句的麻烦——这在大型项目中可能会累加起来。
更广泛地说,改变程序结构的转换、动态生成“模板化”代码或以其他方式“破坏”规则(希望您足够了解以破坏!)是宏的传统领域。我可以不停地写我如何使用宏简化无数项目和作业——但我想你会明白的。
学习 Scheme 样式的宏有点令人生畏,但我向你保证,这里有 excellent guides to syntax-rules
-style macros for the merely eccentric ,并且随着您获得越来越多的宏经验,您可能会得出这样的结论:它们是一个绝妙的主意,名副其实的“Scheme”。
如果你碰巧使用了Racket(以前称为PLT Scheme)--It has excellent documentation on macros ,甚至在此过程中提供了一些巧妙的技巧(我也猜想那里写的大部分内容都可以很容易地用另一种 Scheme 方言编写而不会出现问题)