[plt-scheme] Syntax hack...
Here's a problem: say I want a syntax `foo' that will do something
like capture a continuation and bind it to a known variable. The
problem is I don't want to capture the continuation if it's not going
to get used... Basically something that behaves like this:
(foo (+ 1 2)) --expands-to--> (+ 1 2)
(foo (+ 1 (break 2)) --expands-to--> (let/ec break (+ 1 (break 2)))
The only sane way I can see of solving this is to locally expand the
body and crawl over it -- but doing that I'd have to take care of
things like these:
(foo 'break) --expands-to--> 'break
(foo (let ((break 1)) break)) --expands-to--> (let ((break 1)) break)
So instead, I tought it would be nice to just bind `break' temporarily
to some syntax that I can tell if it was invoked or not. This is
implemented like this:
(define-syntax (foo stx)
(define (id-in-expr sym expr)
(let ((return #f) (id (datum->syntax-object expr sym expr)))
(local-expand
;; Note: this hacks compilation levels but it should be fine
#`(let-syntax ((#,id #,(lambda (stx) (set! return id) #'()))) #,expr)
'expression '())
return))
(syntax-case stx ()
((_ x) (cond ((id-in-expr 'break #'x) =>
(lambda (break) #`(let/ec #,break x)))
(else #'x)))))
The thing is that AFAICT this mixes compilation levels -- at the
marked spot a syntax is created with a literal function instead of
some valid syntax. This seems to be OK since that expression with the
hacked literal is never needed for saving in a compiled file or
something, it is only needed for the expansion.
So my questions are:
* Is there any other elegant way that can do this without a full code
walker implementation?
* How bad would it be to rely on this shortcut to work? (i.e, will
there ever be a restriction on syntax pieces so they will have to
evaluate to some valid syntax?)
* If something like this is useful, maybe it is best to add it as an
implementation level functionality? (So if such a restriction is
ever made, then there is one place to change...)
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!