Racket 编程

4 部分 · 语言设计

宏深入

宏深入

掌握宏的高级技巧:syntax-case、syntax-parse 和编译期计算。

syntax-parse

syntax-parse 是编写健壮宏的标准工具:

#lang racket

(require (for-syntax syntax/parse racket/syntax))

(define-syntax (define-for stx)
  (syntax-parse stx
    [(_ name:id body ...)
     #'(define name (begin body ...))]))

编译期计算

宏在编译时执行,可以做一些有趣的事:

(define-syntax (compile-time-add stx)
  (syntax-parse stx
    [(_ a:number b:number)
     (define result (+ (syntax-e #'a) (syntax-e #'b)))
     #`#,result]))

(compile-time-add 3 4)  ; 在编译时变成 7

syntax-id-rules

让标识符本身变成宏:

(define-syntax current-time
  (syntax-id-rules ()
    [_ (current-seconds)]))

(displayln current-time)  ; 每次求值都获取当前时间

调试宏

;; expand:展开宏
(expand '(when #t (displayln "hello")))
;; => (if #t (begin (displayln "hello")) (void))

;; macro-expand in DrRacket
;; 使用 Macro Stepper 可视化展开过程

小结

syntax-parse 让宏定义更加安全和强大。掌握编译期计算和宏调试,你就能创造出优雅的语言扩展。