
Here’s an implementation of “syntax functors” (definitions, including macro definitions, that can be parameterized over other bindings): https://github.com/rmculpepper/racket-functor/. Barring the discovery of any big problems, I plan to make it a package sometime in the next day or two.

This looks pretty cool

Can I use it to replace my uses of units?

If units work for what you’re doing, they’re probably a better tool for the job. Units are separately compilable because you can only parameterize over value bindings. Syntax functors only allow separate compilation of the syntax definition parts; value definitions and expressions get copied (because their expansion can depend on the syntax definitions and the imports).

This is aimed more at the “define define
once, parameterized over the lambda
form” problem.

Do they feature pervasive boxes and indirection, as units do? Also, do they break if I try to use define/contract
internally because units can’t export macros?

The linking is done with rename-transformers. But they handle run-time expressions just by copying them to the functor application site(s).

I like the idea. How does it compare to using syntax parameters for the extension points instead?

Syntax parameters have many of the problems of side effects. IIRC they interfere with partial expansion (this problem is analogous to trying to mix real and simulated effects, like using parameterize
with CPS). The parameterization can only happen at expansion-context boundaries. It can be hard to delimit the right area of effect for a syntax parameter.

Good question, though. I had an example of a limitation due to the class system’s treatment of this
that I should revisit, and see if this makes a difference. (It might not, still.)

To clarify the first line: syntax parameters have side-effect nature. Syntax functors act more like closures.

Wonderful to see this taking form. :D

@ryanc Would this be a good fit to locally use a different implementation of the same group of functions? Some use cases: switch between fast and debug functions, or locally use fixnums/float/bigfloat/algebraic arithmetic while always using the usual +-*/ operator names, etc.