Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<html><head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head><body style="color: rgb(0, 0, 0); background-color: rgb(255, 255,
 255); color: rgb(0, 0, 0); background-color: rgb(255, 255,
 255); color: rgb(0, 0, 0); background-color: rgb(255, 255,
 255); color: rgb(0, 0, 0); background-color: rgb(255, 255,
 255);" bgcolor="#FFFFFF" text="#000000">[Apologies for resending, 
trying to fix formatting of grammar excerpts. /be]<br>
<br>
Quick update from TC39 
yesterday where Rick and I presented the Stage 3 Exponentiation Operator
 proposal:<br>
<br>
<a class="moz-txt-link-freetext" 
href="http://rwaldron.github.io/exponentiation-operator/">http://rwaldron.github.io/exponentiation-operator/</a><br>
<br>
The current spec, revised to match precedent from all known programming 
languages that have exponentiation operators, binds<br>
<br>
<big><big>-x<sup>y</sup> = -(x<sup>y</sup>)</big></big><br>
<br>
and not<br>
<br>
<big><big>-x<sup>y</sup> = (-x</big></big><big><big>)</big></big><big><big><sup>y</sup><br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
  </big></big>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.<br>
<br>
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.<br>
<br>
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 **.<br>
<br>
We debated the options, which I think are four in number:<br>
<br>
1. Give up because the proposal has hit a "wall of confusion".<br>
<br>
2. Stick with the current spec,<br>
<br>
3. Go back to the old spec, which flouts precedent.<br>
<br>
4. Make unparenthesized exponentiation expression as operand of unary 
operators an early error.<br>
<br>
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).<br>
<br>
The grammar change needed for (4) is trivial. Instead of<br>
<big><br>
  <span style="font-style: italic;">UnaryExpression</span><sub>[Yield]</sub>:<br>
  <span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span 
style="font-style: italic;">IncrementExpression</span><sub>[?Yield]</sub><br><span
 style="font-family: monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;delete</span> <span style="font-style: italic;">UnaryExpression</span><sub>[?Yield]</sub><br><span
 style="font-family: monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;void</span> <span style="font-style: italic;">UnaryExpression</span><sub>[?Yield]</sub><br><span
 style="font-family: monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;typeof</span> <span style="font-style: italic;">UnaryExpression</span><sub>[?Yield]</sub><br><span
 style="font-family: monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;+</span> <span style="font-style: italic;">UnaryExpression</span><sub>[?Yield]</sub><br>
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;-</span> <span 
style="font-style: italic;">UnaryExpression</span><sub>[?Yield]</sub><br>
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;~</span> <span 
style="font-style: italic;">UnaryExpression</span><sub>[?Yield]</sub><br>
  <span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;</span>!<span 
style="font-family: monospace;"> </span><span style="font-style: 
italic;">UnaryExpression</span><sub>[?Yield]</sub><br>
  <span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span 
style="font-style: italic;">IncrementExpression</span><sub>[?Yield]</sub>
 ** <span style="font-style: italic;">UnaryExpression</span><sub>[?Yield]</sub></big><br>
<br>
we factor to require parentheses around the last right-hand side if it 
is an operand of a unary operator:<br>
<big><br>
  <span style="font-style: italic;">UnaryExpression</span><sub>[Yield]</sub>:<br>
</big><big>
  <span style="font-style: italic;"></span></big><big><span 
style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-style: italic;">SimpleUnaryExpression</span><sub>[?Yield]</sub></big><br>
<big>
</big><big><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span 
style="font-style: italic;">IncrementExpression</span><sub>[?Yield]</sub>
 ** <span style="font-style: italic;">UnaryExpression</span><sub>[?Yield]</sub></big><br>
<big><span style="font-style: italic;"><br>
SimpleUnaryExpression</span><sub>[Yield]</sub>:<br>
</big><big><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span 
style="font-style: italic;">IncrementExpression</span><sub>[?Yield]</sub><br>
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;delete</span> <span 
style="font-style: italic;">SimpleUnaryExpression</span><sub>[?Yield]</sub><br>
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;void</span> <span 
style="font-style: italic;">SimpleUnaryExpression</span><sub>[?Yield]</sub><br>
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;typeof</span> <span 
style="font-style: italic;">SimpleUnaryExpression</span><sub>[?Yield]</sub><br>
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;+</span> <span 
style="font-style: italic;">SimpleUnaryExpression</span><sub>[?Yield]</sub><br>
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;-</span> <span 
style="font-style: italic;">SimpleUnaryExpression</span><sub>[?Yield]</sub><br>
<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;~</span> <span 
style="font-style: italic;">SimpleUnaryExpression</span><sub>[?Yield]</sub><br>
  <span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;</span>!<span 
style="font-family: monospace;"> </span><span style="font-style: 
italic;">SimpleUnaryExpression</span><sub>[?Yield]</sub><br>
</big><br>
(It would be nice to rename non-terminals like so: 
s/\&lt;UnaryExpression\&gt;/ExponentiationExpression/g; 
s/\&lt;SimpleUnaryExpression\&gt;/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.)<br>
<br>
Thus one may write<br>
<br>
<big style="font-family: monospace;">let z = K - x**y;</big><br>
<br>
without having to parenthesize unduly<span style="font-family: 
monospace;"></span>, but one cannot write<br>
<br>
<big><span style="font-family: monospace;">let z = -x ** y;</span></big><br>
<br>
The user is forced by an early error to write either <span 
style="font-family: monospace;">(-x)**y</span> or <span 
style="font-family: monospace;">-(x**y)</span>.<br>
<br>
The early error stops parsing with a thrown <span style="font-family: 
monospace;">SyntaxError</span>.<br>
<br>
It seems to me (4) wins and rescues the proposal at stage 3 from 
suffering a loss of consensus. Comments welcome.<br>
<br>
/be<br>
<br>
<span>Jason Orendorff wrote:</span><br>
<blockquote 
cite="mid:CAPh8+Zrh-7+Ya35YCuN+xTPApL_rZjhUk4wcnYfjbSXf=E4T=g@mail.gmail.com"
 type="cite"><pre wrap="">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
<a class="moz-txt-link-abbreviated" href="mailto:es-discuss@mozilla.org">es-discuss@mozilla.org</a>
<a class="moz-txt-link-freetext" href="https://mail.mozilla.org/listinfo/es-discuss">https://mail.mozilla.org/listinfo/es-discuss</a>
</pre></blockquote>
<br>
<br>
</body></html>
Output 300px

This bin was created anonymously and its free preview time has expired (learn why). — Get a free unrestricted account

Dismiss x
public
Bin info
anonymouspro
0viewers