3

syntax-property 與 local-expand 的實際運用

 2 years ago
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.
neoserver,ios ssh client

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK