I’ve just taken the time to reimplement how my curly-fn package handles the transformation in an attempt to make it a little less unwieldy. Specifically, the transformation itself is now done via macro expansion rather than being performed at read-time. This means that the curly brace syntax itself is now expanded extremely simply.
This:
#{+ 1 %}
just becomes this:
(curly-fn {+ 1 %})
and `curly-fn` is a syntax transformer that performs all the relevant introspection required to expand into a `lambda`.
Of course, that expansion doesn’t quite work. The `curly-fn` macro is defined in another module, so the curly brace syntax actually expands into this:
#'(let ()
(local-require curly-fn/private/curly-fn-transformer)
(curly-fn {+ 1 %}))
Overall, this seems to work okay.
I then decided to implement the strategy of using make-syntax-introducer to scope everything properly. This actually worked great—the following now works absolutely fine:
(let ([lambda 0])
(#{+ 1 %} 3))
; => 4
So hygiene is now preserved, but unfortunately, another one of my packages that depends on curly-fn still throws an error. Specifically, the error complains about the `let` containing the `local-require` has no binding. What’s particularly odd, though, is that this error only occurs in my documentation that uses `include-extracted` from `scribble/extract`.
After some investigation, it looks like I can get it to fail when using syntax-local-lift-require. Here’s a minimal example, again using two Racket source files:
; source.rkt
#lang curly-fn racket/base
#{values}
; lift.rkt
#lang racket
(define-syntax (lift stx)
(syntax-case stx ()
[(_ module-path)
(syntax-local-lift-require #'module-path #'id)]))
(lift "source.rkt")
That fails with the following error:
let: unbound identifier;
also, no #%app syntax transformer is bound
context.:
#(252056 module) #(252057 module) #(252265 module reader -1)
#(252266 module reader -1) #(255222 module) #(255223 module source 0)
other binding.:
#<module-path-index:(racket/base)>
#(255032 macro) #(255222 module) #(255223 module source 0) in: let
Is this a bug with syntax-local-lift-require in the new macro expander, or is it my fault (more likely)? For the version of curly-fn that causes this error, see the “stx-transformer” branch:
https://github.com/lexi-lambda/racket-curly-fn/tree/stx-transformer
Thanks, and sorry for the long message,
Alexis