Re: Exponentiation operator precedence
On Thu, Sep 24, 2015 at 8:14 AM, Mark S. Millerwrote: > I like #4. Normally in a situation like this I would still argue for #1. > #4 is a complicated special case that breaks the normal pattern of operator > precedence elsewhere in the language. The need for ** is not great enough > to justify introducing a new special case for users to learn. > > However, in this case, #4 is only technically complicated -- for those > writing or reading spec docs like us. For normal users, the only complexity > is a rarely encountered surprising static error. With a decent (and easy to > generate) error message, these users will immediately know what they need > to do to repair their program. > > Significant programs are read much more than they are written. Both #2 and > #3 will lead many readers to misread programs. For programs that are not > rejected, #4 is no more confusing than #1. Altogether, for readers, #4 is > better than #1 because ** is more readable than Pow. > MarkM, I'm surprised you didn't also mention that there is precedent for #4 from your own E. The E language chose to place math operations as methods on numbers, rather than on any static "Math" object, and does not have an exponentiation operator. In order to avoid precedence surprises of the category we're discussing, E statically rejects the combination of a unary prefix (negation) and unary postfix (method call) operator. -(2).pow(2) # "ought to be" -4, is a syntax error -(2).max(2) # "ought to be" 2, is a syntax error (The parentheses around the number are not actually required in E, but I have included them for the sake of comparison to JS despite the lexical rejection of "1.foo" in JS.) JavaScript already syntactically accepts the above programs (parsing "-" as lower precedence than ".foo()"), but #4 is in the same spirit of rejecting cases where there are conflicting or unclear precedents for operator precedence. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Claude Pache wrote: I just wonder why it is important that unary binds tighter? For instance, before I carefully studied the issue of this thread, I have never expected that unary minus binds tighter than binary multiplication operator in expressions like `-2*x` (although it does not matter in that case). Making the parentheses mandatory here will be somewhat annoying in perfectly reasonable expressions, where you usually don’t use parentheses in real math notation., like: ``` let s2 = - x**2 - y**2 - z**2 + t**2 ``` I would overcome it and do not write the parens: let s2 = 0 - x**2 - y**2 - z**2 + t**2 Writing mandatory parens here is ugly. In fact, I am surprised "-2" is unary minus with 2, I thought it is number -2. And similarly to Claude, I always read -x*y in math notation, that is, as -(x*y). Luckily, for multiplication it does not matter. Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Herby Vojčík wrote: Claude Pache wrote: I just wonder why it is important that unary binds tighter? For instance, before I carefully studied the issue of this thread, I have never expected that unary minus binds tighter than binary multiplication operator in expressions like `-2*x` (although it does not matter in that case). Making the parentheses mandatory here will be somewhat annoying in perfectly reasonable expressions, where you usually don’t use parentheses in real math notation., like: ``` let s2 = - x**2 - y**2 - z**2 + t**2 ``` I would overcome it and do not write the parens: let s2 = 0 - x**2 - y**2 - z**2 + t**2 An off-topic thought: Unary minus (and plus) are only used with numbers in JS. Why are they treated specially, not as hidden 0+x and 0-x, respectively? That would be logical (unary plus and minus would have same precendence as binary plus and minus). Writing mandatory parens here is ugly. In fact, I am surprised "-2" is unary minus with 2, I thought it is number -2. And similarly to Claude, I always read -x*y in math notation, that is, as -(x*y). Luckily, for multiplication it does not matter. Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Because C (B, BCPL, Algol). Too late to change JS where people do tricks such as !-x. No win in risking compat break. /be On Fri, Sep 25, 2015 at 4:18 AM Herby Vojčíkwrote: > > > Herby Vojčík wrote: > > > > > > Claude Pache wrote: > >> > >> I just wonder why it is important that unary binds tighter? For > >> instance, before I carefully studied the issue of this thread, I have > >> never expected that unary minus binds tighter than binary multiplication > >> operator in expressions like `-2*x` (although it does not matter in that > >> case). > >> > >> Making the parentheses mandatory here will be somewhat annoying in > >> perfectly reasonable expressions, where you usually don’t use > >> parentheses in real math notation., like: > >> ``` > >> let s2 = - x**2 - y**2 - z**2 + t**2 > >> ``` > > > > I would overcome it and do not write the parens: > > > > let s2 = 0 - x**2 - y**2 - z**2 + t**2 > > An off-topic thought: Unary minus (and plus) are only used with numbers > in JS. Why are they treated specially, not as hidden 0+x and 0-x, > respectively? That would be logical (unary plus and minus would have > same precendence as binary plus and minus). > > > Writing mandatory parens here is ugly. > > > > In fact, I am surprised "-2" is unary minus with 2, I thought it is > > number -2. And similarly to Claude, I always read -x*y in math notation, > > that is, as -(x*y). Luckily, for multiplication it does not matter. > > > > Herby > > ___ > > es-discuss mailing list > > es-discuss@mozilla.org > > https://mail.mozilla.org/listinfo/es-discuss > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
One advantage of #4 is that it will make it possible to introduce either #2 or #3 in the future, if we change our minds. This way we can use real world use cases to decide if we should go for #2 or #3. Marius Gundersen On Fri, Sep 25, 2015 at 1:23 AM, Waldemar Horwatwrote: > My preference is for 2, but I don't have objections to 4. Either works. > > Waldemar > > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Quick update from TC39 yesterday where Rick and I presented the Stage 3 Exponentiation Operator proposal: http://rwaldron.github.io/exponentiation-operator/ The current spec, revised to match precedent from all known programming languages that have exponentiation operators, binds -x^y = -(x^y ) and not -x^y = (-x)^y as the original proposal specified. These examples use Math notation, but the proposed exponentiation operator is infix ** of course. And that's the source of trouble for this proposal. The problem is, however rare unary minus before an exponentiation expression may be, the lack of superscript-with-smaller-font sugests that - binds tighter than **. And indeed apart from dot (a special form whose right operand must be a lexical identifier-name) and square brackets (which isn't an infix operator per se), unary operators bind tighter than binary in JS as in C and other C-derived languages. Yehuda suggested that exponentiation was "cargo-culted" from Math into Fortran, and then into other languages, without considering the notational shift and the apparent precedence inversion. I don't know the history, but it's plausible, and numerics folks probably would not expect unary - to bind tighter than exponentiation. But JS programmers may see -x and especially -2 as a tighter expression, if not a single lexeme, than any expression joined by infix **. We debated the options, which I think are four in number: 1. Give up because the proposal has hit a "wall of confusion". 2. Stick with the current spec, 3. Go back to the old spec, which flouts precedent. 4. Make unparenthesized exponentiation expression as operand of unary operators an early error. I came up with (4) late in the day, and it didn't get a fair hearing. Before I wrote it up on the board, I asked for a straw poll (those can bite back by forcing people onto a bandwagon, as Dave Herman pointed out) on (1-3). The poll favored (2), with notable but minority positions for (1) and (3). The grammar change needed for (4) is trivial. Instead of UnaryExpression_[Yield] : IncrementExpression_[?Yield] delete UnaryExpression_[?Yield] void UnaryExpression_[?Yield] typeof UnaryExpression_[?Yield] + UnaryExpression_[?Yield] - UnaryExpression_[?Yield] ~ UnaryExpression_[?Yield] !UnaryExpression_[?Yield] IncrementExpression_[?Yield] ** UnaryExpression_[?Yield] we factor to require parentheses around the last right-hand side if it is an operand of a unary operator: UnaryExpression_[Yield] : SimpleUnaryExpression_[?Yield] IncrementExpression_[?Yield] ** UnaryExpression_[?Yield] SimpleUnaryExpression_[Yield] : IncrementExpression_[?Yield] delete SimpleUnaryExpression_[?Yield] void SimpleUnaryExpression_[?Yield] typeof SimpleUnaryExpression_[?Yield] + SimpleUnaryExpression_[?Yield] - SimpleUnaryExpression_[?Yield] ~ SimpleUnaryExpression_[?Yield] !SimpleUnaryExpression_[?Yield] (It would be nice to rename non-terminals like so: s/\/ExponentiationExpression/g; s/\ /UnaryExpression/g where \<\> are left and right word boundaries -- but I'm leaving this out for now since it touches more of the spec and is merely a nominal change.) Thus one may write let z = K - x**y; without having to parenthesize unduly, but one cannot write let z = -x ** y; The user is forced by an early error to write either (-x)**y or -(x**y). The early error stops parsing with a thrown SyntaxError. It seems to me (4) wins and rescues the proposal at stage 3 from suffering a loss of consensus. Comments welcome. /be Jason Orendorff wrote: Don't rely on github searches to turn up representative examples. It doesn't work that well. Here's my educated guess as to how ** will be used. The most common use will be to square numbers. a² a**2 Math.pow(a, 2) a.pow(2) Currently you might write `a * a`, which is kind of lame. So where's the benefit? If this trivial thing is the most common use of exponentation, why bother? The ability to look at an expression and understand it at a glance is a big deal. x² + y²> limit x**2 + y**2> limit Math.pow(x, 2) + Math.pow(y, 2)> limit x.pow(2) + y.pow(2)> limit A big big deal. It's the reason we have arithmetic operators in JS in the first place. Exponentiation is common when computing easing functions, curves for graphics, interest, simulations, random stuff in games. Nth roots are fairly common too (`apr**(1/12)`). In all of these cases, the user is doing the same thing: translating a mathematical formula they wish to use from "math" to JS. It is not extra hard to translate such a formula using Math.pow(), but it is harder to read once you're done. You have to mentally translate back to "math". -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss
Re: Exponentiation operator precedence
[Apologies for resending, trying to fix formatting of grammar excerpts. /be] Quick update from TC39 yesterday where Rick and I presented the Stage 3 Exponentiation Operator proposal: http://rwaldron.github.io/exponentiation-operator/ The current spec, revised to match precedent from all known programming languages that have exponentiation operators, binds -x^y = -(x^y ) and not -x^y = (-x)^y as the original proposal specified. These examples use Math notation, but the proposed exponentiation operator is infix ** of course. And that's the source of trouble for this proposal. The problem is, however rare unary minus before an exponentiation expression may be, the lack of superscript-with-smaller-font sugests that - binds tighter than **. And indeed apart from dot (a special form whose right operand must be a lexical identifier-name) and square brackets (which isn't an infix operator per se), unary operators bind tighter than binary in JS as in C and other C-derived languages. Yehuda suggested that exponentiation was "cargo-culted" from Math into Fortran, and then into other languages, without considering the notational shift and the apparent precedence inversion. I don't know the history, but it's plausible, and numerics folks probably would not expect unary - to bind tighter than exponentiation. But JS programmers may see -x and especially -2 as a tighter expression, if not a single lexeme, than any expression joined by infix **. We debated the options, which I think are four in number: 1. Give up because the proposal has hit a "wall of confusion". 2. Stick with the current spec, 3. Go back to the old spec, which flouts precedent. 4. Make unparenthesized exponentiation expression as operand of unary operators an early error. I came up with (4) late in the day, and it didn't get a fair hearing. Before I wrote it up on the board, I asked for a straw poll (those can bite back by forcing people onto a bandwagon, as Dave Herman pointed out) on (1-3). The poll favored (2), with notable but minority positions for (1) and (3). The grammar change needed for (4) is trivial. Instead of UnaryExpression_[Yield] : IncrementExpression_[?Yield] delete UnaryExpression_[?Yield] void UnaryExpression_[?Yield] typeof UnaryExpression_[?Yield] + UnaryExpression_[?Yield] - UnaryExpression_[?Yield] ~ UnaryExpression_[?Yield] !UnaryExpression_[?Yield] IncrementExpression_[?Yield] ** UnaryExpression_[?Yield] we factor to require parentheses around the last right-hand side if it is an operand of a unary operator: UnaryExpression_[Yield] : SimpleUnaryExpression_[?Yield] IncrementExpression_[?Yield] ** UnaryExpression_[?Yield] SimpleUnaryExpression_[Yield] : IncrementExpression_[?Yield] delete SimpleUnaryExpression_[?Yield] void SimpleUnaryExpression_[?Yield] typeof SimpleUnaryExpression_[?Yield] + SimpleUnaryExpression_[?Yield] - SimpleUnaryExpression_[?Yield] ~ SimpleUnaryExpression_[?Yield] !SimpleUnaryExpression_[?Yield] (It would be nice to rename non-terminals like so: s/\/ExponentiationExpression/g; s/\ /UnaryExpression/g where \<\> are left and right word boundaries -- but I'm leaving this out for now since it touches more of the spec and is merely a nominal change.) Thus one may write let z = K - x**y; without having to parenthesize unduly, but one cannot write let z = -x ** y; The user is forced by an early error to write either (-x)**y or -(x**y). The early error stops parsing with a thrown SyntaxError. It seems to me (4) wins and rescues the proposal at stage 3 from suffering a loss of consensus. Comments welcome. /be Jason Orendorff wrote: Don't rely on github searches to turn up representative examples. It doesn't work that well. Here's my educated guess as to how ** will be used. The most common use will be to square numbers. a² a**2 Math.pow(a, 2) a.pow(2) Currently you might write `a * a`, which is kind of lame. So where's the benefit? If this trivial thing is the most common use of exponentation, why bother? The ability to look at an expression and understand it at a glance is a big deal. x² + y²> limit x**2 + y**2> limit Math.pow(x, 2) + Math.pow(y, 2)> limit x.pow(2) + y.pow(2)> limit A big big deal. It's the reason we have arithmetic operators in JS in the first place. Exponentiation is common when computing easing functions, curves for graphics, interest, simulations, random stuff in games. Nth roots are fairly common too (`apr**(1/12)`). In all of these cases, the user is doing the same thing: translating a mathematical formula they wish to use from "math" to JS. It is not extra hard to translate such a formula using Math.pow(), but it is harder to read once you're done. You have to mentally translate back to "math". -j ___ es-discuss mailing list
Re: Exponentiation operator precedence
Here's a nicely formatted jsbin version of my message: http://jsbin.com/bihilaveda Sorry about the mess, mail user agents (at least Postbox) and archive software do not like explicit indentation. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Even nicer: http://jsbin.com/baquqokujo I hate email. /be Brendan Eich wrote: Here's a nicely formatted jsbin version of my message: http://jsbin.com/bihilaveda Sorry about the mess, mail user agents (at least Postbox) and archive software do not like explicit indentation. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
I like #4. Normally in a situation like this I would still argue for #1. #4 is a complicated special case that breaks the normal pattern of operator precedence elsewhere in the language. The need for ** is not great enough to justify introducing a new special case for users to learn. However, in this case, #4 is only technically complicated -- for those writing or reading spec docs like us. For normal users, the only complexity is a rarely encountered surprising static error. With a decent (and easy to generate) error message, these users will immediately know what they need to do to repair their program. Significant programs are read much more than they are written. Both #2 and #3 will lead many readers to misread programs. For programs that are not rejected, #4 is no more confusing than #1. Altogether, for readers, #4 is better than #1 because ** is more readable than Pow. +1 on #4. On Thu, Sep 24, 2015 at 7:55 AM, Brendan Eichwrote: > Here's a nicely formatted jsbin version of my message: > > http://jsbin.com/bihilaveda > > Sorry about the mess, mail user agents (at least Postbox) and archive > software do not like explicit indentation. > > /be > > > > -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On 24 September 2015 at 17:19, Brendan Eichwrote: > Even nicer: > > http://jsbin.com/baquqokujo > > I hate email. You are holding it wrong. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
I won't try to guess where the rendering problem is, but see the attached screenshots. This is how I'm seeing your page on my Chrome and Firefox. On Thu, Sep 24, 2015 at 8:19 AM, Brendan Eichwrote: > Even nicer: > > http://jsbin.com/baquqokujo > > I hate email. > > /be > > > Brendan Eich wrote: > >> Here's a nicely formatted jsbin version of my message: >> >> http://jsbin.com/bihilaveda >> >> Sorry about the mess, mail user agents (at least Postbox) and archive >> software do not like explicit indentation. >> >> /be >> > > -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Thu, Sep 24, 2015 at 11:08 AM, Claude Pachewrote: > > Le 24 sept. 2015 à 16:11, Brendan Eich a écrit : > > And indeed apart from dot (a special form whose right operand must be a > lexical identifier-name) and square brackets (which isn't an infix operator > per se), unary operators bind tighter than binary in JS as in C and other > C-derived languages. > > > I just wonder why it is important that unary binds tighter? For instance, > before I carefully studied the issue of this thread, I have never expected > that unary minus binds tighter than binary > Before Jason pointed out the discrepancy: * all of us on the committee who were engaged with the proposal * including myself, * all those who reviewed the proposal, * and all those who implemented the proposal had the opposite naive expectation. That's the point. In the absence of learning about this case specifically, many people will be unpleasantly surprised by #2, and many by #3. Therefore #4 wins. (Actually, it just won ;).) > multiplication operator in expressions like `-2*x` (although it does not > matter in that case). > > > without having to parenthesize unduly, but one cannot write > > let z = -x ** y; > > The user is forced by an early error to write either (-x)**y or -(x**y). > > > In traditional math notation, when you mean `(-x)**n`, you write (-x)ⁿ > with mandatory parentheses, so I don’t expect that many people will be > tempted to miswrite it `-x ** n`. > > Making the parentheses mandatory here will be somewhat annoying in > perfectly reasonable expressions, where you usually don’t use parentheses > in real math notation., like: > ``` > let s2 = - x**2 - y**2 - z**2 + t**2 > ``` > > —Claude > > > -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
I object to #4. Disallowing perfectly reasonable math expressions (Claude's is a good example) makes this operator too surprising to include in the language. From: Brendan Eich <brendan.e...@gmail.com> Sent: Sep 24, 2015 13:18 To: Mark S. Miller; Claude Pache Cc: es-discuss Subject: Re: Exponentiation operator precedence Right. It's confusing because (as opposed to Math), ** is not a superscripting operator whose typography suggests higher precedence than -, and this matters for the sign of the result when exponentiating. Claude, the Math folks won't often need to negate the result, but when they do, they'll have to parenthesize. That's the price of the typographic shift and the precedence inversion that it suggests to many people. /be On Thu, Sep 24, 2015 at 11:16 AM, Mark S. Miller <erig...@google.com<mailto:erig...@google.com>> wrote: On Thu, Sep 24, 2015 at 11:08 AM, Claude Pache <claude.pa...@gmail.com<mailto:claude.pa...@gmail.com>> wrote: Le 24 sept. 2015 à 16:11, Brendan Eich <bren...@mozilla.org<mailto:bren...@mozilla.org>> a écrit : And indeed apart from dot (a special form whose right operand must be a lexical identifier-name) and square brackets (which isn't an infix operator per se), unary operators bind tighter than binary in JS as in C and other C-derived languages. I just wonder why it is important that unary binds tighter? For instance, before I carefully studied the issue of this thread, I have never expected that unary minus binds tighter than binary Before Jason pointed out the discrepancy: * all of us on the committee who were engaged with the proposal * including myself, * all those who reviewed the proposal, * and all those who implemented the proposal had the opposite naive expectation. That's the point. In the absence of learning about this case specifically, many people will be unpleasantly surprised by #2, and many by #3. Therefore #4 wins. (Actually, it just won ;).) multiplication operator in expressions like `-2*x` (although it does not matter in that case). without having to parenthesize unduly, but one cannot write let z = -x ** y; The user is forced by an early error to write either (-x)**y or -(x**y). In traditional math notation, when you mean `(-x)**n`, you write (-x)ⁿ with mandatory parentheses, so I don’t expect that many people will be tempted to miswrite it `-x ** n`. Making the parentheses mandatory here will be somewhat annoying in perfectly reasonable expressions, where you usually don’t use parentheses in real math notation., like: ``` let s2 = - x**2 - y**2 - z**2 + t**2 ``` —Claude -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Right. It's confusing because (as opposed to Math), ** is not a superscripting operator whose typography suggests higher precedence than -, and this matters for the sign of the result when exponentiating. Claude, the Math folks won't often need to negate the result, but when they do, they'll have to parenthesize. That's the price of the typographic shift and the precedence inversion that it suggests to many people. /be On Thu, Sep 24, 2015 at 11:16 AM, Mark S. Millerwrote: > > > On Thu, Sep 24, 2015 at 11:08 AM, Claude Pache > wrote: > >> >> Le 24 sept. 2015 à 16:11, Brendan Eich a écrit : >> >> And indeed apart from dot (a special form whose right operand must be a >> lexical identifier-name) and square brackets (which isn't an infix operator >> per se), unary operators bind tighter than binary in JS as in C and other >> C-derived languages. >> >> >> I just wonder why it is important that unary binds tighter? For instance, >> before I carefully studied the issue of this thread, I have never expected >> that unary minus binds tighter than binary >> > > > Before Jason pointed out the discrepancy: > * all of us on the committee who were engaged with the proposal > * including myself, > * all those who reviewed the proposal, > * and all those who implemented the proposal > had the opposite naive expectation. That's the point. In the absence of > learning about this case specifically, many people will be unpleasantly > surprised by #2, and many by #3. Therefore #4 wins. (Actually, it just won > ;).) > > > > > >> multiplication operator in expressions like `-2*x` (although it does not >> matter in that case). >> >> >> without having to parenthesize unduly, but one cannot write >> >> let z = -x ** y; >> >> The user is forced by an early error to write either (-x)**y or -(x**y). >> >> >> In traditional math notation, when you mean `(-x)**n`, you write (-x)ⁿ >> with mandatory parentheses, so I don’t expect that many people will be >> tempted to miswrite it `-x ** n`. >> >> Making the parentheses mandatory here will be somewhat annoying in >> perfectly reasonable expressions, where you usually don’t use parentheses >> in real math notation., like: >> ``` >> let s2 = - x**2 - y**2 - z**2 + t**2 >> ``` >> >> —Claude >> >> >> > > > -- > Cheers, > --MarkM > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Sez you! :-P Seriously, the problem you are dismissing implicitly (bad form :-/) is the one we discussed yesterday, which I've stated explicitly twice now: the typography and plain sense of JS-in-itself suggests unary minus binds tighter than any binary connective (including **). Saying "Math!" doesn't overcome this, any more than shouting "typography!" or "JS-in-itself!" You don't get to pick a winner just because you root for one team. If you think the operator is worth adding and you concede that the other team's position is tenable because enough people are confused on the committee to predict a wider problem, then you have to consider whether the hardship of mandatory parens in the rare case of negated exponentiation expression is onerous. It's not a source of runtime bugs, where test coverage is never good enough. It's a SyntaxError, so (a) Math uber alles people who (b) run into the rare hard case will learn to parenthesize. I suspect that many Math-should-prevail types (I am among them in the abstract, prior to engaging with the human factors at play in JS) will want to parenthesize anyway, given the typographic appearance of precedence inversion. I will certainly do it if there's any unary prefixing an exponentiation expression in my code. I did find a formula search engine. See http://www.searchonmath.com/result?equation=-+x%5E%7By%7D=1=1 for a taste of the hard cases (and false positives, which do not count). Methinks you protest too much. Where is the common case made hard by proposal (4)? /be On Thu, Sep 24, 2015 at 12:29 PM, Domenic Denicola <d...@domenic.me> wrote: > I object to #4. Disallowing perfectly reasonable math expressions > (Claude's is a good example) makes this operator too surprising to include > in the language. > > > > *From:* Brendan Eich <brendan.e...@gmail.com> > *Sent:* Sep 24, 2015 13:18 > *To:* Mark S. Miller; Claude Pache > *Cc:* es-discuss > *Subject:* Re: Exponentiation operator precedence > > Right. It's confusing because (as opposed to Math), ** is not a > superscripting operator whose typography suggests higher precedence than -, > and this matters for the sign of the result when exponentiating. > > Claude, the Math folks won't often need to negate the result, but when > they do, they'll have to parenthesize. That's the price of the typographic > shift and the precedence inversion that it suggests to many people. > > /be > > On Thu, Sep 24, 2015 at 11:16 AM, Mark S. Miller <erig...@google.com> > wrote: > >> >> >> On Thu, Sep 24, 2015 at 11:08 AM, Claude Pache <claude.pa...@gmail.com> >> wrote: >> >>> >>> Le 24 sept. 2015 à 16:11, Brendan Eich <bren...@mozilla.org> a écrit : >>> >>> And indeed apart from dot (a special form whose right operand must be a >>> lexical identifier-name) and square brackets (which isn't an infix operator >>> per se), unary operators bind tighter than binary in JS as in C and other >>> C-derived languages. >>> >>> >>> I just wonder why it is important that unary binds tighter? For >>> instance, before I carefully studied the issue of this thread, I have never >>> expected that unary minus binds tighter than binary >>> >> >> >> Before Jason pointed out the discrepancy: >> * all of us on the committee who were engaged with the proposal >> * including myself, >> * all those who reviewed the proposal, >> * and all those who implemented the proposal >> had the opposite naive expectation. That's the point. In the absence of >> learning about this case specifically, many people will be unpleasantly >> surprised by #2, and many by #3. Therefore #4 wins. (Actually, it just won >> ;).) >> >> >> >> >> >>> multiplication operator in expressions like `-2*x` (although it does not >>> matter in that case). >>> >>> >>> without having to parenthesize unduly, but one cannot write >>> >>> let z = -x ** y; >>> >>> The user is forced by an early error to write either (-x)**y or -(x**y). >>> >>> >>> In traditional math notation, when you mean `(-x)**n`, you write (-x)ⁿ >>> with mandatory parentheses, so I don’t expect that many people will be >>> tempted to miswrite it `-x ** n`. >>> >>> Making the parentheses mandatory here will be somewhat annoying in >>> perfectly reasonable expressions, where you usually don’t use parentheses >>> in real math notation., like: >>> ``` >>> let s2 = - x**2 - y**2 - z**2 + t**2 >>> ``` >>> >>> —Claude >>> >>> >>> >> >> >> -- >> Cheers, >> --MarkM >> > > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
> Le 24 sept. 2015 à 22:20, Brendan Eich <brendan.e...@gmail.com> a écrit : > > Sez you! :-P > > Seriously, the problem you are dismissing implicitly (bad form :-/) is the > one we discussed yesterday, which I've stated explicitly twice now: the > typography and plain sense of JS-in-itself suggests unary minus binds tighter > than any binary connective (including **). It’s more a question of convention than of typography, as in: `x + y * z` or: `x || y && z`. There are two conflicting conventions here, not two conflicting typographies. For the set of operators defined in C, the convention of making every unary operator having a higher precedence, does not conflict with the conventions used in math. (It is not clear for me why that convention is important, just that it is a handy uniform rule that works well for some limited set of operators.) Note that if you want to disallow `-x**y`, you might want to disallow `x**y**z` (which is imho more confusing), as there is no other right-associative binary operator (except assignment). —Claude > > Saying "Math!" doesn't overcome this, any more than shouting "typography!" or > "JS-in-itself!" > > You don't get to pick a winner just because you root for one team. If you > think the operator is worth adding and you concede that the other team's > position is tenable because enough people are confused on the committee to > predict a wider problem, then you have to consider whether the hardship of > mandatory parens in the rare case of negated exponentiation expression is > onerous. > > It's not a source of runtime bugs, where test coverage is never good enough. > It's a SyntaxError, so (a) Math uber alles people who (b) run into the rare > hard case will learn to parenthesize. > > I suspect that many Math-should-prevail types (I am among them in the > abstract, prior to engaging with the human factors at play in JS) will want > to parenthesize anyway, given the typographic appearance of precedence > inversion. I will certainly do it if there's any unary prefixing an > exponentiation expression in my code. > > I did find a formula search engine. See > http://www.searchonmath.com/result?equation=-+x%5E%7By%7D=1=1 > <http://www.searchonmath.com/result?equation=-+x%5E%7By%7D=1=1> for a > taste of the hard cases (and false positives, which do not count). > > Methinks you protest too much. Where is the common case made hard by proposal > (4)? > > /be > > > On Thu, Sep 24, 2015 at 12:29 PM, Domenic Denicola <d...@domenic.me > <mailto:d...@domenic.me>> wrote: > I object to #4. Disallowing perfectly reasonable math expressions (Claude's > is a good example) makes this operator too surprising to include in the > language. > > > > From: Brendan Eich <brendan.e...@gmail.com <mailto:brendan.e...@gmail.com>> > Sent: Sep 24, 2015 13:18 > To: Mark S. Miller; Claude Pache > Cc: es-discuss > Subject: Re: Exponentiation operator precedence > > Right. It's confusing because (as opposed to Math), ** is not a > superscripting operator whose typography suggests higher precedence than -, > and this matters for the sign of the result when exponentiating. > > Claude, the Math folks won't often need to negate the result, but when they > do, they'll have to parenthesize. That's the price of the typographic shift > and the precedence inversion that it suggests to many people. > > /be > > On Thu, Sep 24, 2015 at 11:16 AM, Mark S. Miller <erig...@google.com > <mailto:erig...@google.com>> wrote: > > > On Thu, Sep 24, 2015 at 11:08 AM, Claude Pache <claude.pa...@gmail.com > <mailto:claude.pa...@gmail.com>> wrote: > >> Le 24 sept. 2015 à 16:11, Brendan Eich <bren...@mozilla.org >> <mailto:bren...@mozilla.org>> a écrit : >> >> And indeed apart from dot (a special form whose right operand must be a >> lexical identifier-name) and square brackets (which isn't an infix operator >> per se), unary operators bind tighter than binary in JS as in C and other >> C-derived languages. > > I just wonder why it is important that unary binds tighter? For instance, > before I carefully studied the issue of this thread, I have never expected > that unary minus binds tighter than binary > > > Before Jason pointed out the discrepancy: > * all of us on the committee who were engaged with the proposal > * including myself, > * all those who reviewed the proposal, > * and all those who implemented the proposal > had the opposite naive expectation. That's the point. In the absence of > learning about this case specifically,
Re: Exponentiation operator precedence
The worry over the meaning of (- x ** y) arises not just due to conventions or inference from typography, but from intuitions based on limited knowledge. As Dave Herman pointed out yesterday, many programmers (most) do not have the full precedence and associativity set memorized. When in doubt, they will rely on precedent in the language, visual cues including weight of operator (two chars vs. one), unary vs. binary. When in more doubt, they'll over-parenthesize. The problem case is exactly the user cohort who'll not have enough doubt to over-parenthesize, who will rely on precedent and typographic weight clues, sound or not. Mark Miller pointed out how many reviewers missed the problem with the original proposal as predicting likely confusion at scale. If we can avoid any confusion with an error, and force the people who should over-parenthesize to do so, while taxing the Math fans to do it when they must as well, this seems more prudent than just sticking with the Math-trumps-JS precedent and letting wrong results pass silently at runtime. (I see no reason to disallow right-associative chaining. We haven't run head-on into confusion by drafting it the wrong way and getting it to stage 3 :-P.) /be On Thu, Sep 24, 2015 at 2:05 PM, Claude Pache <claude.pa...@gmail.com> wrote: > > Le 24 sept. 2015 à 22:20, Brendan Eich <brendan.e...@gmail.com> a écrit : > > Sez you! :-P > > Seriously, the problem you are dismissing implicitly (bad form :-/) is the > one we discussed yesterday, which I've stated explicitly twice now: the > typography and plain sense of JS-in-itself suggests unary minus binds > tighter than any binary connective (including **). > > > It’s more a question of convention than of typography, as in: `x + y * z` > or: `x || y && z`. > > There are two conflicting conventions here, not two conflicting > typographies. For the set of operators defined in C, the convention of > making every unary operator having a higher precedence, does not conflict > with the conventions used in math. (It is not clear for me why that > convention is important, just that it is a handy uniform rule that works > well for some limited set of operators.) > > Note that if you want to disallow `-x**y`, you might want to disallow > `x**y**z` (which is imho more confusing), as there is no other > right-associative binary operator (except assignment). > > —Claude > > > Saying "Math!" doesn't overcome this, any more than shouting "typography!" > or "JS-in-itself!" > > You don't get to pick a winner just because you root for one team. If you > think the operator is worth adding and you concede that the other team's > position is tenable because enough people are confused on the committee to > predict a wider problem, then you have to consider whether the hardship of > mandatory parens in the rare case of negated exponentiation expression is > onerous. > > It's not a source of runtime bugs, where test coverage is never good > enough. It's a SyntaxError, so (a) Math uber alles people who (b) run into > the rare hard case will learn to parenthesize. > > I suspect that many Math-should-prevail types (I am among them in the > abstract, prior to engaging with the human factors at play in JS) will want > to parenthesize anyway, given the typographic appearance of precedence > inversion. I will certainly do it if there's any unary prefixing an > exponentiation expression in my code. > > I did find a formula search engine. See > http://www.searchonmath.com/result?equation=-+x%5E%7By%7D=1=1 for > a taste of the hard cases (and false positives, which do not count). > > Methinks you protest too much. Where is the common case made hard by > proposal (4)? > > /be > > > On Thu, Sep 24, 2015 at 12:29 PM, Domenic Denicola <d...@domenic.me> wrote: > >> I object to #4. Disallowing perfectly reasonable math expressions >> (Claude's is a good example) makes this operator too surprising to include >> in the language. >> >> >> >> *From:* Brendan Eich <brendan.e...@gmail.com> >> *Sent:* Sep 24, 2015 13:18 >> *To:* Mark S. Miller; Claude Pache >> *Cc:* es-discuss >> *Subject:* Re: Exponentiation operator precedence >> >> Right. It's confusing because (as opposed to Math), ** is not a >> superscripting operator whose typography suggests higher precedence than -, >> and this matters for the sign of the result when exponentiating. >> >> Claude, the Math folks won't often need to negate the result, but when >> they do, they'll have to parenthesize. That's the price of the typographic >> shift and the precedence inversion that it suggests to many people. >> >> /be >> >> On Th
Re: Exponentiation operator precedence
My preference is for 2, but I don't have objections to 4. Either works. Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Thanks again to Brendan for taking time to write this up. And to Mark, thanks for reviewing this and expeditiously providing valuable feedback—it's greatly appreciated. Rick On Thu, Sep 24, 2015 at 8:27 AM Mark S. Millerwrote: > I won't try to guess where the rendering problem is, but see the attached > screenshots. This is how I'm seeing your page on my Chrome and Firefox. > > On Thu, Sep 24, 2015 at 8:19 AM, Brendan Eich wrote: > >> Even nicer: >> >> http://jsbin.com/baquqokujo >> >> I hate email. >> >> /be >> >> >> Brendan Eich wrote: >> >>> Here's a nicely formatted jsbin version of my message: >>> >>> http://jsbin.com/bihilaveda >>> >>> Sorry about the mess, mail user agents (at least Postbox) and archive >>> software do not like explicit indentation. >>> >>> /be >>> >> >> > > > -- > Cheers, > --MarkM > ___ > es-discuss mailing list > es-discuss@mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
> Le 24 sept. 2015 à 16:11, Brendan Eicha écrit : > > And indeed apart from dot (a special form whose right operand must be a > lexical identifier-name) and square brackets (which isn't an infix operator > per se), unary operators bind tighter than binary in JS as in C and other > C-derived languages. I just wonder why it is important that unary binds tighter? For instance, before I carefully studied the issue of this thread, I have never expected that unary minus binds tighter than binary multiplication operator in expressions like `-2*x` (although it does not matter in that case). > > without having to parenthesize unduly, but one cannot write > > let z = -x ** y; > > The user is forced by an early error to write either (-x)**y or -(x**y). In traditional math notation, when you mean `(-x)**n`, you write (-x)ⁿ with mandatory parentheses, so I don’t expect that many people will be tempted to miswrite it `-x ** n`. Making the parentheses mandatory here will be somewhat annoying in perfectly reasonable expressions, where you usually don’t use parentheses in real math notation., like: ``` let s2 = - x**2 - y**2 - z**2 + t**2 ``` —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
I agree with that completely. This would also become a gotcha. I can see a lot of people down the road thinking -x ** 2 === -x**2, only to find that's not the case. It looks like it should, which will quickly lead to hard to find bugs. I think it's a terrible idea, but that's just my opinion. On Fri, Aug 28, 2015, 00:56 Brendan Eich bren...@mozilla.org wrote: Not to worry, the significant whitespace prospect was (I trust) a warding-off spell. Good of Waldemar to mention Fortress, too. JS, which as source is and will always be minified, indeed requires full-parsing minifiers, so one might naively still entertain the stated prospect. But it's a bad idea, since people minify (or just tidy by removing spaces) by hand. Keep warding off significant space! /be Joe Gibbs Politz wrote: On Thu, Aug 27, 2015 at 2:58 PM, Alexander Jonesa...@weej.com wrote: Ethan is making my point far better than I did, and I agree completely about the issue of unary operators visually appearing more tightly bound than binary operators. At this point it seems fair to at least acknowledge the prospect of significant whitespace. ``` -x**2 === -(x ** 2) -x ** 2 === (-x) ** 2 ``` One kind of cost that I haven't seen mentioned (and is relevant re:whitespace) is the impact on minifiers and other tools that use JS as output, which have to deal with operator precedence/whitespace rules in quite complicated ways. There's a nice recent piece about precedence bugs in a minifier: https://zyan.scripts.mit.edu/blog/backdooring-js/ Making the creation and maintenance of systems like minifiers harder is a real cost worth bearing in mind when updating already-subtle existing rules. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
because the right-side-up way to say that is: e - a * c Yeah, I was waiting for someone to point that out, after I hit send. : ) I should spend more time setting up a better examples... ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
x ** y ** z is easier to read/write than x.pow(y.pow(z)) That might be cherry picking. Trying to make up something a little more complex: a**b * -c**d + e Math.pow(a, b) * -Math.pow(c, d) + e a.pow(b) * -c.pow(d) + e I don't have strong feelings on this issue, but the third option looks pretty good to me. If we had some form of pipelining syntax (yet to be proposed), then we could have: let { pow } = Math; a-pow(b) * -c-pow(d) + e; Kevin ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
You don't need to be a language guru to know which operation will be performed first, you can (and should) check an operator precedence and associativity table such as MDN's https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence . Knowing operator precedence and associativity is very important when reading code written by others, and many projects use the no unnecessary parens linting rule. /fm On Thu, Aug 27, 2015 at 8:35 AM, Bill Frantz fra...@pwpconsult.com wrote: On 8/27/15 at 11:51 PM, niloy.monda...@gmail.com (Niloy Mondal) wrote: x ** y ** z is easier to read/write than x.pow(y.pow(z)) As a language guru, you know which operation will be performed first. As Joe programmer, I don't and I would need to write it as x ** (y ** z). With some operations, like +, the order doesn't matter and x + y + z is not confusing. Cheers - Bill --- Bill Frantz|We used to quip that password is the most common 408-356-8506 | password. Now it's 'password1.' Who said users haven't www.pwpconsult.com | learned anything about security? -- Bruce Schneier ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Thu, Aug 27, 2015 at 9:04 AM, Kevin Smith zenpars...@gmail.com wrote: a**b * -c**d + e I don't think people use unary - like this very often. It's nothing to do with exponentiation. You don't see people write: a * -c + e because the right-side-up way to say that is: e - a * c -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On 08/27/2015 09:25 AM, Dean Tribble wrote: Ideally syntax proposals should include some frequency information to motivate any change. Is there an easy search to estimate the frequency of Math.pow? In my application codebase (financial app with only modest JS use), there are very few uses, and there are as many uses of Math.sin as there are of Math.pow. Frequency relative to what, though? If code that does nontrivial math is a very small proportion of total JS code, and yet the exponentiation operator makes that code much more readable, then what is the conclusion? I would argue that ** precedence confusion is irrelevant to code that isn't going to use Math.pow in the first place. So it's a question of whether ** is a big enough readability win in code that computes exponents. Anecdotally, my eyes caught on: -Math.pow(2,-10*a/1) (from a charting library) which makes me not want to have to review code where I'm worried about the precedence of exponentiation. I'd have to write that out: -2**(-10*a/1). That doesn't seem too bad. For myself, I do very much prefer Math.sqrt(a**2 + b**2) to Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)). The verbosity and uneven density of notation is really bothersome -- for any equation like the second one, I guarantee that I'll rewrite it on paper to figure out what it's saying. (Ok, maybe not for that specific formula, but even there I'll mentally render it.) I would not need to do so with the first one. Jumping between prefix and infix is jarring. Then again, I could make the same argument for Math.sqrt(a**2 + b**2) vs (a**2 + b**2) ** 0.5. And I don't like the second one much. But people don't interchange those when handwriting formulas, either. Math.sqrt(a.pow(2) + b.pow(2)) is an interesting middle point. I initially thought it struck the right balance, but seeing it written out, it still looks far inferior to me. A more complex example might help: a * (b - a)**(x - 1/2 * (b - a)**2) vs a * Math.pow(b - a, x - 1/2 * Math.pow(b - a, 2)) vs a * (b - a).pow(x - 1/2 * (b - a).pow(2)) For me, the middle one is a mess. I can't make sense of it, and I can't spot the common (b - a) expression at all. The first one is as readable as such formulas ever are when written out with ASCII text. The third one is somewhere in between. I can see the common (b - a), and perhaps if I got more used to seeing .pow I could mentally make use of it without writing it on paper, but for now I cannot. Part of the problem is that I can easily translate x**2 into x squared, but x.pow(2) is raising x to the power of 2. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Anecdotal evidence via a quick github search https://github.com/search?l=JavaScriptp=1q=Math.pow+language%3AJavaScript+extension%3Ajsref=advsearchtype=Codeutf8=%E2%9C%93 A significant number of the usages are unit tests. Many others are repeats from popular libraries like D3. The most extreme use case I could find: y4ashida/ika/blob/master/js/culc_dence.js https://github.com/y4ashida/ika/blob/master/js/culc_dence.js On Thu, Aug 27, 2015 at 11:19 AM, Steve Fink sph...@gmail.com wrote: On 08/27/2015 09:25 AM, Dean Tribble wrote: Ideally syntax proposals should include some frequency information to motivate any change. Is there an easy search to estimate the frequency of Math.pow? In my application codebase (financial app with only modest JS use), there are very few uses, and there are as many uses of Math.sin as there are of Math.pow. Frequency relative to what, though? If code that does nontrivial math is a very small proportion of total JS code, and yet the exponentiation operator makes that code much more readable, then what is the conclusion? I would argue that ** precedence confusion is irrelevant to code that isn't going to use Math.pow in the first place. So it's a question of whether ** is a big enough readability win in code that computes exponents. Anecdotally, my eyes caught on: -Math.pow(2,-10*a/1) (from a charting library) which makes me not want to have to review code where I'm worried about the precedence of exponentiation. I'd have to write that out: -2**(-10*a/1). That doesn't seem too bad. For myself, I do very much prefer Math.sqrt(a**2 + b**2) to Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)). The verbosity and uneven density of notation is really bothersome -- for any equation like the second one, I guarantee that I'll rewrite it on paper to figure out what it's saying. (Ok, maybe not for that specific formula, but even there I'll mentally render it.) I would not need to do so with the first one. Jumping between prefix and infix is jarring. Then again, I could make the same argument for Math.sqrt(a**2 + b**2) vs (a**2 + b**2) ** 0.5. And I don't like the second one much. But people don't interchange those when handwriting formulas, either. Math.sqrt(a.pow(2) + b.pow(2)) is an interesting middle point. I initially thought it struck the right balance, but seeing it written out, it still looks far inferior to me. A more complex example might help: a * (b - a)**(x - 1/2 * (b - a)**2) vs a * Math.pow(b - a, x - 1/2 * Math.pow(b - a, 2)) vs a * (b - a).pow(x - 1/2 * (b - a).pow(2)) For me, the middle one is a mess. I can't make sense of it, and I can't spot the common (b - a) expression at all. The first one is as readable as such formulas ever are when written out with ASCII text. The third one is somewhere in between. I can see the common (b - a), and perhaps if I got more used to seeing .pow I could mentally make use of it without writing it on paper, but for now I cannot. Part of the problem is that I can easily translate x**2 into x squared, but x.pow(2) is raising x to the power of 2. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Exponentiation operator precedence
Long-time esdiscuss lurker; hopefully this perspective is helpful. I think the problem here is that traditional mathematic notation uses visual cues to imply precedence that JS can't take advantage of. When -3 ** 2 is written out on paper, the 2 is very clearly grouped visually with the 3. In fact, the superscript almost makes the 2 feel like an appendage of the 3. That makes it more natural to read it as two items: the negative sign, and (3 ** 2). By contrast, when (-3 ** 2) is written out in code, the negative sign is way closer visually to the 3 than the 2 is, so I find myself instinctively pulling out a -3 first and reading the expression as (-3)**2. Treating -3 ** 2 as -(3 ** 2) seems technologically possible and mathematically sensible, but also like it's going against the grain of the human visual system. I think that's at least one reason to value the binary precedence should be lower than unary principle. The `Number.prototype.pow` approach might be an improvement, as it has the effect of mandating parentheses on some cases that might otherwise be confusing (e.g. x ** y ** z) and it offers most of the conciseness of **. But -x.pow(2) still feels unpredictable to me as an everyday programmer switching between languages. (Also, pow() requires an extra set of parentheses if I want to operate on a literal.) Maybe it's ok if the operator surprises some people in some cases, and the guidance will just become to use parentheses if you're unsure. That occasional uncertainty for the vast majority of JS programmers that aren't doing much exponentiation might be worth it if ** makes a minority of JS programmers much more productive. I don't know. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Ideally syntax proposals should include some frequency information to motivate any change. Is there an easy search to estimate the frequency of Math.pow? In my application codebase (financial app with only modest JS use), there are very few uses, and there are as many uses of Math.sin as there are of Math.pow. Anecdotally, my eyes caught on: -Math.pow(2,-10*a/1) (from a charting library) which makes me not want to have to review code where I'm worried about the precedence of exponentiation. On Thu, Aug 27, 2015 at 7:32 AM, Kevin Smith zenpars...@gmail.com wrote: because the right-side-up way to say that is: e - a * c Yeah, I was waiting for someone to point that out, after I hit send. : ) I should spend more time setting up a better examples... ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Thu, Aug 27, 2015 at 2:58 PM, Alexander Jones a...@weej.com wrote: Ethan is making my point far better than I did, and I agree completely about the issue of unary operators visually appearing more tightly bound than binary operators. At this point it seems fair to at least acknowledge the prospect of significant whitespace. ``` -x**2 === -(x ** 2) -x ** 2 === (-x) ** 2 ``` One kind of cost that I haven't seen mentioned (and is relevant re:whitespace) is the impact on minifiers and other tools that use JS as output, which have to deal with operator precedence/whitespace rules in quite complicated ways. There's a nice recent piece about precedence bugs in a minifier: https://zyan.scripts.mit.edu/blog/backdooring-js/ Making the creation and maintenance of systems like minifiers harder is a real cost worth bearing in mind when updating already-subtle existing rules. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Ethan is making my point far better than I did, and I agree completely about the issue of unary operators visually appearing more tightly bound than binary operators. At this point it seems fair to at least acknowledge the prospect of significant whitespace. ``` -x**2 === -(x ** 2) -x ** 2 === (-x) ** 2 ``` On Thursday, August 27, 2015, Steve Fink sph...@gmail.com wrote: On 08/27/2015 11:20 AM, Ethan Resnick wrote: Long-time esdiscuss lurker; hopefully this perspective is helpful. I think the problem here is that traditional mathematic notation uses visual cues to imply precedence that JS can't take advantage of. When -3 ** 2 is written out on paper, the 2 is very clearly grouped visually with the 3. In fact, the superscript almost makes the 2 feel like an appendage of the 3. That makes it more natural to read it as two items: the negative sign, and (3 ** 2). By contrast, when (-3 ** 2) is written out in code, the negative sign is way closer visually to the 3 than the 2 is, so I find myself instinctively pulling out a -3 first and reading the expression as (-3)**2. If we're making ** bind tighter than unary -, then I would hope it would be written -3**2, not -3 ** 2. The latter is indeed deceptive. For me, x**y**z is rare enough that I don't really care if ** is right associative or nonassociative. Parentheses are part of the cost you have to pay for rendering things as plain text -- and yet, I see no reason not to make x**y**z just do the right thing. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Don't rely on github searches to turn up representative examples. It doesn't work that well. Here's my educated guess as to how ** will be used. The most common use will be to square numbers. a² a**2 Math.pow(a, 2) a.pow(2) Currently you might write `a * a`, which is kind of lame. So where's the benefit? If this trivial thing is the most common use of exponentation, why bother? The ability to look at an expression and understand it at a glance is a big deal. x² + y² limit x**2 + y**2 limit Math.pow(x, 2) + Math.pow(y, 2) limit x.pow(2) + y.pow(2) limit A big big deal. It's the reason we have arithmetic operators in JS in the first place. Exponentiation is common when computing easing functions, curves for graphics, interest, simulations, random stuff in games. Nth roots are fairly common too (`apr**(1/12)`). In all of these cases, the user is doing the same thing: translating a mathematical formula they wish to use from math to JS. It is not extra hard to translate such a formula using Math.pow(), but it is harder to read once you're done. You have to mentally translate back to math. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On 08/27/2015 11:20 AM, Ethan Resnick wrote: Long-time esdiscuss lurker; hopefully this perspective is helpful. I think the problem here is that traditional mathematic notation uses visual cues to imply precedence that JS can't take advantage of. When -3 ** 2 is written out on paper, the 2 is very clearly grouped visually with the 3. In fact, the superscript almost makes the 2 feel like an appendage of the 3. That makes it more natural to read it as two items: the negative sign, and (3 ** 2). By contrast, when (-3 ** 2) is written out in code, the negative sign is way closer visually to the 3 than the 2 is, so I find myself instinctively pulling out a -3 first and reading the expression as (-3)**2. If we're making ** bind tighter than unary -, then I would hope it would be written -3**2, not -3 ** 2. The latter is indeed deceptive. For me, x**y**z is rare enough that I don't really care if ** is right associative or nonassociative. Parentheses are part of the cost you have to pay for rendering things as plain text -- and yet, I see no reason not to make x**y**z just do the right thing. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On 08/27/2015 11:58, Alexander Jones wrote: Ethan is making my point far better than I did, and I agree completely about the issue of unary operators visually appearing more tightly bound than binary operators. At this point it seems fair to at least acknowledge the prospect of significant whitespace. ``` -x**2 === -(x ** 2) -x ** 2 === (-x) ** 2 ``` Take a look at the Fortress language ☺. But that one benefits from operators and syntax not limited to ASCII. Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Not to worry, the significant whitespace prospect was (I trust) a warding-off spell. Good of Waldemar to mention Fortress, too. JS, which as source is and will always be minified, indeed requires full-parsing minifiers, so one might naively still entertain the stated prospect. But it's a bad idea, since people minify (or just tidy by removing spaces) by hand. Keep warding off significant space! /be Joe Gibbs Politz wrote: On Thu, Aug 27, 2015 at 2:58 PM, Alexander Jonesa...@weej.com wrote: Ethan is making my point far better than I did, and I agree completely about the issue of unary operators visually appearing more tightly bound than binary operators. At this point it seems fair to at least acknowledge the prospect of significant whitespace. ``` -x**2 === -(x ** 2) -x ** 2 === (-x) ** 2 ``` One kind of cost that I haven't seen mentioned (and is relevant re:whitespace) is the impact on minifiers and other tools that use JS as output, which have to deal with operator precedence/whitespace rules in quite complicated ways. There's a nice recent piece about precedence bugs in a minifier: https://zyan.scripts.mit.edu/blog/backdooring-js/ Making the creation and maintenance of systems like minifiers harder is a real cost worth bearing in mind when updating already-subtle existing rules. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
x ** y ** z is easier to read/write than x.pow(y.pow(z)) On Aug 27, 2015 8:51 AM, Mark S. Miller erig...@google.com wrote: On Wed, Aug 26, 2015 at 6:19 PM, Waldemar Horwat walde...@google.com wrote: On 08/26/2015 15:08, Mark S. Miller wrote: The force of that precedent is indeed what my objection is. The yield counter-example is interesting, but yield is an identifier not an operator symbol, and so does not as clearly fall within or shape operator expectations. If someone explains a compelling need for ** I would find that interesting. But until then... ** is a convenience, and that's the wrong criterion to apply here. If it were, then we wouldn't have useful conveniences like Math.cosh or arrow functions. I'd rather read a*x**3 + b*x**2 + c*x + d than a*Math.pow(x, 3) + b*Math.pow(x, 2) + c*x + d Ok, we have a benefit to evaluate. Brevity. With the example contrast between a*x**3 + b*x**2 + c*x + d and a*Math.pow(x, 3) + b*Math.pow(x, 2) + c*x + d Let's also apply Alexander's suggestion a*x.pow(3) + b*x.pow(2) + c*x + d To help us compare for brevity, and because I'm too lazy to count, I'm sending it in a fixed width font. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On 8/27/15 at 11:51 PM, niloy.monda...@gmail.com (Niloy Mondal) wrote: x ** y ** z is easier to read/write than x.pow(y.pow(z)) As a language guru, you know which operation will be performed first. As Joe programmer, I don't and I would need to write it as x ** (y ** z). With some operations, like +, the order doesn't matter and x + y + z is not confusing. Cheers - Bill --- Bill Frantz|We used to quip that password is the most common 408-356-8506 | password. Now it's 'password1.' Who said users haven't www.pwpconsult.com | learned anything about security? -- Bruce Schneier ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Wed, Aug 26, 2015 at 1:03 PM, Thomas thomasjamesfos...@bigpond.com wrote: There's still the issue of exponentiation being right-associative. Unless ** becomes an operator which behaves differently as to how it would in a high school maths class, we're at an impasse. I'm not sure I follow. Exponentiation is right-associative in math, in the current ** proposal, and in every suggested update to it. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Wed, Aug 26, 2015 at 11:09 AM, Mark S. Miller erig...@google.com wrote: I don't get it. The conflict between * the history of ** in other languages, * the general pattern that unary binds tighter than binary seems unresolvable. By the first bullet, -2 ** 2 would be -4. By the second, it would be 4. Either answer will surprise too many programmers. I just think the danger is not so great. Who's really going to be surprised that `-x**2` is negative? This follows not only other mainstream programming languages but a mathematical notation that has been in common use for hundreds of years and is taught to every high school algebra student. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Aug 26, 2015, at 9:09 AM, Mark S. Miller wrote: I don't get it. The conflict between * the history of ** in other languages, * the general pattern that unary binds tighter than binary seems unresolvable. By the first bullet, -2 ** 2 would be -4. By the second, it would be 4. Either answer will surprise too many programmers. By contrast, no one is confused by either -Math.pow(2, 2) or Math.pow(-2, 2). An of course the history includes many very popular languages that chose to not include an exponentiation operator. This is really a cost-benefits issue. Several of us have identified costs (complexity, cognitive, pedagogical, error hazards, etc.). What are the benefits of having such an operator? Are they sufficient to offset the cost of having it. Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Tue, Aug 25, 2015 at 5:43 PM, Mark S. Miller erig...@google.com wrote: When the costs were minor, it was ok that the benefits were minor. The costs will probably still be minor if we just let Rick look at it and revise the proposal. What has happened here is - upon implementing the feature, we noticed a problem - we thought through it together and found possible solutions - we found other languages already use these solutions This seems like less turbulence than average for a new ES feature, even a minor one. Considering dropping the feature seems premature. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Yehuda Katz cited an acronym taught when he was a wee lad learning algebra: PEMDAS (Parentheses, Exponentiation, Multiplication/Dviistion, Addition/Subtraction). Who else learned this? There's nothing sacrosanct about binary precedence being generally lower than unary. Consider the property access operators in JS. But the precedent to which all cited languages bow is Math and that's what programmers (mostly) study. I think you are making too much out of the local -x ** y case in light of this global argument. /be Mark S. Miller wrote: I don't get it. The conflict between * the history of ** in other languages, * the general pattern that unary binds tighter than binary seems unresolvable. By the first bullet, -2 ** 2 would be -4. By the second, it would be 4. Either answer will surprise too many programmers. By contrast, no one is confused by either -Math.pow(2, 2) or Math.pow(-2, 2). ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
I don't get it. The conflict between * the history of ** in other languages, * the general pattern that unary binds tighter than binary seems unresolvable. By the first bullet, -2 ** 2 would be -4. By the second, it would be 4. Either answer will surprise too many programmers. By contrast, no one is confused by either -Math.pow(2, 2) or Math.pow(-2, 2). On Wed, Aug 26, 2015 at 9:00 AM, Jason Orendorff jason.orendo...@gmail.com wrote: On Tue, Aug 25, 2015 at 5:43 PM, Mark S. Miller erig...@google.com wrote: When the costs were minor, it was ok that the benefits were minor. The costs will probably still be minor if we just let Rick look at it and revise the proposal. What has happened here is - upon implementing the feature, we noticed a problem - we thought through it together and found possible solutions - we found other languages already use these solutions This seems like less turbulence than average for a new ES feature, even a minor one. Considering dropping the feature seems premature. -j -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
There's still the issue of exponentiation being right-associative. Unless ** becomes an operator which behaves differently as to how it would in a high school maths class, we're at an impasse. That said, ^ is usually the operator used for exponentiation outside programming languages when you need to express an equation in text. It could be made explicit that ** is a variant on 'exponentiation', but then maybe things are deviating from being useful. Thomas On 27 Aug 2015, at 3:28 AM, Brendan Eich bren...@mozilla.org wrote: Yehuda Katz cited an acronym taught when he was a wee lad learning algebra: PEMDAS (Parentheses, Exponentiation, Multiplication/Dviistion, Addition/Subtraction). Who else learned this? There's nothing sacrosanct about binary precedence being generally lower than unary. Consider the property access operators in JS. But the precedent to which all cited languages bow is Math and that's what programmers (mostly) study. I think you are making too much out of the local -x ** y case in light of this global argument. /be Mark S. Miller wrote: I don't get it. The conflict between * the history of ** in other languages, * the general pattern that unary binds tighter than binary seems unresolvable. By the first bullet, -2 ** 2 would be -4. By the second, it would be 4. Either answer will surprise too many programmers. By contrast, no one is confused by either -Math.pow(2, 2) or Math.pow(-2, 2). ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Exponentiation is written in conventional mathematics as if it were a postfix unary operator, parameterised by a value written in superscript. IMO this puts it in a whole different class to binary operators where both operands are written equally. I don't see a ** b ** c as a good reflection of mathematical convention. Number.prototype.pow, on the other hand, would be fine. On Wednesday, August 26, 2015, Jason Orendorff jason.orendo...@gmail.com wrote: On Wed, Aug 26, 2015 at 1:03 PM, Thomas thomasjamesfos...@bigpond.com javascript:; wrote: There's still the issue of exponentiation being right-associative. Unless ** becomes an operator which behaves differently as to how it would in a high school maths class, we're at an impasse. I'm not sure I follow. Exponentiation is right-associative in math, in the current ** proposal, and in every suggested update to it. -j ___ es-discuss mailing list es-discuss@mozilla.org javascript:; https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Wed, Aug 26, 2015 at 2:55 PM, Waldemar Horwat walde...@google.com wrote: On 08/26/2015 09:09, Mark S. Miller wrote: I don't get it. The conflict between * the history of ** in other languages, * the general pattern that unary binds tighter than binary seems unresolvable. By the first bullet, -2 ** 2 would be -4. By the second, it would be 4. Either answer will surprise too many programmers. By contrast, no one is confused by either -Math.pow(2, 2) or Math.pow(-2, 2). The grammar concerns have been resolved nicely upthread, so I'm not sure what your objection is. The costs are no more significant than in the original proposal. ** now has the same precedence as unary operators and weaker than the increment operators, which matches what most other languages that support exponentiation do. There is precedence for unary operators not always binding tighter than binary. yield 3+4 is yield(3+4), not (yield 3)+4. The force of that precedent is indeed what my objection is. The yield counter-example is interesting, but yield is an identifier not an operator symbol, and so does not as clearly fall within or shape operator expectations. If someone explains a compelling need for ** I would find that interesting. But until then... -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On 08/26/2015 09:09, Mark S. Miller wrote: I don't get it. The conflict between * the history of ** in other languages, * the general pattern that unary binds tighter than binary seems unresolvable. By the first bullet, -2 ** 2 would be -4. By the second, it would be 4. Either answer will surprise too many programmers. By contrast, no one is confused by either -Math.pow(2, 2) or Math.pow(-2, 2). The grammar concerns have been resolved nicely upthread, so I'm not sure what your objection is. The costs are no more significant than in the original proposal. ** now has the same precedence as unary operators and weaker than the increment operators, which matches what most other languages that support exponentiation do. There is precedence for unary operators not always binding tighter than binary. yield 3+4 is yield(3+4), not (yield 3)+4. Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Alexander Jones schrieb: Exponentiation is written in conventional mathematics as if it were a postfix unary operator, parameterised by a value written in superscript. IMO this puts it in a whole different class to binary operators where both operands are written equally. I don't see a ** b ** c as a good reflection of mathematical convention. I disagree. When in maths we write x sup y sup z /sup/sup, we mean x ^ (y ^ z). Which is exactly what `x ** y ** z` will do. And no, we never write x supy/sup supz/sup, if we wanted to express that we'd write x supy * z/sup (or often enough, with implicit multiplication, i.e. no * operator: x supy z/sup). If we'd want to express that in JS, it would by x ** (y * z). Number.prototype.pow, on the other hand, would be fine. You don't mean to use it like `x.pow(y).pow(z)`, do you? Sure, a function or method invocation is always explicit with parenthesis. But that's no improvement over the current `Math.pow`. Bergi ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Le 26 août 2015 à 00:43, Mark S. Miller erig...@google.com a écrit : When the costs were minor, it was ok that the benefits were minor. Given significant costs, we need to ask: While I don't have a strong opinion about the cost of the proposed modified grammar, I protest that the cost of the previous version wasn't anything near minor (although it was probably an oversight): having `-x**y` producing (literally) the opposite result of what is expected, and even only half of the time, is a high cost in terms of bugs produced and debugging man-hours lost. —Claude Why do we need ** ? What great benefit does it provide? If nothing compelling, then this proposal has lost consensus. On Tue, Aug 25, 2015 at 3:30 PM, Claude Pache claude.pa...@gmail.com mailto:claude.pa...@gmail.com wrote: Le 25 août 2015 à 03:22, Jason Orendorff jason.orendo...@gmail.com mailto:jason.orendo...@gmail.com a écrit : On Mon, Aug 24, 2015 at 7:24 PM, Jason Orendorff jason.orendo...@gmail.com mailto:jason.orendo...@gmail.com P.S. Admittedly it might be a good idea to rename UnaryExpression if we put a binary operator in there. -j RightAssociativeExpression? —Claude ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
I completely agree. My When the costs were minor refers to when we were not yet aware of the conflict. On Wed, Aug 26, 2015 at 12:19 AM, Claude Pache claude.pa...@gmail.com wrote: Le 26 août 2015 à 00:43, Mark S. Miller erig...@google.com a écrit : When the costs were minor, it was ok that the benefits were minor. Given significant costs, we need to ask: While I don't have a strong opinion about the cost of the proposed modified grammar, I protest that the cost of the previous version wasn't anything near minor (although it was probably an oversight): having `-x**y` producing (literally) the opposite result of what is expected, and even only half of the time, is a high cost in terms of bugs produced and debugging man-hours lost. —Claude Why do we need ** ? What great benefit does it provide? If nothing compelling, then this proposal has lost consensus. On Tue, Aug 25, 2015 at 3:30 PM, Claude Pache claude.pa...@gmail.com wrote: Le 25 août 2015 à 03:22, Jason Orendorff jason.orendo...@gmail.com a écrit : On Mon, Aug 24, 2015 at 7:24 PM, Jason Orendorff jason.orendo...@gmail.com P.S. Admittedly it might be a good idea to rename UnaryExpression if we put a binary operator in there. -j RightAssociativeExpression? —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On 08/26/2015 15:08, Mark S. Miller wrote: The force of that precedent is indeed what my objection is. The yield counter-example is interesting, but yield is an identifier not an operator symbol, and so does not as clearly fall within or shape operator expectations. If someone explains a compelling need for ** I would find that interesting. But until then... ** is a convenience, and that's the wrong criterion to apply here. If it were, then we wouldn't have useful conveniences like Math.cosh or arrow functions. I'd rather read a*x**3 + b*x**2 + c*x + d than a*Math.pow(x, 3) + b*Math.pow(x, 2) + c*x + d Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Not much, as far as I can tell. Engines do usually lower this, and redo the whole object when the shape changes, or an intrinsic no longer applies. V8 has a MathPow intrinsic, and I believe SpiderMonkey has similar. On Wed, Aug 26, 2015, 23:45 Jordan Harband ljh...@gmail.com wrote: Is there also perhaps a potential performance/static analysis benefit in having it be syntax, rather than a builtin function? `Math.pow` can be overwritten, and varies per-realm, but `**` can not and does not. On Wed, Aug 26, 2015 at 8:21 PM, Mark S. Miller erig...@google.com wrote: On Wed, Aug 26, 2015 at 6:19 PM, Waldemar Horwat walde...@google.com wrote: On 08/26/2015 15:08, Mark S. Miller wrote: The force of that precedent is indeed what my objection is. The yield counter-example is interesting, but yield is an identifier not an operator symbol, and so does not as clearly fall within or shape operator expectations. If someone explains a compelling need for ** I would find that interesting. But until then... ** is a convenience, and that's the wrong criterion to apply here. If it were, then we wouldn't have useful conveniences like Math.cosh or arrow functions. I'd rather read a*x**3 + b*x**2 + c*x + d than a*Math.pow(x, 3) + b*Math.pow(x, 2) + c*x + d Ok, we have a benefit to evaluate. Brevity. With the example contrast between a*x**3 + b*x**2 + c*x + d and a*Math.pow(x, 3) + b*Math.pow(x, 2) + c*x + d Let's also apply Alexander's suggestion a*x.pow(3) + b*x.pow(2) + c*x + d To help us compare for brevity, and because I'm too lazy to count, I'm sending it in a fixed width font. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Wed, Aug 26, 2015 at 6:19 PM, Waldemar Horwat walde...@google.com wrote: On 08/26/2015 15:08, Mark S. Miller wrote: The force of that precedent is indeed what my objection is. The yield counter-example is interesting, but yield is an identifier not an operator symbol, and so does not as clearly fall within or shape operator expectations. If someone explains a compelling need for ** I would find that interesting. But until then... ** is a convenience, and that's the wrong criterion to apply here. If it were, then we wouldn't have useful conveniences like Math.cosh or arrow functions. I'd rather read a*x**3 + b*x**2 + c*x + d than a*Math.pow(x, 3) + b*Math.pow(x, 2) + c*x + d Ok, we have a benefit to evaluate. Brevity. With the example contrast between a*x**3 + b*x**2 + c*x + d and a*Math.pow(x, 3) + b*Math.pow(x, 2) + c*x + d Let's also apply Alexander's suggestion a*x.pow(3) + b*x.pow(2) + c*x + d To help us compare for brevity, and because I'm too lazy to count, I'm sending it in a fixed width font. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Is there also perhaps a potential performance/static analysis benefit in having it be syntax, rather than a builtin function? `Math.pow` can be overwritten, and varies per-realm, but `**` can not and does not. On Wed, Aug 26, 2015 at 8:21 PM, Mark S. Miller erig...@google.com wrote: On Wed, Aug 26, 2015 at 6:19 PM, Waldemar Horwat walde...@google.com wrote: On 08/26/2015 15:08, Mark S. Miller wrote: The force of that precedent is indeed what my objection is. The yield counter-example is interesting, but yield is an identifier not an operator symbol, and so does not as clearly fall within or shape operator expectations. If someone explains a compelling need for ** I would find that interesting. But until then... ** is a convenience, and that's the wrong criterion to apply here. If it were, then we wouldn't have useful conveniences like Math.cosh or arrow functions. I'd rather read a*x**3 + b*x**2 + c*x + d than a*Math.pow(x, 3) + b*Math.pow(x, 2) + c*x + d Ok, we have a benefit to evaluate. Brevity. With the example contrast between a*x**3 + b*x**2 + c*x + d and a*Math.pow(x, 3) + b*Math.pow(x, 2) + c*x + d Let's also apply Alexander's suggestion a*x.pow(3) + b*x.pow(2) + c*x + d To help us compare for brevity, and because I'm too lazy to count, I'm sending it in a fixed width font. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Le 25 août 2015 à 19:25, Mark S. Miller erig...@google.com a écrit : It also does not work. x ** y ** z, if we allow it at all, must be right associative. It must parse as x ** (y ** z). Unless I missed something, it *is* right-associative. —Claude On Tue, Aug 25, 2015 at 10:08 AM, Mark S. Miller erig...@google.com mailto:erig...@google.com wrote: It does not work as well as simply omitting ** entirely. On Tue, Aug 25, 2015 at 9:42 AM, Isiah Meadows isiahmead...@gmail.com mailto:isiahmead...@gmail.com wrote: I like this. It works very well. On Tue, Aug 25, 2015, 12:38 Claude Pache claude.pa...@gmail.com mailto:claude.pa...@gmail.com wrote: I think the following grammar could work. Replace the current (ES2015) PostfixExpression production with: ``` IncrementExpression: LeftHandSideExpression LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] -- ++ LeftHandSideExpression -- LeftHandSideExpression ``` And define UnaryExpression as: ``` UnaryExpression: IncrementExpression delete UnaryExpression void UnaryExpression typeof UnaryExpression ++ UnaryExpression + UnaryExpression -- UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression IncrementExpression ** UnaryExpression ``` where the following production (which exists only to avoid to confusingly interpret, e.g., `++x++` as `+ +x++`): ``` UnaryExpression: ++ UnaryExpression -- UnaryExpression ``` yields a static SyntaxError (or a static ReferenceError if we want to be 100% compatible ES2015). That way, we have the following expected behaviour: * in/decrement operators bind most tightly; * unary and exponentiation operators are applied from right to left. —Claude ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
It also does not work. x ** y ** z, if we allow it at all, must be right associative. It must parse as x ** (y ** z). On Tue, Aug 25, 2015 at 10:08 AM, Mark S. Miller erig...@google.com wrote: It does not work as well as simply omitting ** entirely. On Tue, Aug 25, 2015 at 9:42 AM, Isiah Meadows isiahmead...@gmail.com wrote: I like this. It works very well. On Tue, Aug 25, 2015, 12:38 Claude Pache claude.pa...@gmail.com wrote: I think the following grammar could work. Replace the current (ES2015) PostfixExpression production with: ``` IncrementExpression: LeftHandSideExpression LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] -- ++ LeftHandSideExpression -- LeftHandSideExpression ``` And define UnaryExpression as: ``` UnaryExpression: IncrementExpression delete UnaryExpression void UnaryExpression typeof UnaryExpression ++ UnaryExpression + UnaryExpression -- UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression IncrementExpression ** UnaryExpression ``` where the following production (which exists only to avoid to confusingly interpret, e.g., `++x++` as `+ +x++`): ``` UnaryExpression: ++ UnaryExpression -- UnaryExpression ``` yields a static SyntaxError (or a static ReferenceError if we want to be 100% compatible ES2015). That way, we have the following expected behaviour: * in/decrement operators bind most tightly; * unary and exponentiation operators are applied from right to left. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
I'm a python user and I dislike using **, it just becomes rather noisy. Expressing formulas in text based programming languages has always been kind of a drag. On the other hand, often the mathematical expression of a formula would be quite inefficient because they lack the ability to keep temporary results in some variable. Picking a formula apart to isolate those temporaries the expressiveness vanishes naturally. On Tue, Aug 25, 2015 at 7:25 PM, Mark S. Miller erig...@google.com wrote: It also does not work. x ** y ** z, if we allow it at all, must be right associative. It must parse as x ** (y ** z). On Tue, Aug 25, 2015 at 10:08 AM, Mark S. Miller erig...@google.com wrote: It does not work as well as simply omitting ** entirely. On Tue, Aug 25, 2015 at 9:42 AM, Isiah Meadows isiahmead...@gmail.com wrote: I like this. It works very well. On Tue, Aug 25, 2015, 12:38 Claude Pache claude.pa...@gmail.com wrote: I think the following grammar could work. Replace the current (ES2015) PostfixExpression production with: ``` IncrementExpression: LeftHandSideExpression LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] -- ++ LeftHandSideExpression -- LeftHandSideExpression ``` And define UnaryExpression as: ``` UnaryExpression: IncrementExpression delete UnaryExpression void UnaryExpression typeof UnaryExpression ++ UnaryExpression + UnaryExpression -- UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression IncrementExpression ** UnaryExpression ``` where the following production (which exists only to avoid to confusingly interpret, e.g., `++x++` as `+ +x++`): ``` UnaryExpression: ++ UnaryExpression -- UnaryExpression ``` yields a static SyntaxError (or a static ReferenceError if we want to be 100% compatible ES2015). That way, we have the following expected behaviour: * in/decrement operators bind most tightly; * unary and exponentiation operators are applied from right to left. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Sorry. I just has another look at your proposed grammar and you are correct. On Tue, Aug 25, 2015 at 10:54 AM, Claude Pache claude.pa...@gmail.com wrote: Le 25 août 2015 à 19:25, Mark S. Miller erig...@google.com a écrit : It also does not work. x ** y ** z, if we allow it at all, must be right associative. It must parse as x ** (y ** z). Unless I missed something, it *is* right-associative. —Claude On Tue, Aug 25, 2015 at 10:08 AM, Mark S. Miller erig...@google.com wrote: It does not work as well as simply omitting ** entirely. On Tue, Aug 25, 2015 at 9:42 AM, Isiah Meadows isiahmead...@gmail.com wrote: I like this. It works very well. On Tue, Aug 25, 2015, 12:38 Claude Pache claude.pa...@gmail.com wrote: I think the following grammar could work. Replace the current (ES2015) PostfixExpression production with: ``` IncrementExpression: LeftHandSideExpression LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] -- ++ LeftHandSideExpression -- LeftHandSideExpression ``` And define UnaryExpression as: ``` UnaryExpression: IncrementExpression delete UnaryExpression void UnaryExpression typeof UnaryExpression ++ UnaryExpression + UnaryExpression -- UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression IncrementExpression ** UnaryExpression ``` where the following production (which exists only to avoid to confusingly interpret, e.g., `++x++` as `+ +x++`): ``` UnaryExpression: ++ UnaryExpression -- UnaryExpression ``` yields a static SyntaxError (or a static ReferenceError if we want to be 100% compatible ES2015). That way, we have the following expected behaviour: * in/decrement operators bind most tightly; * unary and exponentiation operators are applied from right to left. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
I like this. It works very well. On Tue, Aug 25, 2015, 12:38 Claude Pache claude.pa...@gmail.com wrote: I think the following grammar could work. Replace the current (ES2015) PostfixExpression production with: ``` IncrementExpression: LeftHandSideExpression LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] -- ++ LeftHandSideExpression -- LeftHandSideExpression ``` And define UnaryExpression as: ``` UnaryExpression: IncrementExpression delete UnaryExpression void UnaryExpression typeof UnaryExpression ++ UnaryExpression + UnaryExpression -- UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression IncrementExpression ** UnaryExpression ``` where the following production (which exists only to avoid to confusingly interpret, e.g., `++x++` as `+ +x++`): ``` UnaryExpression: ++ UnaryExpression -- UnaryExpression ``` yields a static SyntaxError (or a static ReferenceError if we want to be 100% compatible ES2015). That way, we have the following expected behaviour: * in/decrement operators bind most tightly; * unary and exponentiation operators are applied from right to left. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
This may be of some relevance: https://en.wikipedia.org/wiki/Order_of_operations#Special_cases Exponentiation is clearly exponentially more complicated in terms of order of operations and precedence than other operators if the desire is to follow 'standard maths'. Otherwise, making Exponentiation behave differently in JavaScript to how it does elsewhere is going to be a constant source of bugs and needing parentheses just to get the desire behaviour negates the whole point of making it an operator vs a function. Thomas On 26 Aug 2015, at 1:49 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Aug 25, 2015, at 8:11 AM, Mark S. Miller wrote: I think we should drop the feature. Given the conflict between * the history of ** in other languages, * the general pattern that unary binds tighter than binary any solution at this point will confuse many people. These confusions will not result in a confusing static rejection but in runtime behavior that *sometimes* violates expectations. I was all for adding ** to the language when it did not have these problems. But it does. The minor convenience it adds is not worth these costs. By contrast, no one is confused about the parsing of calls to Math.pow. When in doubt, leave it out. I've had the same reaction to this recent thread. It seems like the functional form (Math.pow) is a much less confusing formulation for use in JS expressions. It's interesting to note that while early algebraic languages such as FORTRAN, Algol 60, BASIC, PL/I all had exponentiation operators the next couple generations of similar languages including Pascal, C, C++, Java, and C# do not. Each of those languages could have had an exponentiation operator but choose to exclude it. The utility of an exponentiation operation may simply not be worth the complexity and potential for confusion it introduces into a language with a rich set of operators. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
I think we should drop the feature. Given the conflict between * the history of ** in other languages, * the general pattern that unary binds tighter than binary any solution at this point will confuse many people. These confusions will not result in a confusing static rejection but in runtime behavior that *sometimes* violates expectations. I was all for adding ** to the language when it did not have these problems. But it does. The minor convenience it adds is not worth these costs. By contrast, no one is confused about the parsing of calls to Math.pow. When in doubt, leave it out. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
So far, I like the idea of exponentiation having identical precedence to unary `+`/`-`, and lower than the increment operators. That sounds like it should work pretty well. ``` x ** y // x^y -x ** y // -(x^y) x ** -y // x^(-y) ++x ** y === (++x) ** y x++ ** y === (x++) ** y x ** ++y === x ** (++y) x ** y++ === x ** (y++) ``` On Tue, Aug 25, 2015, 12:17 Thomas thomasjamesfos...@bigpond.com wrote: This may be of some relevance: https://en.wikipedia.org/wiki/Order_of_operations#Special_cases Exponentiation is clearly exponentially more complicated in terms of order of operations and precedence than other operators if the desire is to follow 'standard maths'. Otherwise, making Exponentiation behave differently in JavaScript to how it does elsewhere is going to be a constant source of bugs and needing parentheses just to get the desire behaviour negates the whole point of making it an operator vs a function. Thomas On 26 Aug 2015, at 1:49 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Aug 25, 2015, at 8:11 AM, Mark S. Miller wrote: I think we should drop the feature. Given the conflict between * the history of ** in other languages, * the general pattern that unary binds tighter than binary any solution at this point will confuse many people. These confusions will not result in a confusing static rejection but in runtime behavior that *sometimes* violates expectations. I was all for adding ** to the language when it did not have these problems. But it does. The minor convenience it adds is not worth these costs. By contrast, no one is confused about the parsing of calls to Math.pow. When in doubt, leave it out. I've had the same reaction to this recent thread. It seems like the functional form (Math.pow) is a much less confusing formulation for use in JS expressions. It's interesting to note that while early algebraic languages such as FORTRAN, Algol 60, BASIC, PL/I all had exponentiation operators the next couple generations of similar languages including Pascal, C, C++, Java, and C# do not. Each of those languages could have had an exponentiation operator but choose to exclude it. The utility of an exponentiation operation may simply not be worth the complexity and potential for confusion it introduces into a language with a rich set of operators. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
It does not work as well as simply omitting ** entirely. On Tue, Aug 25, 2015 at 9:42 AM, Isiah Meadows isiahmead...@gmail.com wrote: I like this. It works very well. On Tue, Aug 25, 2015, 12:38 Claude Pache claude.pa...@gmail.com wrote: I think the following grammar could work. Replace the current (ES2015) PostfixExpression production with: ``` IncrementExpression: LeftHandSideExpression LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] -- ++ LeftHandSideExpression -- LeftHandSideExpression ``` And define UnaryExpression as: ``` UnaryExpression: IncrementExpression delete UnaryExpression void UnaryExpression typeof UnaryExpression ++ UnaryExpression + UnaryExpression -- UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression IncrementExpression ** UnaryExpression ``` where the following production (which exists only to avoid to confusingly interpret, e.g., `++x++` as `+ +x++`): ``` UnaryExpression: ++ UnaryExpression -- UnaryExpression ``` yields a static SyntaxError (or a static ReferenceError if we want to be 100% compatible ES2015). That way, we have the following expected behaviour: * in/decrement operators bind most tightly; * unary and exponentiation operators are applied from right to left. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Tue, Aug 25, 2015 at 11:12 AM Mark S. Miller erig...@google.com wrote: I think we should drop the feature. Given the conflict between * the history of ** in other languages, * the general pattern that unary binds tighter than binary any solution at this point will confuse many people. These confusions will not result in a confusing static rejection but in runtime behavior that *sometimes* violates expectations. I was all for adding ** to the language when it did not have these problems. But it does. The minor convenience it adds is not worth these costs. By contrast, no one is confused about the parsing of calls to Math.pow. Math.pow has exactly the same semantics as the _current_ ** . I'd like the opportunity to work with Claude and Brian to resolve the grammar issue before just tossing it out. Thanks. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
Le 25 août 2015 à 03:22, Jason Orendorff jason.orendo...@gmail.com a écrit : On Mon, Aug 24, 2015 at 7:24 PM, Jason Orendorff jason.orendo...@gmail.com P.S. Admittedly it might be a good idea to rename UnaryExpression if we put a binary operator in there. -j RightAssociativeExpression? —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On 08/25/2015 09:38, Claude Pache wrote: I think the following grammar could work. Replace the current (ES2015) PostfixExpression production with: ``` IncrementExpression: LeftHandSideExpression LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] -- ++ LeftHandSideExpression -- LeftHandSideExpression ``` And define UnaryExpression as: ``` UnaryExpression: IncrementExpression delete UnaryExpression void UnaryExpression typeof UnaryExpression ++ UnaryExpression + UnaryExpression -- UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression IncrementExpression ** UnaryExpression ``` The above is not a valid grammar. For example, parsing ++x leads to a reduce-reduce conflict, where the ++ can come from either a UnaryExpression or an IncrementExpression. where the following production (which exists only to avoid to confusingly interpret, e.g., `++x++` as `+ +x++`): That makes no sense. ++ is a lexical token. The lexer always greedily bites off the largest token it can find, even if that leads to a parser error later. The parser does not backtrack into the lexer to look for alternate lexings. For example, x + y; is a syntax error because it's greedily lexed as: x ++ ++ + y; The parser does not backtrack into the lexer to look for other possible lexings such as: x ++ + ++ y; ``` UnaryExpression: ++ UnaryExpression -- UnaryExpression ``` yields a static SyntaxError (or a static ReferenceError if we want to be 100% compatible ES2015). This is a problem. It makes ++x into a static SyntaxError because x is a UnaryExpression. If you got rid of these two ++ and -- productions in UnaryExpression, that would solve that problem (and I think make the grammar valid). Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
When the costs were minor, it was ok that the benefits were minor. Given significant costs, we need to ask: Why do we need ** ? What great benefit does it provide? If nothing compelling, then this proposal has lost consensus. On Tue, Aug 25, 2015 at 3:30 PM, Claude Pache claude.pa...@gmail.com wrote: Le 25 août 2015 à 03:22, Jason Orendorff jason.orendo...@gmail.com a écrit : On Mon, Aug 24, 2015 at 7:24 PM, Jason Orendorff jason.orendo...@gmail.com P.S. Admittedly it might be a good idea to rename UnaryExpression if we put a binary operator in there. -j RightAssociativeExpression? —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On 08/24/2015 17:24, Jason Orendorff wrote: On Mon, Aug 24, 2015 at 5:45 PM, Waldemar Horwat walde...@google.com wrote: Let's not. As I said at the last meeting, making ** bind tighter than unary operators would break x**-2. And making it sometimes tighter and sometimes looser would be too confusing and lead to other opportunities for precedence inversion. Don't you think having `-x**2` mean the same thing as `x**2` is more confusing? It seems like it will cause problems for the exact programmers we are trying to help with this feature. What you're describing as sometimes tighter and sometimes looser I would call the same precedence. It's even easier to specify than the current proposal: UnaryExpression : PostfixExpression ** UnaryExpression An expression using both `**` and unary `-` is then parsed right-associatively: -a ** -b ** -c ** -d means -(a ** (-(b ** (-(c ** (-d)) That has different right and left precedence and is probably the closest to the mathematical intent. However, it does carry other surprises. What does each of the following do? ++x ** y; x++ ** y; x ** ++y; x ** y++; Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Mon, Aug 24, 2015 at 7:24 PM, Jason Orendorff jason.orendo...@gmail.com wrote: What you're describing as sometimes tighter and sometimes looser I would call the same precedence. It's even easier to specify than the current proposal: UnaryExpression : PostfixExpression ** UnaryExpression P.S. Admittedly it might be a good idea to rename UnaryExpression if we put a binary operator in there. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Mon, Aug 24, 2015 at 8:10 PM, Waldemar Horwat walde...@google.com wrote: That has different right and left precedence and is probably the closest to the mathematical intent. Not to quibble, but I do want to understand: UnaryExpression : PostfixExpression ** UnaryExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression We don't say binary `+` has different left and right precedence, right? What's different with `**`, apart from being right-associative? However, it does carry other surprises. What does each of the following do? Interesting: ++x ** y; // early error: invalid operand for ++ (because it's parsed as `++(x ** y)`) x++ ** y; // parses as expected: (x++) ** y x ** ++y; // parses as expected: x ** (++y) x ** y++; // parses as expected: x ** (y++) I'm OK with this. It should be rarer in practice than `-x**2`, and at least the language won't silently assign a surprising meaning to user code. It could be made to parse as `(++x) ** y` by changing prefix ++ and -- to be higher precedence than the other prefix operators. I don't think this would break any existing programs, because combinations like `++typeof 3` are already early errors. PHP apparently does something like this: $ php -r '$x = 3; print(++$x**2 . \n); print($x . \n);' 16 4 D doesn't. Python and Haskell don't have ++/--. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Mon, Aug 24, 2015 at 3:45 PM, Waldemar Horwat walde...@google.com wrote: On 08/24/2015 10:08, Jason Orendorff wrote: In math, -x² is -(x²), not (-x)². But as proposed for JS, -x**2 is (-x)**2. PHP, Python, Haskell, and D side with the traditional algebraic notation, against JS. Here's PHP: $ php -r 'print(-2 ** 2);' -4 Python: -2 ** 2 -4 Haskell: Prelude -2 ^ 2 -4 The D grammar: http://dlang.org/grammar.html#UnaryExpression Let's switch. Let's not. As I said at the last meeting, making ** bind tighter than unary operators would break x**-2. And making it sometimes tighter and sometimes looser would be too confusing and lead to other opportunities for precedence inversion. Waldemar Agreed that the precedence should not bind sometimes tighter and sometimes looser is problematic. I think following the way other languages solve the same problem is more important for minimizing user surprise than any particular expression looking especially good. Looking kinda similar to other languages in surface syntax has been a major advantage of JS all along. Dan ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Exponentiation operator precedence
On Mon, Aug 24, 2015 at 5:45 PM, Waldemar Horwat walde...@google.com wrote: Let's not. As I said at the last meeting, making ** bind tighter than unary operators would break x**-2. And making it sometimes tighter and sometimes looser would be too confusing and lead to other opportunities for precedence inversion. Don't you think having `-x**2` mean the same thing as `x**2` is more confusing? It seems like it will cause problems for the exact programmers we are trying to help with this feature. What you're describing as sometimes tighter and sometimes looser I would call the same precedence. It's even easier to specify than the current proposal: UnaryExpression : PostfixExpression ** UnaryExpression An expression using both `**` and unary `-` is then parsed right-associatively: -a ** -b ** -c ** -d means -(a ** (-(b ** (-(c ** (-d)) -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss