sweet-core icon indicating copy to clipboard operation
sweet-core copied to clipboard

Macros don't destructure terms

Open gabejohnson opened this issue 8 years ago • 2 comments

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.

gabejohnson avatar Jan 27 '17 04:01 gabejohnson

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 .

disnet avatar Jan 27 '17 18:01 disnet

I can live w/ that. Maybe implement a Symbol method or two on Term. match/destructure.

👍 on the docs.

gabejohnson avatar Jan 27 '17 18:01 gabejohnson