[英]How do defines and syntax macros interact in Racket?
我是 Racket 的新手,有些關於語法宏的內容我不明白。 我有這兩個程序:
這個正確執行:
#lang racket
(define-syntax-rule (create name) (define name 2))
(create x)
(displayln (+ x 3))
而這個抱怨標識符x
未綁定:
#lang racket
(define-syntax-rule (create) (define x 2))
(create)
(displayln (+ x 3))
使用簡單的替換方法(例如 C/C++ 宏),這兩個程序的行為將相同,但顯然它們並非如此。 似乎出現在語法宏調用中的標識符在某種程度上是“特殊的”,並且使用它們的define
s 的行為與define
不使用它們的 s 的行為不同。 此外,Racket 標准庫中有一個struct
語法宏,它定義了幾個在其調用中未明確命名的變量,例如:
(struct employee (first-name last-name))
將定義employee?
和employee-first-name
,它們都沒有在調用中直接命名。
這里發生了什么,可以解決它以便我可以創建自定義版本的struct
?
朴素替換的問題是無意捕獲。 默認情況下,Racket 宏是衛生的,這意味着它可以避免這個問題。 有關更多詳細信息,請參閱https://en.wikipedia.org/wiki/Hygienic_macro 。
話雖如此,宏系統也支持不衛生的宏。 struct
是不衛生宏的一個示例。 但是你需要付出更多的努力才能讓不衛生的宏工作。
例如,您的第二個版本的create
可以編寫如下:
#lang racket
(require syntax/parse/define)
(define-syntax-parse-rule (create)
#:with x (datum->syntax this-syntax 'x)
(define x 2))
(create)
(displayln (+ x 3))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.