sweet-core
sweet-core copied to clipboard
Macros don't destructure terms
Passing the "same" input through two consecutive transforms can lead to surprising behaviour:
syntax m = ctx => {
const term = ctx.expand('expr').value;
return #`n ${term}`;
};
syntax n = ctx => {
const [a,b,c] = ctx;
return #`${a} ${b} ${c}`;
};
m 1 + 2
// expected: 1 + 2
// actual: Error: replacement values for syntax template must not be null or undefined
Now I know why this happens. The term is already built and Enforester::advance scoops it up and spits it out. But without knowing the implementation details this is unexpected.
Of course this works as expected:
syntax m = ctx => {
const term = ctx.expand('expr').value;
return #`n ${term}`;
};
syntax n = ctx => {
const [term] = ctx;
return #`${term}`;
};
m 1 + 2
I don't think this is a bug, but it could cause some confusion. I'm wondering what the impact would be on declarative macros.
I think the current behavior is "correct" as long as we're thinking of
these APIs as being low level power tools. When you work at this level you
must be aware that a context might return you a single "token" or a
partially enforested Term. Once the API stabilizes we need some good docs
to cover this point; you and I might be the only people who know about this
subtlety at the moment 😄
Once we start working on the high-level API we definitely need a way of
smoothing over this issue. The hazy idea I've had for a while is that
something like the match form #516 would be able to look into Terms and
match on flat tokens.
On Thu, Jan 26, 2017 at 8:11 PM Gabe Johnson [email protected]
wrote:
Passing the "same" input through two consecutive transforms can lead to surprising behaviour:
syntax m = ctx => { const term = ctx.expand('expr').value; return #
n ${term}; };syntax n = ctx => { const [a,b,c] = ctx; return #
${a} ${b} ${c}; };m 1 + 2// expected: 1 + 2// actual: Error: replacement values for syntax template must not be null or undefined
Now I know why this happens. The term is already built and Enforester::advance scoops it up and spits it out. But without knowing the implementation details this is unexpected.
Of course this works as expected:
syntax m = ctx => { const term = ctx.expand('expr').value; return #
n ${term}; };syntax n = ctx => { const [term] = ctx; return #
${term}; };m 1 + 2
I don't think this is a bug, but it could cause some confusion. I don't know what the impact would be on declarative macros.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/sweet-js/sweet.js/issues/636, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAJOhGSWp7GjUDZxV8uxtfkyNlY8abXks5rWW5ZgaJpZM4Lva0E .
I can live w/ that. Maybe implement a Symbol method or two on Term. match/destructure.
👍 on the docs.