tc39 / proposal-do-expressions

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

Explicit return from normal statements #41

Open hagabaka opened 5 years ago

hagabaka commented 5 years ago

My suggestion is similar to #20 and #39. All statements become expressions, so do is unnecessary. However, statements will by default evaluate to undefined, and a new keyword value (TBD) allows changing the statement's value. Unlike return, the value statement does not skip following statements.

let x;

x = if (true) {
  value 3;
} // x = 3

x = if (true) {
  value 3;
  value 4;
} // x = 4: value overwrites previous uses

x = if(true) {
  3;
} // x = undefined: no implicit value

let y = 0;
x = while(y <= 10) {
 if(y === 2) {
    value y;
  }
  y++;
}
// x = 2: value can be set in nested statements
// y = 10: setting value does not lead to early return

With nested scopes it may be hard to define where value returns to. I think it should follow similar rules as return does in nested functions, if we consider any statement used as an expression to be like a function:

x = {
  {
    {
      value 1;
    }
  }
  y = {
    value 2
  };
  z = 4 + {
    value 3
  };
}
// x = 1, y = 2, z = 7: "value" applies to its outermost statement used as an expression

Compared to the current proposal and other suggestions, I think this is less of a concept leap. After all, functions in JavaScript already return undefined if they don't explicitly return. Adding a new keyword will likely lead to backward incompatibility with any code using that word as an identifier, but from what I see in some of the issues, it seems also hard to maintain compatibility by reusing existing keywords do or return, or not using any keywords.

ljharb commented 5 years ago

I believe this would break existing code relying on eval and its return value, and would also introduce grammar complexities around blocks and object literals.