3
syntax-property 與 local-expand 的實際運用
source link: https://dannypsnl.github.io/blog/2021/08/19/cs/syntax-property-and-local-expand/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
syntax-property 與 local-expand 的實際運用
syntax-property
可以用來把資訊存入 syntax 中,這可以用在各種有趣的 macro 擴展系統之中。一個我比較熟悉的案例是 type-system,比如我們可以寫下
(define-syntax-parser Nat
[_ (syntax-property #''Nat 'type #'Type)])
(define-syntax-parser zero
[_ (syntax-property #''zero 'type #'Nat)])
(define-syntax-parser succ
[(_ n)
(check-type #'n #'Nat)
(syntax-property #'`(succ ,n) 'type #'Nat)])
data Nat =
zero
succ Nat
其中 check-type
可以用
(define (typeof stx)
(syntax-property (local-expand stx 'expression '()) 'type))
來取得型別。 這是因為有一個常見的問題:marco 是由外往內處理的,然而我們的程式是要模擬由內往外的語意。這時候我們就會不知道 #'n
到底是什麼玩意兒,這裡用 local-expand
先展開之後,才會知道它原始的 syntax 是什麼。所以如果我們直接寫:
(define-syntax-parser succ
[(_ n)
(displayln (syntax-property #'n 'type))
(syntax-property #``(succ ,#,(local-expand n 'expression '())) 'type #'Nat)])
我們會得到 #f
而非 #'Nat
。而 #'Nat
之巧妙就在於這時候如果我們寫:
(syntax-property (local-expand (syntax-property (local-expand #'n 'expression '()) 'type) 'expression '()) 'type)
會得到 #'Type
。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK