gelisam / klister

an implementation of stuck macros
BSD 3-Clause "New" or "Revised" License
128 stars 11 forks source link

local-expand #247

Open gelisam opened 6 days ago

gelisam commented 6 days ago

We can imagine two versions of local-expand.

local-expand-syntax executes at phase 1, takes a Syntax object and expands it at phase 0, producing a Syntax object. Syntax objects can be deconstructed with open-syntax, spliced into larger Syntax objects with close-syntax, and eventually returned by the macro.

local-expand-core executes at phase 1, takes a Syntax object and expands it at phase 0, producing an opaque value of type Core. Values of type Core can be deconstructed carefully, producing well-formed Core sub-terms, they can be embedded into larger Syntax objects, and eventually returned by the macro.

One disadvantage of local-expand-syntax is that once the Syntax it returns is returned by the macro, the expander needs to expand it again, even though it is known to already contain only core constructs. This can lead to quadratic performance in some cases, and for this reason, we have long wanted Klister to have local-expand-core.

gelisam commented 6 days ago

I think it might make sense to have a variant of local-expand-syntax which only expands a single user macro for one step. For example, if (list 1) expands to (:: 1 (list)) and then to (:: 1 (nil)), it would help with examples and debugging to get (list 1) rather than (:: 1 (nil)) or its core representation.

gelisam commented 6 days ago

local-expand-core seems related to #119.

It seems unwise to expose Klister's definition of Core, that seems like an implementation detail which is likely to change and Klister is specifically designed to help the programmer write programs which do not depend on implementation details such as the order in which the type-checker and the expander perform their steps. However, once programmers are able to define their own domain-specific MyCore language, then it starts to make a lot of sense to call local-expand-my-core on a Syntax object in order to obtain a MyCore value whose possible constructors are well-known to the programmer.