Precedence of yield operator

Dean Tribble tribble at
Fri Jun 14 14:39:50 PDT 2013

This is a familiar discussion from C#. I forwarded it to the mediator of
that convresation and got a nice summary, pasted here:

---------- Forwarded message ----------
From: Mads Torgersen <Mads.Torgersen at>
Date: Fri, Jun 14, 2013 at 2:11 PM
Subject: RE: Precedence of yield operator
To: Dean Tribble <tribble at>

I’m not on the mailing list. Feel free to forward to it.****

** **

In C# we have separate keywords too, and indeed the precedence differs as
described below. For “yield return” (our yield) the lower precendence falls
out naturally since it engenders a statement, not an

** “await” is not a reserved keyword in C# either, but we managed to wedge
it in all the same. Just adding await as an operator would lead to all
kinds of ambiguity; e.g. “await (x)” could be a function call or an await
expression, and the statement “await x;” could be a variable declaration or
an await statement.

** **

However, in C# “await” is only allowed inside methods marked “async”, and
since there weren’t any of those around before the feature was introduced,
it is not a breaking change. Inside non-async methods, therefore, “await”
continues to be just an identifier.****

** **

I don’t know if a similar thing is possible in EcmaScript. But I believe
that a low-precedence yield as a substitute for a high-precedence await is
problematic: you never want “yield a + yield b” to mean “yield (a + (yield
b))”: the things you await – Task, Promises, Futures, whatever you call
them – just don’t have operators defined on them, and it would be silly to
parse them as if they might and then give errors (at runtime in EcmaScript,
at compile time in e.g. TypeScript).****

** **


On Fri, Jun 14, 2013 at 11:07 AM, Brendan Eich <brendan at> wrote:

> Bruno Jouhier wrote:
>> While playing with my little async/await library, I noticed that I was
>> often forced to parenthesize yield expressions as (yield exp) because of
>> the low precedence of the yield operator. Typical patterns are:
>> var foo = (yield a()) + (yield b()) + (yield c());
> That's actually a hard case, IMHO -- and "hard cases make bad law".
> Many programmers would rather have the extra parens for uncertain cases
> (C's misplaced bitwise-logical and shift operators, vs.
> equality/relational; anything novel such as yield).
> But the real reason for yield being low precedence is to avoid precedence
> inversion. Consider if yield could be high-precedence, say a unary operator
> like delete:
> let x = yield a + b;
> Oops, many people would want that to be equivalent to
> let x = yield (a + b);
> but if yield is at delete's precence level, it's rather:
> let x = (yield a) + b;
> Which is the rare ("hard", from law school) case.
> For commutative operators such as +, over-parenthesizing is better again,
> because
> let x = b + (yield a);
> and
> let x = (yield a) + b;
> ignoring order of effects in shared mutable store, and ignoring floating
> point non-determinism, are equivalent.
> /be
> ______________________________**_________________
> es-discuss mailing list
> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list