On 14 July 2015 at 15:04, Matthew Robb <[email protected]> wrote:
> The only gripes I have with do expressions is the inability to specify the > value produced in an obvious and uniform way, > Well, the completion value is fairly uniform. You mean an analogue to a return in a function body? > also are do expressions capable of being labelled? > No, but they can of course contain a labelled statement, which is equivalently expressive. /Andreas On Tue, Jul 14, 2015 at 3:31 AM, Andreas Rossberg <[email protected]> > 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 <[email protected]> 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 <[email protected]> >>> 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 >>>> [email protected] >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> >>> >>> -- >>> Cheers, >>> --MarkM >>> >>> _______________________________________________ >>> es-discuss mailing list >>> [email protected] >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> >> _______________________________________________ >> es-discuss mailing list >> [email protected] >> https://mail.mozilla.org/listinfo/es-discuss >> >> >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

