tc39 / proposal-do-expressions

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

"use expressions" directive #43

Open pvider opened 5 years ago

pvider commented 5 years ago

Write "use expressions" directive like we write "use strict" and have statements-as-expression powered language. "use expressions" makes every statement in the end of a block behave like expression. No more ambiguites, no more syntatic noise, no more thinking about legacy compatibility, no more mental switching between statements-as-expression and statement-is-not-expression. Just two words in the beginning of your code. I want to have better language after all without extra moves. And with above directive we will have very good chance of enabling it by default with time. Without it we will have a language with outdated concepts and software crutches.

FireyFly commented 5 years ago

My understanding from previous discussions (admittedly a few years back) about adding new pragmas like the strict-mode one is that it'd go against the "1JS" goal of having a single versionless language. "use strict" was a bit of a one-off exception to get rid of some really annoying legacy behaviour.

It's also a bit of a special-case that the move to modules and type="module" lets us make it a "new default" without breaking any old code. I don't think you could really accomplish the same with something like "use expressions" in the long run, so I'm not sure it could ever be made a default without breaking old code.

So, as much as I'd enjoy writing code in such a language that you suggest, I don't think it's really viable. :\

alamothe commented 4 years ago

Best proposal ever. do is just noise, every statement should be an expression, like Brendan Eich intended.

ghost commented 3 years ago

Pretty late, but I would support the idea behind this issue if it were made into a proposal over the "do statement" proposal any day.

I was literally thinking that I would just use do statements in functions, but that seems backward, we should really just have this as the default.

@FireyFly Also, technically, it's backward-compatible:

const sign = (n) => {
    if ( n > 0 ) {
        1;
    } else if ( n < 0 ) {
        -1;
    } else {
        0;
    }
};

If that were written today, it wouldn't do anything, but it runs.

If the "use expressions" happened, this would remain unaffected.

Now, if you put the use expressions above it, or in the function only then would it change.

kenbellows commented 3 years ago

While I agree that this would be awesome, I have a hard time imagining this being adopted, mainly for the reasons @FireyFly mentioned. I imagine that enabling a sort of expressions mode would open a bunch of questions about how various parts of the language should behave, and I have to assume (as someone who has never worked on a JS engine) that it would require introducing a ton of logic throughout the engine to modify behavior based on whether expressions mode is enabled.

But regardless, even if none of that is true (and it might not be, I'm no expert), "use expressions" should probably be put into its own separate proposal if it is to be pursued or discussed further. While it does overlap with some of the intent of do-expressions, they have very different scopes, and they are not mutually exclusive: even in an expressions-based JS, we'd still need some construct to allow for blocks on the right-hand-side of an assignment to accomplish the goal of this proposal.

IMO, close this issue, and if anyone wants to pursue "use expressions", start a separate proposal.

stiff commented 3 years ago

Maybe even better would be "use ES2020" which will assume if-as-expression, deprecate and fix other long-waiting-to-be-fixed pains?

ghost commented 3 years ago

Something like "use ES2020" really ought to be exclusive to modules. Is what we want just a versioned language, the opposite of what W3C and HTMLWG are following?

Maybe we ought to just embrace Wasm, and compile a langauge that already does this stuff to it? It has explicit versioning, so it's allowed to break backward compatabilitiy.

MaxGraey commented 3 years ago

I also think global "use expression" mode is a best solution. Mixed semantics will produce a lot of problems. Already creates problems. In addition, pattern matching is now an expression, although it does not explicitly use the do expression block. Thus, it will also make pattern matching more safe, which, for example, becomes available only in this global expression mode.

ghost commented 3 years ago

I must've overlooked it, but what was previously said,

even in an expressions-based JS, we'd still need some construct to allow for blocks on the right-hand-side of an assignment to accomplish the goal of this proposal.

this makes a "use expression" completely useless.

I was thinking of eval semantics, like how this code would work:

const e = eval(`
try {
    0 + 0n;
} catch (e) {
  e
}
`);

the constant variable e should contain a type error. With do blocks, we'd have this:

const e = do {
    try {
        0 + 0n;
    } catch (e) {
        e
    }
};

because the do block may be in (I don't know the correct terminology for it), what I call a "value postion," or a rhs position.

Allowing this:

const e = try {
    0 + 0n;
} catch (e) {
    e
};

would be both, awesome from a developer perspective, but potentially hard to implement, and as was said, it may cause abiguous syntax/grammer now.

Consider simple object assignment:

const point_1d = {
    x: 1
};

is this an object with a property x, that has the value of 1.0? Or, is this a block scope that has a label x with the statement 1, meaning that 1d_point === 1?