Reconstruct-Template
Source code: https://github.com/AlexKnauth/reconstruct-template.
syntax
{~list/ctx ctx-id pattern ...}
> (syntax-parse #'(1 2 3) [{~list/ctx p a b c} (values #'a #'b #'c)])
#<syntax:eval:2:0 1>
#<syntax:eval:2:0 2>
#<syntax:eval:2:0 3>
> (syntax-parse #'[1 2 3] [{~list/ctx p a b c} (values (syntax-column #'p) (syntax-span #'p) (syntax-property #'p 'paren-shape))])
0
1
#f
syntax
{?list/ctx ctx-id template ...}
> (define stx1 #'[1 2 3])
> (define stx2 (syntax-parse stx1 [{~list/ctx p a b c} #'{?list/ctx p c b a}])) > stx1 #<syntax:eval:2:0 (1 2 3)>
> stx2 #<syntax:eval:2:0 (3 2 1)>
; same source location
> (equal? (syntax-position stx1) (syntax-position stx2)) #t
; same syntax properties
> (equal? (syntax-property stx1 'paren-shape) (syntax-property stx2 'paren-shape)) #t
; same scopes
> (bound-identifier=? (datum->syntax stx1 'x) (datum->syntax stx2 'x)) #t
The main intended use of ~list/ctx and ?list/ctx is for reconstructing syntax objects when making expanders for new core-form languages. This purpose is similar to syntax/loc/props from Alexis King’s blog post Reimplementing Hackett’s type language: expanding to custom core forms in Racket.
The main advantage of ~list/ctx and ?list/ctx over syntax/loc or syntax/loc/props is that they work even for stx-list templates nested deeply within a template, as well as for stx-list templates under ellipses. For example, if x is a well-formed let expression:
(syntax-parse x [{~list/ctx p1 l {~list/ctx p2 {~list/ctx p3 x a} ...} b} #'{?list/ctx p1 l {?list/ctx p2 {?list/ctx p3 x a} ...} b}]) = x