Andreas Rossberg (2015-07-14T07:20:18.000Z)
All you are proposing is to allow the braces to be dropped from a
do-expression, right? That's an obvious tweak, although I'm not sure if it
really improves readability. (Other than that, do-expressions are already
intended to work as you describe, using the completion value of the
statement list. That's their whole point, after all.)

I had something else in mind. Once we have do expressions, we can introduce
syntactic sugar that effectively makes any statement syntax into legal
expressions. E.g.:

  throw expr  ~>  do { throw expr; }
  try expr catch (pat) expr  ~>  do { try { expr; } catch (pat) { expr; } }
  if (expr) expr else expr  ~>  do { if (expr) expr; else expr; }
  etc

At least for those statements for which it makes sense. To avoid ambiguity,
all you need to do is extend the existing restriction that none of the
initial keywords may start an expression statement.

But I intend to propose that separately from (or as an optional part of)
the do-expressions proposal, since it might be more controversial.

/Andreas


On 14 July 2015 at 00:47, Isiah Meadows <impinball at gmail.com> wrote:

> I was reading a recent thread
> <https://esdiscuss.org/topic/allow-try-catch-blocks-to-return-a-value> where
> do-expressions simplified a common try-catch use case, and I was wondering
> if `do` could be simplified to an expression? It would allow for this to be
> solved very easily, but also add a lot more flexibility in this proposal,
> as well as avoiding some ugly nested braces.
>
> I know it would cause an ambiguity with `do-while` loops, but that could
> be resolved with a single token lookahead of "if the next token is the
> keyword `while`, then the block body is the body of a do-while loop, else
> it is the body of the block statement in a `do` expression".
>
> As for the EBNF, do-expressions could be parsed with a goal symbol of
> either `+While` or `-While`, with do-while statements spec-wise effectively
> being treated as do-expressions without an init part run repetitively, but
> mandated to be statements.
>
> ```js
> // Do expression
> let foo = do {
>   foo(0)
> };
>
> let tried = do try {
>   foo(0)
> } catch (e) {
>   throw e
> };
>
> // Do-while statement
> let i = 0;
> do {
>   foo(i)
> } while (i++ < 10);
>
> // Combined:
> let i = 0;
> let foo9 = do do {
>   foo(i) // can have side effects, foo9 = foo(9)
> } while (i++ < 10);
> ```
>
> Another example of where this could come in handy: simplifying
> asynchronous code.
>
> ```js
> function readConfig() {
>   fs.readFileAsync('config.json', 'utf8')
>     .then(JSON.parse)
>     .then(contents => do if (contents.unexpectedProperty) {
>       throw new Error('Bad property') // rejects the promise
>     } else {
>       doSomething(contents)
>     })
>     .catch(err => process.domain.emit('err', error))
> }
>
> // With only block statement
> function readConfig() {
>   fs.readFileAsync('config.json', 'utf8')
>     .then(JSON.parse)
>     .then(contents => do {
>       if (contents.unexpectedProperty) {
>         throw new Error('Bad property') // rejects the promise
>       } else {
>         doSomething(contents)
>       }
>     })
>     .catch(err => process.domain.emit('err', error))
> }
>
> // Without do-expressions
> function readConfig() {
>   fs.readFileAsync('config.json', 'utf8')
>     .then(JSON.parse)
>     .then(contents => {
>       if (contents.unexpectedProperty) {
>         throw new Error('Bad property') // rejects the promise
>       } else {
>         doSomething(contents)
>       }
>     })
>     .catch(err => process.domain.emit('err', error))
> }
> ```
>
> As you can see, the more general version does simplify things a little.
>
> Also, if-statements look better than long ternaries IMHO, and are less
> repetitive than their counterpart, repeated assignment (us lazy typists...):
>
> ```js
> let foo = do if (someCondition) {
>   value
> } else if (someOtherCondition) {
>   value + 1
> } else if (someEdgeCase) {
>   addressEdgeCase(value)
> } else {
>   value
> }
> ```
>
> --
> Isiah Meadows
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150714/b9ad4777/attachment-0001.html>
d at domenic.me (2015-07-25T02:53:07.550Z)
All you are proposing is to allow the braces to be dropped from a
do-expression, right? That's an obvious tweak, although I'm not sure if it
really improves readability. (Other than that, do-expressions are already
intended to work as you describe, using the completion value of the
statement list. That's their whole point, after all.)

I had something else in mind. Once we have do expressions, we can introduce
syntactic sugar that effectively makes any statement syntax into legal
expressions. E.g.:

```
  throw expr  ~>  do { throw expr; }
  try expr catch (pat) expr  ~>  do { try { expr; } catch (pat) { expr; } }
  if (expr) expr else expr  ~>  do { if (expr) expr; else expr; }
  etc
```

At least for those statements for which it makes sense. To avoid ambiguity,
all you need to do is extend the existing restriction that none of the
initial keywords may start an expression statement.

But I intend to propose that separately from (or as an optional part of)
the do-expressions proposal, since it might be more controversial.