I'm trying to write a pattern matching macro. I haven't got very far but I'm already confused. My test code is as follows
#!r6rs
(import (for (rnrs base (6)) run expand)
(for (rnrs syntax-case (6)) expand)
(rnrs io simple (6)))
(define-syntax matcher
(lambda (stx)
(define (parse-clauses c)
#'x)
(syntax-case stx ()
((_ c ...)
(with-syntax ((body (parse-clauses #'(c ...))))
#'(lambda (x) body))))))
(write ((matcher) '(1 2 3))) (newline)
Executing this produces the output (1 2 3)
.
To be honest I wrote this code in the expectation that it would fail. I thought the syntax returned from parse-clauses
refers to an undefined symbol x
. But it seems that #'x
returned from parse-clauses
does reference the parameter x
in the lambda expression. I've no idea why.
This slight variation has me even more confused.
#!r6rs
(import (for (rnrs base (6)) run expand)
(for (rnrs syntax-case (6)) expand)
(rnrs io simple (6)))
(define-syntax matcher
(lambda (stx)
(define (parse-clauses c)
(let ((x 1))
#'x))
(syntax-case stx ()
((_ c ...)
(with-syntax ((body (parse-clauses #'(c ...))))
#'(lambda (x) body))))))
(write ((matcher) '(1 2 3))) (newline)
This produces the error x: identifier used out of context in: x
. This error I understand, x
is bound locally in parse-clauses
, but I'm using the reference outside of that scope so I get an error.
I guess what I'm saying is that the second example shows that the lexical context matters but in the first example there is no lexical binding for x
so how come it ends up referring to an unrelated binding?
I hope that's not too confused, any explanations welcome.
I'm using Racket 5.3.6.