Matthew Robb (2015-07-14T13:04:57.000Z)
The only gripes I have with do expressions is the inability to specify the
value produced in an obvious and uniform way, also are do expressions
capable of being labelled?


- Matthew Robb

On Tue, Jul 14, 2015 at 3:31 AM, Andreas Rossberg <rossberg at google.com>
wrote:

> I don't see why you need parens at all, see my previous post. But I
> wouldn't make the do-less forms the base syntax,; rather, only short-hands
> for the general thing. In particular, because the ability to have an actual
> block inside an expression is one primary motivation for having
> do-expressions in the first place.
>
> ...Ah, it's 2015, and we still have to come up with ways to overcome the
> archaic statement/expression distinction from the stone ages. :)
>
> /Andreas
>
>
> On 14 July 2015 at 01:33, Mark S. Miller <erights at google.com> wrote:
>
>> Interesting. Got me thinking. Here's an alternate proposal I'll call "do
>> expressions without the 'do'."
>>
>> At <
>> https://people.mozilla.org/~jorendorff/es6-draft.html#sec-expression-statement>
>> we have the syntax of the expression statement. Ignoring sloppy "let"
>> nonsense, this says that an expression statement cannot begin with "{",
>> "function", or "class".
>>
>> At <
>> https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-language-statements-and-declarations>
>> are the legal ES6 statements. Note that most of these begin with a keyword
>> that cannot possibly be legal at the beginning of an expression. Therefore,
>> adding all these initial-statement-keywords to the list of things that
>> cannot begin an expression statement would break nothing. They already
>> cannot begin an expression statement.
>>
>> With the expression statement prohibition in place, now we can allow all
>> these forms to be expressions. As with "{", "function", or "class", if you
>> want to state such an expression in expression-statement position, surround
>> it with parens.
>>
>> Because all these new forms will look bizarre and confusing, at least at
>> first, let's say these always need surrounding parens to be expressions. I
>> think that would help minimize confusion.
>>
>> If we do this, the oddest duck is "{", since it begins an object literal
>> expression. This proposal gives us no straightforward way to express an
>> block expression. "function" and "class" are less odd, since their existing
>> expression forms mean what you almost might expect by this new rule -- even
>> though they are initial-declaration-keywords rather than
>> initial-statement-keywords.
>>
>> The remaining initial-declaration-keywords are "let" and "const". We
>> already made "let" insane regarding these issues in sloppy mode, so I'm
>> going to ignore that. But let's consider "const" and strict "let". These
>> already cannot appear at the beginning of an expression, so it would not
>> break anything to add them to the prohibition list for the beginning of
>> expression statements.
>>
>> No current expression can add any binding to the scope in which the
>> expression appears. Let's examine the consequences of having parens --
>> rather than containing a "{"-block to create a nested scope with a value
>> (which would conflict with object literals), instead simply define a
>> block-like nested scope with a value. This would allow declarations and
>> statements within the parens, much like the current "do" proposal. It would
>> even be consistent enough with the existing semantics of paren-surrounded
>> function and class expressions: Someone who sees these as a function or
>> class declaration within its own nested scope, whose value was the value
>> being declared, would rarely be surprised by the subtle difference between
>> that story and the current semantics.
>>
>> Having parens accept a list of declarations and statements rather than
>> just an expressions seems like a radical change that must break something,
>> but I can't find a problem. Am I missing something?
>>
>> Examples inline:
>>
>>
>>
>> On Mon, Jul 13, 2015 at 5:47 PM, 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 foo = (foo(0));
>>
>> This seems as broken as the original. In both cases, unless I'm missing
>> something, this is a TDZ violation when the right side evaluates foo.
>> Mistake?
>>
>>
>>>
>>> let tried = do try {
>>>   foo(0)
>>> } catch (e) {
>>>   throw e
>>> };
>>>
>>
>> let tried = (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);
>>> ```
>>>
>>
>> let i = 0;
>> let foo9 = (do { foo(i) } 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))
>>> }
>>>
>>
>> ...
>> .then(contents => (if (contents.unexpectedProperty) {
>> ...
>> }))
>> ...
>>
>>
>>>
>>> // 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
>>> }
>>> ```
>>>
>>
>> let foo = (if (someCondition) {
>> ...
>> })
>>
>>
>>
>>>
>>> --
>>> Isiah Meadows
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
>>
>> --
>>     Cheers,
>>     --MarkM
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
> _______________________________________________
> 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/7ec2d039/attachment.html>
d at domenic.me (2015-07-25T02:53:22.064Z)
The only gripes I have with do expressions is the inability to specify the
value produced in an obvious and uniform way, also are do expressions
capable of being labelled?