• @Robin, I am attempting to report a parsing error, not a semantic error, and “while (0,0);” is a minimal reproduction. It is not intended to be a full, useful program; just the shortest and simplest snippet I can concoct that triggers the error, to assist with debugging. I did also explain what real examples would look like and why I care.

    I apologise for not including the link https://tc39.es/ecma262/multipage/ecmasc­ript-language-statements-and-declaration­s.html#sec-while-statement ; I truly didn't think it was necessary, because I thought everyone here would know what the comma operator is and does. Mea culpa.

    In any case, the standard, at that link, says this:

    Syntax
    WhileStatement[Yield, Await, Return] :
    while ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]

    (and similarly for for statements, which are also affected by the bug).

    I don't really understand your point about truthiness. “x = costlyAccessor(i++), p(x.a, x.b)” returns the value of p(…), not the value of x. Per https://tc39.es/ecma262/multipage/ecmasc­ript-language-expressions.html#sec-comma­-operator-runtime-semantics-evaluation :

    13.16.1 Runtime Semantics: Evaluation
    Expression : Expression , AssignmentExpression

    1. Let lref be the result of evaluating Expression.
    2. Perform ? GetValue(lref).
    3. Let rref be the result of evaluating AssignmentExpression.
    4. Return ? GetValue(rref).

    In short, it does the same thing as in every other language in the C family, evaluating the value on the left, then evaluating and returning the value on the right. The use in loop conditions is generally consider to be the principal motivation for the existence of the operator, since elsewhere you can usually accomplish the same thing with some unpacking and a semicolon. Admittedly it is more commonly used in for loops than in while loops, but again, I was seeking the easiest example to debug the grammar on.

  • Sat 2021.10.16

    Thank you for posting that link @user135362 allowing us all to be on the same page. It eliminates the reader's possible confusion as to which reference is being used. The number of times a reference has been made to inacurate document detail, or an in process document constantly changing.

    The references I mentioned indicate a conditional expression to be evaluated within the while, while that comma operator contains both a statement expression as well. So should the statement expression also be evaluated as a conditional as in the reference example shown?

    As you pointed, I've only ever seen that in use to separate a list of increment operators inside the end of a for loop, and I have to agree with @allObjects that it adds too much confusion when not quickly readable/understandable by the onlooker.

    Another 'gotcha' is that it wouldn't be possible to insert Espruino's WebIDE editor side debugger statement at that point in order to single step debug. (didn't test that though)

    Also, if we keep expanding our expectations, feature creep will eventually not leave enough RAM for us to play!

    http://www.espruino.com/Features

  • I don't quite understand the question. The comma operator is a normal operator valid in any full Expression (13.16 ). It is historically descended from Algol68's semicolon operator, and (despite the different precedence) semantically related to JS's && operator. Like && it processes the left argument and returns the right; unlike && it voids the left argument and proceeds unconditionally. In fact, I suspect a, b could be defined (semantically) as !a < 2 && b or some such stupidity.

    Syntactically it has only one oddity, which is that it, like the bare assignment operator, is also used for other things, such as forming VariableDeclarationLists (14.3.2) and ArgumentLists (13.3), which means that there are places where the semantic expectation is an expression but the syntax restricts you to an AssignmentExpression to resolve the ambiguity of which kind of comma is expected.

    In any case, none of this has anything to do with the conditions in control constructs, which are uniformly and uncomplicatedly Expressions (14.6, 14.7.2.1, 14.7.3.1, 14.7.4, 14.7.5, 14.12).

    There's also no case to be made that it is a semantic restriction of Espruino or its debugging mechanism, since the semantically identical while ((0, 0)); parses and executes flawlessly. This is nothing but an issue with Espruino's internal grammar, as far as I can see, either a typo (I hope) or an utterly capricious decision to alter the syntax of while () while not even making the same change for if ().

    To the argument that this feature of the language is not pretty and adds confusion, all I can say is that today it was recommended to me that I replace
    search: while (…) while (…) if (…) break search; (which Espruino does not implement) with
    (() => {while (…) while (…) if (…) return;})();. It does not appear that prettiness and lack of visual confusion is the driving force behind this project(!). And, for goodness' sake, if you really hate the comma operator so passionately, why allow it in if and switch?

    Orthogonality and lack of bugs are generally considered virtues in the programming language community; I'm honestly not sure what's going on here. If it's that efficiency trumps usability, then what's the point of Espruino at all? C, or indeed assembly, is easy enough to write; I came here in the expectation that things would “just work” without too much hassle :-}.

About

Avatar for Robin @Robin started