宏
这是另一个可以尝试的图书馆:
(require slideshow/code)
> (code (circle 10))
[image]
而不是一个圆,结果是一个代码的图片,如果它被用作一个表达式,将产生一个圆。换句话说,代码不是一种功能,而是一种创建图片的新句法形式;开括号与代码之间的位不是表达式,而是由代码语法形式操作的。
这有助于解释我们在上一节中所说的球拍提供需求和函数调用语法的含义。库不限于输出值,比如函数;它们还可以定义新的语法形式。从这个意义上说,球拍根本就不是一种语言;它更多的是关于如何构造一种语言以便您可以扩展它或创建全新的语言。
引入新句法形式的一种方法是通过带有语法规则的定义语法:
(define-syntax pict+code
(syntax-rules ()
[(pict+code expr)
(hc-append 10
expr
(code expr))]))
> (pict+code (circle 10))
[image]
这种定义是一个宏。(pict+code expr)部分是宏的使用模式;程序中的模式实例被替换为相应模板的实例,即(hc-append 10 expr(代码expr))。特别地,(pict+code (circle 10))将模式与(circle 10)匹配作为expr,因此将其替换为(hc-append 10 (circle 10) (code (circle 10))。
当然,这种语法扩展有利有弊:发明一种新语言可以让你更容易地表达自己想要表达的内容,但让别人更难理解。碰巧的是,Racket的开发人员经常会讲一些关于Racket代码的东西,写一些关于Racket代码的论文,对于那些为这些产品工作的人来说,了解一下代码是值得的。
实际上,您可能需要查看此文档的源代码。你会看到它以#lang开始,但其他方面看起来不太像 Racket ;
尽管如此,我们通过运行 Racket 程序来建立这个文件。我们需要使用更多的语法规则来扩展 Racket 的语法来写文档,但是 Racket 的语法扩展可以让你走很长的路。