syntax-rules 宏 什么是语法扩展(syntax extension) 宏的定义语法 syntax-rules 转换器 展开器的行为 一点补充 参考资料 #メイドインアビス ナナチ - SBIN的插画 - pixiv 谈到Scheme 的独特之处,除了它那极简语法的 s-expression 外,就是与众不同但又威力强大的宏,或者说是语法拓展(syntactic-extension)了。
在Scheme 语言中, 在R5R5 规范以后简单的宏可以被方便地使用syntax-rules 形式来定义,作为对比 Common Lisp 的宏显得要复杂许多: 使用syntax-rules 可以更直接地定义宏,而不需要考虑诸如变量捕捉 等细节 定义复杂的宏,使用 syntax-rules 比起 Common Lisp 的宏来说会困难得多(某些 Scheme 实现提供了define-macro ...
define-syntax和syntax-rules: define-syntax和syntax-rules:define-syntax-rule只能匹配一个pattern,但是使用define-syntax和syntax-rules,我们 可以在一个宏里写出多个pattern-template。 我们 可以在一个宏里写出多个pattern-template。 (define-syntaxid(syntax-rules (literal-id ...) [pattern template] ...)) ...
syntax-rule的第一个参数是保留字的表。比如,cond的定义如[代码6]所示,其中,else是保留字。 (define-syntaxmy-cond(syntax-rules(else)((_(elsee1 ...))(begine1 ...))((_(e1e2 ...))(whene1 e2 ...))((_(e1e2 ...)c1 ...)(ife1(begine2 ...)(condc1 ...))) 局部...
syntax-rules的能力是受限的,不能引入新的syntax-object,只能写一些简单的宏.但是用syntax-rules写出来的宏肯定比用syntax-case或define-macro写的更优雅. syntax-case完全不受限制,扩展能力与传统lisp宏(defmacro)是一样的,但由于它自带模式匹配功能,所以写起来会更方便,至少quasiquote,unquote,unquote-splicing少了很...
(syntax-rules () ((_ exp) (cons exp '())) ((_ exp1 exp2 ...) (cons exp1 (ourlst exp2 ...))) (display (ourlst 1 2 3 4 5)) (newline) 上面代码的结果如下: 15 (1 2 3 4 5) 在sum宏定义中,如果附合规则(_ exp1 exp2 ...)或(sum exp1 exp2 ...)将按(+ exp1 ex...
在Scheme中,宏是通过(define-syntax关键字定义的。宏定义了一个语法变换规则,当Scheme解释器遇到匹配的语法结构时,就会按照定义的规则进行变换。 例如,我们可以定义一个简单的宏,将(add x y)转换为(+ x y): (define-syntax add (syntax-rules () ((_ x y) (+ x y))) 这样,在代码中我们就可以使用(ad...
( syntax-rules () [ ( _ pred body ... ) ( if pred ( begin body ... ) ( void ) ) ] ) ) ( my-when ( = 2 1 ) ( display 1 ) ( display 2 ) ) ( define-syntax my-let ( syntax-rules () [ ( my-let ( [ var exp ] ... ) ...
在Scheme 上实现的话,实际要做的工作就是搞清楚 Scheme 版本的 typing rules。 常数,这个很简单,我们可以直接从 syntax 得到类型 变量绑定,对于语句(define x y)wherey:\sigma, 我们得到x: \sigma Function Application, 对于表达式 (foo arg2 ...), 如果 foo 的类型为A1 A2 ... An \rightarrow Ret, ...
(syntax-rules() ((_x) (set!x '())) syntax-reuls的第二个参数由是变换前表达式构成的表。_代表宏的名字。简言之,代码片段1表示表达式(nil! x)会变换为(set!x ‘()). 这类过程不能通过函数来实现,这是因为函数的闭包性质限制它不能影响外部变量。让我们来用函数实现代码片段1,并观察效果。 (define...