tc39 / proposal-do-expressions

Proposal for `do` expressions
MIT License
1.12k stars 14 forks source link

What is the expected behaviour in sub expressions of a do expression? #18

Open kasperpeulen opened 6 years ago

kasperpeulen commented 6 years ago

It would be great if subexpression of a do expression act the same as a do expression themself.

For example, consider the the code below. I would expect that the placeholders act as do expressions as well.

const template = (user) => do `
  <button>
    ${
      if (user.loggedIn) {
        loginButton(user);
      } else if (user == null) {
        registerButton();
      } else {
        logoutButton(user); 
      } 
    }
  </button>
`;
ljharb commented 6 years ago

The placeholders are a new JS context; i'd definitely be surprised by that. I'd expect you need a do inside each set of curly braces if you wanted them to act like a do.

pitaj commented 6 years ago

A new JS context? You might need to expand on that. In my opinion, every sub-expression and sub-block should inherit the expression-oriented syntax, with the exception, maybe, of functions, since hoisting is a question.

ljharb commented 6 years ago

That would be very strange; the "expression-oriented syntax" you describe imo should only be at the top-most level.

ljharb commented 6 years ago

(iow it's not a mode, it's an expression)

pitaj commented 6 years ago

If it's only top level, this common example wouldn't work:

if (thing) {
  5;
} else {
  3;
}
pitaj commented 6 years ago

Unless your definition of top-level is different. You should provide examples.

ljharb commented 6 years ago

Hmm, that's a fair point.

I'd expect the boundary to be a new scope - ie, any function or class - as well as template literals.

pitaj commented 6 years ago

I think this also kind of relates to the two issues about treating if, else, switch, etc as expressions instead of statements. If that's possible then this discussion is irrelevant. For instance, inside a do block right now is it possible to do the following:

const x = if (y) { 3; } else { 4; };

I don't think so, it looks like you'd need to have another do block around that.

ljharb commented 6 years ago

I also think you would need to have another do block around that.

bakkot commented 3 years ago

I don't think this really makes sense with how the rest of the language works. The idea is that do is a very simple wrapper for statements which you could write in any other context, rather than changing the meaning of those statements. As such, if ${ can't contain an statement in any other code, its workings shouldn't suddenly change when it happens to be nested within a do.

(I'm not entirely clear on what @ljharb means by "a new JS context".)

@pitaj

For instance, inside a do block right now is it possible to do the following

const x = if (y) { 3; } else { 4; };

No, following the principle I stated above: since you can't do that outside of a do, you shouldn't suddenly be able to do it within one.

ljharb commented 3 years ago

By "context" I mean a brand new place in which to put code. I agree with your analysis.