Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

If you treat the statement as an expression, I do not think you need a do-expressions #11

Closed
kgtkr opened this issue Oct 16, 2017 · 5 comments

Comments

@kgtkr
Copy link

kgtkr commented Oct 16, 2017

This one can be written more simply.
This is a README sample code.

let x = {
  let tmp = f();
  tmp * tmp + 1
};
let x = if (foo()) {
  f();
}else if (bar()) {
  g();
}else {
  h();
}
return (
  <nav>
    <Home />
    {
        if (loggedIn) {
          <LogoutButton />
        } else {
          <LoginButton />
        }
    }
  </nav>
)
@kgtkr kgtkr changed the title If you treat the statement as an expression, I do not think you need a do expression If you treat the statement as an expression, I do not think you need a do-expressions Oct 16, 2017
@krzkaczor
Copy link

I also keep thinking about this. What if we would change language semantics to make various statements (if, switch etc.) expressions instead.

I keep wondering if there is a way that this is not backward compatible but as long as we don't try to infer return at the end of the functions (rust style) it should be fine.

What do you think? @dherman Is it discussed somewhere already?

@kornelski
Copy link

kornelski commented Oct 23, 2017

This is how Rust works (the first example is a valid Rust syntax!), and I love it.

There are no statements. Everything is an expression. Constructs that don't have anything sensible to return (e.g. while) return a special value (), which is sort-of like void/undefined.

@Jessidhia
Copy link

Seems related to #9

@dead-claudia
Copy link

There are two big complications to be aware of:

  1. If you were to have both do expressions and do ... while expressions, they'd conflict in cases like this, where ASI is at play:

    var x = do {
    }
    while (foo)
    {}
    
    // Option 1
    var x = do {};
    while (foo) {}
    
    // Option 2
    var x = do {} while (foo);
    {}
  2. How would you handle block statements? They would conflict with objects, and if you prefix them with do, you'd run into the same ambiguity as 1.

Not that I'm against this idea (I'm actually vehemently in favor of it), but there are things to look out for, and the naïve way of doing it won't work as you would expect.


One way to resolve this ambiguity is by disallowing do ... while statements as expressions and disallowing non-parenthesized do expressions as statements.

Also, doing this (making most statements expressions) would simplify the grammar and literally every parser out there, because they can check 99% of statements and expressions at the same time, only branching for very specific cases like in the case of object literals and do expressions vs block statements and do ... while loops, where the latter is only used in block statement lists.

  • For Statement, only BlockStatement, ExpressionStatement, and a few lines of IterationStatement (specifically those for do ... while) would be kept.
  • do would be banned by lookahead from ExpressionStatement.
  • The rest of that production would be moved to Expression, and `do` BlockStatement would be added to it.

(Note: this idea should be backwards-compatible, despite the significant change.)

@bakkot
Copy link
Collaborator

bakkot commented Jan 30, 2021

I'm going to close this in favor of #39, which is the same proposal but has more discussion. Please see my most recent comment there, in particular.

@bakkot bakkot closed this as completed Jan 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants