Skip to content

Hackable mode

We want to enable REPL-driven development on the target. For this we need full support for syntax expanders, and ideally a run-time module registry as well, including all bindings (or maybe only exported bindings) from those modules that are part of the compilation unit. This is going to produce large and slow binaries, and itself be a bit large and slow to compile, but it's an important use case.

I propose to add a --hackable / #:hackable? #t flag to the different compilation interfaces. This is what you would use when compiling in active development. It would:

  • Make it so that modules add their definitions to a run-time registry, instead of modules only existing at compile-time
    • This may be all internal and exported definitions, or only exported definitions. Internal definitions would let you "enter" a module and evaluate expressions in its context.
    • Definitions may be mutable (captured via (case-lambda (() foo) ((x) (set! foo x)))), or they may be immutable (throwing an error for the unary case). Having a set! in the source code will prevent inlining and most kinds of optimization; this would be like -O0. Sometimes you may want something like -O1, in which you can import modules but not mutate their bindings and not get inside the modules.
  • Residualize syntax transformers for the target. In this way you will be able to use match et al there.
    • This also solves a thorny issue, which is how to make the current-module form work: you need to refer to syntax transformers by value, which isn't allowed by psyntax. It works instead to reference them from modules.
    • One unknown is how to map a binding present in a lexical environment (as from syntax-local-bindings) to a name under which that binding is exported from some module. But, I think we could use the expand-time module graph to do this.
  • Also turn on all WebAssembly debugging things such as the name section.