Suppose we're writing interpreters interp0 and interp1 for languages L0 and L1 respectively. L0 has numbers and binary addition, and L1 extends L0 with binary multiplication. Goal. Write interp1 without copying all the cases from interp0.
Example Before
One solution is to write the interpreters in open-recursive style. Instead of recurring directly, recursive calls occur indirectly through an extra parameter. An interpreter can be invoked by closing the recursion using a fixed-point combinator.
For a valid input, define-extend generates two variants of the procedure: a closed version and an open version. It then creates a transformer binding that records the name of both these variants in an extensible struct. This struct has prop:rename-transformer so that calling the procedure defaults to the closed variant.
When defining an extension of procedure f, we make sure to shadow the binding of f within the body of the extension so as to close it off appropriately. We use the extensible struct (found by syntax-local-value/immediate) to get the identifier of the open version of f.
Suppose we're writing interpreters
interp0
andinterp1
for languagesL0
andL1
respectively.L0
has numbers and binary addition, andL1
extendsL0
with binary multiplication. Goal. Writeinterp1
without copying all the cases frominterp0
.Example Before
One solution is to write the interpreters in open-recursive style. Instead of recurring directly, recursive calls occur indirectly through an extra parameter. An interpreter can be invoked by closing the recursion using a fixed-point combinator.
Example After
The
define-extend
macro allows you to write extensible procedures in a more natural style.This macro supports some static checking. If the procedure we're extending wasn't defined using
define-extend
, then we get a compile-time error.Macro
For a valid input,
define-extend
generates two variants of the procedure: a closed version and an open version. It then creates a transformer binding that records the name of both these variants in anextensible
struct. This struct hasprop:rename-transformer
so that calling the procedure defaults to the closed variant.When defining an extension of procedure
f
, we make sure to shadow the binding off
within the body of the extension so as to close it off appropriately. We use theextensible
struct (found bysyntax-local-value/immediate
) to get the identifier of the open version off
.License
MIT License and CC BY 4.0