So to sum up:
1. Default parameter expressions are evaluated in the activation scope,
with all formal parameters bound, no use-before-set dead zone (so
formals are var-like), functions hoisted and in scope -- because in this
case, simpler and worse are better.
2. Generator function with
On Sat, Sep 15, 2012 at 2:14 AM, Brendan Eich bren...@mozilla.org wrote:
So to sum up:
1. Default parameter expressions are evaluated in the activation scope,
with all formal parameters bound, no use-before-set dead zone (so formals
are var-like), functions hoisted and in scope -- because in
Rick Waldron wrote:
On Sat, Sep 15, 2012 at 2:14 AM, Brendan Eich bren...@mozilla.org
mailto:bren...@mozilla.org wrote:
So to sum up:
1. Default parameter expressions are evaluated in the activation
scope, with all formal parameters bound, no use-before-set dead
zone (so
On Thu, Sep 13, 2012 at 8:23 PM, Kevin Smith khs4...@gmail.com wrote:
No amount of argument is going to convince a user that defaults should *not*
be executed at the location of the call. That's just not how it reads. No?
I kind of agree, but at this point we could do with a little less
I don’t have a strong preference. It seems to be is a classic Right
Thing vs. Worse Is Better situation. The advantage of the Worse Is
Better approach is that you can correctly and completely explain
what’s going on in one sentence: “It’s just like an if statement at
the top of the function
Kevin Smith wrote:
What I'm questioning now is the idea that, in generators, the implicit
first yield should occur *before the defaults are evaluated*. I don't
think that's a tenable position. Is there an implementation problem
with inserting the implicit first yield *after* the defaults are
Jason Orendorff wrote:
I think Allen is proposing a scheme where in code like
function f(a1=EXPR1, a2=EXPR2, a3=EXPR3) { ... }
f();
first EXPR1 is evaluated in a scope including only a1,
then EXPR2 is evaluated in a scope that contains a1 and a2,
then EXPR3 is evaluated in a scope
My point is serious, in that we are not bound to follow C, C++, or Java
and try to separate formal parameter scope, default parameter
initialization, or other observables from those languages, just because of
that left curly brace at the start of a function body.
Yeah - but the argument
On Wed, Sep 12, 2012 at 5:13 AM, Brendan Eich bren...@mozilla.com wrote:
You say it's too error prone but you don't adduce any evidence.
Meanwhile we have lots of extant code that does things like
function foo(bar, baz) {
baz = baz || default_baz;
...
}
That's the cowpath
We still have the choice of the implicit yield going after argument
defaulting, not before. SpiderMonkey implements before, though, and my own
argument from compositionality, above, makes it more clear to me that we
should go with implicit-yield-first. This makes contrived throwing
parameter
Kevin Smith wrote:
function f(x) {
console.log(x);
if (truthy()) {
with ({x: 'ha ha'}) {
var x = 'ho ho';
console.log(x);
}
}
function x(){}
console.log(x);
}
In these cases there is
Dmitry Soshnikov wrote:
On Tue, Sep 11, 2012 at 1:33 AM, Brendan Eich bren...@mozilla.com
mailto:bren...@mozilla.com wrote:
If you really want the Pythonic default parameter rules
(evaluation in definition context) then you need to address the
bad case Jason showed:
Allen, even with all the requirements you listed, I wouldn't write
that example code. There's a more natural way to factor the problem.
The original example fails for at least the last bullet. To fix that, it
would have to be rewritten, something like:
function dataSnapshot(aDataSource) {
Nothing is new here, under the straightforward semantics Jason
described. JS today:
var FOO = 42;
function bar(x, y) {
if (y === void 0) y = FOO + x;
...
}
ES6 as proposed:
var FOO = 42;
function bar(x, y = FOO + x) {
...
}
What's the problem?
The other cases you
Dmitry Soshnikov wrote:
var FOO = 42;
function bar(x, y = FOO + z) { var z = 10; } // Error .. ?
Translating to JS as it is:
var FOO = 42;
function bar(x, y) {
if (y === void 0) y = FOO + z;
var z = 10;
}
No error expected, undefined hoisted z used in FOO + z resulting in y
On Tue, Sep 11, 2012 at 10:33 AM, Brendan Eich bren...@mozilla.com wrote:
If you really want the Pythonic default parameter rules (evaluation in
definition context) then you need to address the bad case Jason showed:
function foo(arg = []) {
arg.push('strange');
return arg;
}
Brendan Eich wrote:
Dmitry Soshnikov wrote:
var FOO = 42;
function bar(x, y = FOO + z) { var z = 10; } // Error .. ?
Translating to JS as it is:
var FOO = 42;
function bar(x, y) {
if (y === void 0) y = FOO + z;
var z = 10;
}
Another benefit of the simple semantics: existing
On Sep 11, 2012, at 4:39, Brendan Eich bren...@mozilla.com wrote:
Brendan Eich wrote:
Dmitry Soshnikov wrote:
var FOO = 42;
function bar(x, y = FOO + z) { var z = 10; } // Error .. ?
Translating to JS as it is:
var FOO = 42;
function bar(x, y) {
if (y === void 0) y = FOO + z;
Domenic Denicola wrote:
On Sep 11, 2012, at 4:39, Brendan Eichbren...@mozilla.com wrote:
Brendan Eich wrote:
Dmitry Soshnikov wrote:
var FOO = 42;
function bar(x, y = FOO + z) { var z = 10; } // Error .. ?
Translating to JS as it is:
var FOO = 42;
function bar(x, y) {
if (y ===
function f(x) {
console.log(x);
if (truthy()) {
with ({x: 'ha ha'}) {
var x = 'ho ho';
console.log(x);
}
}
function x(){}
console.log(x);
}
In these cases there is information flowing right to left, even across
unbalanced left
The initializing generator arguments thread and related discussions has got me
questioning our use of function declaration/expression syntax as our basis for
defining generators. Changing this would be a departure from what Firefox has
supported in recent years, but in ES6 we have more
On Tue, Sep 11, 2012 at 1:33 AM, Brendan Eich bren...@mozilla.com wrote:
If you really want the Pythonic default parameter rules (evaluation in
definition context) then you need to address the bad case Jason showed:
function foo(arg = []) {
arg.push('strange');
return arg;
}
On Tue, Sep 11, 2012 at 1:36 AM, Brendan Eich bren...@mozilla.com wrote:
Dmitry Soshnikov wrote:
var FOO = 42;
function bar(x, y = FOO + z) { var z = 10; } // Error .. ?
Translating to JS as it is:
var FOO = 42;
function bar(x, y) {
if (y === void 0) y = FOO + z;
var z =
I'd appreciate a less contrived motivating example. The best way to
implement this dataSnapshot() function is simply:
function dataSnapshot(aCollection) {
return aCollection.clone();
}
-j
___
es-discuss mailing list
On Tue, Sep 11, 2012 at 4:53 AM, Domenic Denicola
dome...@domenicdenicola.com wrote:
...
And, if one replaced all `var`s in the above example with `let`s, one
would get the desired error, right? To me the most important use cases to
consider are those in an idiomatic ES6
On Tue, Sep 11, 2012 at 11:37 AM, Dmitry Soshnikov
dmitry.soshni...@gmail.com wrote:
On Tue, Sep 11, 2012 at 1:33 AM, Brendan Eich bren...@mozilla.com wrote:
If you really want the Pythonic default parameter rules (evaluation in
definition context) then you need to address the bad case
On Sep 11, 2012, at 7:48 PM, Jason Orendorff wrote:
I'd appreciate a less contrived motivating example. The best way to
implement this dataSnapshot() function is simply:
function dataSnapshot(aCollection) {
return aCollection.clone();
}
-j
My original example was
Jason Orendorff wrote:
On Sun, Sep 9, 2012 at 8:50 PM, Jason Orendorff
jason.orendo...@gmail.com wrote:
What I think is that default parameters should be specified to be as
much like the following desugaring as possible:
function f(x=EXPR1, y=EXPR2) { BODY }
===
function f(x,
On Mon, Sep 10, 2012 at 1:08 PM, Brendan Eich bren...@mozilla.com wrote:
Jason Orendorff wrote:
On Sun, Sep 9, 2012 at 8:50 PM, Jason Orendorff
jason.orendo...@gmail.com wrote:
What I think is that default parameters should be specified to be as
much like the following desugaring as
function f(x=EXPR1, y=EXPR2) { BODY }
===
function f(x, y) {
if (x === void 0) x = EXPR1;
if (y === void 0) y = EXPR2;
BODY
}
In case it isn't clear what I'm saying here, I think the same
desugaring should hold for generators. Exceptions
Kevin Smith wrote:
function f(x=EXPR1, y=EXPR2) { BODY }
===
function f(x, y) {
if (x === void 0) x = EXPR1;
if (y === void 0) y = EXPR2;
BODY
}
In case it isn't clear what I'm saying here, I think the same
desugaring should hold for
Brendan Eich wrote:
Python binds then, but evaluates the expressions at generation
definition evaluation time.
generator definition evaluation time of course -- -ion on the brain
(IonMonkey!).
/be
___
es-discuss mailing list
es-discuss@mozilla.org
Brendan Eich wrote:
Any exceptions that occur in the generator body prior to the first
yield will be expected at the first call to next().
That would be loc 2, though -- seems to go against what you wrote
earlier.
I stick by this! ;-)
It also is not how generators work in Python or
On Mon, Sep 10, 2012 at 12:50 PM, Kevin Smith khs4...@gmail.com wrote:
function f(x=EXPR1, y=EXPR2) { BODY }
===
function f(x, y) {
if (x === void 0) x = EXPR1;
if (y === void 0) y = EXPR2;
BODY
}
I'm not so sure - the desugaring above would
On Sep 10, 2012, at 9:48 PM, Jason Orendorff jason.orendo...@gmail.com wrote:
On Mon, Sep 10, 2012 at 12:50 PM, Kevin Smith khs4...@gmail.com wrote:
function f(x=EXPR1, y=EXPR2) { BODY }
===
function f(x, y) {
if (x === void 0) x = EXPR1;
if (y === void 0) y = EXPR2;
But as I pointed out, we have problems already in JS:
function f(x) {var x; ...}
the var x restates the formal parameter. It does not shadow it.
Ah - observable here:
function crazypants(x) { var x; return x; }
undefined
crazypants(123);
123
If it shadowed, we would
Kevin Smith wrote:
But as I pointed out, we have problems already in JS:
function f(x) {var x; ...}
the var x restates the formal parameter. It does not shadow it.
Ah - observable here:
function crazypants(x) { var x; return x; }
undefined
crazypants(123);
123
If
On Mon, Sep 10, 2012 at 2:59 PM, Tobie Langel tobie.lan...@gmail.com wrote:
On Sep 10, 2012, at 9:48 PM, Jason Orendorff jason.orendo...@gmail.com
wrote:
On Mon, Sep 10, 2012 at 12:50 PM, Kevin Smith khs4...@gmail.com wrote:
function f(x=EXPR1, y=EXPR2) { BODY }
===
function f(x,
Oops, missing one line below:
Brendan Eich wrote:
Which one? If you mean let*, so that
function f(a = a, b = b*a) { return [a, b]; }
var a = 42;
var b;
console.log(f()) // [42, NaN]
console.log(f(1)) // [1, NaN]
console.log(f(1,2)) // [1, 2]
Otherwise b*a will throw on unbound
(re-adding the list)
On Mon, Sep 10, 2012 at 5:20 PM, Tobie Langel tobie.lan...@gmail.com wrote:
Yes, sorry for being unclear. What I meant to say was that I would
expect EXPR1 and EXPR2 to have been evaluated within the lexical scope
of f() at the time of function declaration, in source
On Mon, Sep 10, 2012 at 2:47 PM, Jason Orendorff
jason.orendo...@gmail.comwrote:
On Mon, Sep 10, 2012 at 2:59 PM, Tobie Langel tobie.lan...@gmail.com
wrote:
On Sep 10, 2012, at 9:48 PM, Jason Orendorff jason.orendo...@gmail.com
wrote:
On Mon, Sep 10, 2012 at 12:50 PM, Kevin Smith
Dmitry Soshnikov wrote:
FOO = 45;
bar(); // 48
Use cases like:
function bar(y = FOO + 3) {
var FOO = 10;
return y;
}
May look subtle, however, if again to accept lexical scope as the
function definition, then FOO again should be resolved in the
bar.[[Scope]], not in the bar's
On Mon, Sep 10, 2012 at 5:38 PM, Brendan Eich bren...@mozilla.com wrote:
Dmitry Soshnikov wrote:
FOO = 45;
bar(); // 48
Use cases like:
function bar(y = FOO + 3) {
var FOO = 10;
return y;
}
May look subtle, however, if again to accept lexical scope as the
function definition,
On Mon, Sep 10, 2012 at 5:55 PM, Dmitry Soshnikov
dmitry.soshni...@gmail.com wrote:
But not this one:
var FOO = 42;
function bar(x, y = FOO + y) { var y = 10; } // Error .. ?
Typo, mean if there is no such parameter, but only the local var:
var FOO = 42;
function bar(x, y = FOO + z) {
I wanted to leave a clean example (no var and let mixing, either):
function dataSnapshot(aCollection) {
let snapshot = aCollection.clone();
let i = 0;
return {
next: function () {
if (i == snapshot.length)
throw StopIteration;
return snapshot[i++];
}
};
}
(I
On Sep 9, 2012, at 3:32 PM, Brendan Eich wrote:
I wanted to leave a clean example (no var and let mixing, either):
function dataSnapshot(aCollection) {
let snapshot = aCollection.clone();
let i = 0;
return {
next: function () {
if (i == snapshot.length)
throw
On Sat, Sep 8, 2012 at 3:01 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
This is the first of probably several semantic issues WRT generator that
will need to be resolved in the spec.
I mentioned this to David Herman when we started implementing default
parameters.
What I think is that
On Sun, Sep 9, 2012 at 8:50 PM, Jason Orendorff
jason.orendo...@gmail.com wrote:
What I think is that default parameters should be specified to be as
much like the following desugaring as possible:
function f(x=EXPR1, y=EXPR2) { BODY }
===
function f(x, y) {
if (x ===
This is the first of probably several semantic issues WRT generator that will
need to be resolved in the spec.
Here is the user level issue:
let thrower = {throw () {throw exception}};
function * G(arg = thrower.throw()) {
//possibly other explicit initialization code which could also throw
Allen Wirfs-Brock wrote:
This is the first of probably several semantic issues WRT generator
that will need to be resolved in the spec.
Here is the user level issue:
let thrower = {throw () {throw exception}};
function * G(arg = thrower.throw()) {
//possibly other explicit initialization
Brendan Eich wrote:
However, the semantics of parameter default value initialization can
result in exceptions and more closely links argument instantiations
with the actual activation of the generator function. You can't
really build the parameter bindings without performing declaration
On Saturday, September 8, 2012 at 4:01 PM, Allen Wirfs-Brock wrote:
This is the first of probably several semantic issues WRT generator that will
need to be resolved in the spec.
Here is the user level issue:
let thrower = {throw () {throw exception}};
function * G(arg =
SpiderMonkey (Firefox 15 and newer has default parameters):
js function f(a = g) { function g(){}; return a; }
js f()
function g(){}
So function g is hoisted and a defaults to it, as expected.
The trivial generator variant, i.e., what you get by putting a * after
function and before f, above:
On Sep 8, 2012, at 3:20 PM, Brendan Eich wrote:
SpiderMonkey (Firefox 15 and newer has default parameters):
js function f(a = g) { function g(){}; return a; }
js f()
function g(){}
So function g is hoisted and a defaults to it, as expected.
While I agree that the above is reasonable
Sorry to over-reply. This *does* work in SpiderMonkey:
js function f(a = g) { function g(){}; yield a; }
js var it = f()
js it.next()
function g(){}
/be
Brendan Eich wrote:
SpiderMonkey (Firefox 15 and newer has default parameters):
js function f(a = g) { function g(){}; return a; }
js f()
On Sep 8, 2012, at 3:59 PM, Brendan Eich wrote:
Here's an attempt at a crucial experiment:
js var g = 'now'
js function f(a = g) { yield a; }
js var it = f()
js g = 'later'
later
js it.next()
later
So I'm wrong, SpiderMonkey inserts the impliciti |yield;| before parameter
Allen Wirfs-Brock wrote:
On Sep 8, 2012, at 3:51 PM, Brendan Eich wrote:
Allen Wirfs-Brock wrote:
On Sep 8, 2012, at 3:20 PM, Brendan Eich wrote:
SpiderMonkey (Firefox 15 and newer has default parameters):
js function f(a = g) { function g(){}; return a; }
js f()
function g(){}
So
Allen Wirfs-Brock wrote:
On Sep 8, 2012, at 3:59 PM, Brendan Eich wrote:
Here's an attempt at a crucial experiment:
js var g = 'now'
js function f(a = g) { yield a; }
js var it = f()
js g = 'later'
later
js it.next()
later
So I'm wrong, SpiderMonkey inserts the impliciti |yield;| before
On Sep 8, 2012, at 5:20 PM, Brendan Eich wrote:
Allen Wirfs-Brock wrote:
On Sep 8, 2012, at 3:59 PM, Brendan Eich wrote:
Here's an attempt at a crucial experiment:
js var g = 'now'
js function f(a = g) { yield a; }
js var it = f()
js g = 'later'
later
js it.next()
later
So
Allen Wirfs-Brock wrote:
On Sep 8, 2012, at 5:20 PM, Brendan Eich wrote:
The contract of dataSnapshot wants a deep copy of aCollection, so it must make
one. Fortunately if we bind parameters before the implicit yield, it can:
function dataSnapshot(aCollection) {
var snapshot =
Brendan Eich wrote:
That's a gap in the wiki'ed page. As in Python, and in SpiderMonkey
for almost six years, yield like return has an operation
optional
operand. Unlike return, and after Python 2.5, yield is an operator
(low-precedence, at assignment level).
Send from my iPad, LOL
/be
Brendan Eich wrote:
function dataSnapshot(aCollection) {
var snapshot = aCollection.clone();
let i = 0;
let i = -1;
rather,
return {
next: function () {
if (++i == snapshot.length)
throw StopIteration;
return snapshot[i];
}
};
}
or this might run a
62 matches
Mail list logo