Re: Day 2 meeting notes

2010-08-01 Thread Kevin Curtis
for (k in lst) { ... } // key

for (v, in lst) { ... } // value - trailing comma

for (v,k in lst) { ...} // value, key

And/Or using some symbol to indicate an iterator:
for ([k,v] in @lst) {...} // with destructuring
//@ = sugar for the method call to return the iterator.
let it = @lst;

How much leeway is there for adding new keywords?

--
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-08-01 Thread Brendan Eich
On Aug 1, 2010, at 10:55 AM, Kevin Curtis wrote:

 for (k in lst) { ... } // key
 
 for (v, in lst) { ... } // value - trailing comma
 
 for (v,k in lst) { ...} // value, key

We already have destructuring, which looks similar but with less ambiguity or 
lightness (square or curly brackets, helpful to avoid typos and misreadings 
by code reviewers).

Typically key comes before value when destructuring items (see Python and 
other languages).


 And/Or using some symbol to indicate an iterator:
 for ([k,v] in @lst) {...} // with destructuring
 //@ = sugar for the method call to return the iterator.
 let it = @lst;

And if the @ operand is not a proxy with an iterate trap in its handler?

If the answer is to throw an error for want of an iterable, then some 
(allegedly, see shallowCopy) generic code will work well, while other would-be 
generic code will not.

Adding a way to opt into iteration instead of enumeration only helps if 
enumeration is right -- but enumeration is broken in several ways, so the 
long-term trade-offs are not so clearly in favor of keeping it under-specified 
yet sacrosanct.

There are three parties (at least) involved in the evolving system: the for-in 
loop author; JS hackers who might pass in any native, host, and proxy object; 
and Ecma TC39 / the browser vendors and other JS implementors.

1. The for-in loop author may know exactly what objects could ever be on the 
right of 'in', but let's assume not. The really challenging case is where the 
loop is in a reusable function taking the object as a parameter. Such an author 
has a hard time defending against host objects even today, never mind against 
proxies tomorrow. Again, this applies to . and [] as well as for-in -- all can 
give unusual answers down the road, although competition should (knock on wood) 
keep the insane objects from proliferating.

2. The JS hackers who might pass in unexpected objects may not simply err or do 
evil. Often they make clever use of the for-in-based library function, and 
would like to smooth other any differences between implementations in how 
for-in works. These users want more meta-programmability.

3. The TC39 committee can try to bikeshed syntax for new fixed points of 
semantics, but as I've written, we are the least likely to get it right and 
make it stick.

Which of the three parties is most likely to provide the right object for a 
given for-in-based library function? My money is on party #2, the JS hackers at 
large and in the future.

BTW @foo is already in use in ECMA-357 (E4X).


 How much leeway is there for adding new keywords?


We can add new keywords, especially contextual ones (although not in verbose 
ways that users will hate). It is hard to prove new reserved identifiers won't 
impose an oversized migration tax compared to the alleged benefit.

No one wants to add if there's a good way not to add (e.g., via a module or 
other library API) that has as good or better usability than a keyword. Hence 
our rejection of 'each' in favor of library (module) based standard iterators.

/be



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-08-01 Thread Brendan Eich
On Aug 1, 2010, at 11:29 AM, Brendan Eich wrote:

 And if the @ operand is not a proxy with an iterate trap in its handler?
 
 If the answer is to throw an error for want of an iterable, then some 
 (allegedly, see shallowCopy) generic code will work well, while other 
 would-be generic code will not.

I should have written work well, in the sense of not copying a potentially 
large number of iterated values, but getting an exception instead usually 
means a hard stop. Existing code would not defend with try-catch and try some 
fallback logic.

Really, generic code is hard to write without more meta-programming control, 
both inspection and intercession.

That's what we are aiming at with proxies (including iteration).

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-31 Thread Brendan Eich
On Jul 30, 2010, at 9:06 PM, felix wrote:

 it seems odd to me that if 'a' is an iterator, it will iterate over the 
 iterator's value stream instead of the iterator's properties, unless you 
 define the two to be identical, which would be strange.  eg, if you have an 
 input stream iterator f, would f.hasOwnProperty('bacon') work or not?

Sorry, I misspoke -- without having specified keys fully (we'll get to that 
task on the wiki), let me try to make up for it by implementing some variations 
on keys using proxies, in TraceMonkey.

The object returned by keys, called a in your revision, is a proxy. Let's 
call it p to avoid confusion.

Let's say that the handler for proxy p has no traps emulating properties, 
only an iterate trap. The iterate trap is a derived trap (it is optional; if 
missing, the default enumerate behavior is supplied by the proxy support in the 
runtime). The for-in loop calls the iterate trap on p, which returns an 
iterator object.

This iterator, call it it, is an object with a 'next' property whose value is 
a function taking no arguments and returning the next value in the iteration. 
This iterator object it is not necessarily a proxy -- it could be, but it 
need not be.

Ok, so the proxy denoted by p returned by keys(o) has been subject to for-in 
by being on the right of 'in', so its iterate trap has been called, and now the 
for-in runtime has the returned iterator it.

The for-in loop runtime therefore calls it.next() implicitly at the top of each 
iteration of the loop body. If it.next() throws StopIteration, the for-in loop 
terminates normally (any other exception thrown by the body terminates the loop 
and is of course propagated).

Here's a keys implementation in bleeding edge SpiderMonkey 
(http://hg.mozilla.org/tracemonkey):

js function keys(o) {
const handler = {
iterate: function () { for (let i in o) yield i; }
};
return Proxy.create(handler);
}
js let o = {a:1, b:2, c:3};
js for (let k in keys(o))
print(k);
a
b
c
js 

(The strawman at http://wiki.ecmascript.org/doku.php?id=strawman:iterators 
provides a convenience Iterator.create function to make a proxy given just the 
handler iterate trap function. Using it, we could simplify keys to just

function keys(o) {
return Iterator.create(function () { for (let i in o) yield i; });
}

but the full expansion above, using Proxy.create, is not much longer.)

What if you wanted a proxy whose handler uses other traps in addition to 
iterate to emulate enumerable properties in full? That is doable too, thanks to 
the power of proxies:

js function keys2(o) {
const handler = {
iterate: function () { for (let i in o) yield i; },
getPropertyDescriptor: function (name) {
if (o.hasOwnProperty(name))
return Object.getOwnPropertyDescriptor(o, name); 
return undefined;
},
getOwnPropertyDescriptor: function (name) {
return Object.getOwnPropertyDescriptor(o, name); 
},
defineProperty: function (name, pd) {
return Object.defineProperty(o, name, pd);
},
getOwnPropertyNames: function () {
return Object.getOwnPropertyNames(o);
},
delete: function (name) {
return delete o[name];
},
/*enumerate:*/
fix: function () {
return Object.freeze(o);
}
};
return Proxy.create(handler);
}
js let o = {a:1, b:2, c:3};
js let p = keys2(o);
js for (let k in p)
print(k);
a
b
c
js print(p.a);
1
js print(p.b);
2
js print(p.c);
3
js delete p.a;
true
js for (let k in p)
print(k);
b
c

There's a workaround in this handler's getPropertyDescriptor trap, because we 
have not yet implemented Object.getPropertyDescriptor (it was ratified only 
this week at the TC39 meeting). I took the easy way out and instead of walking 
o's prototype chain, being careful to shadow, I handle only own properties 
(let's assume that Object.prototype has not been monkey-patched ;-).

This example shows how delete p.a followed by another for-in loop over p 
reveals that 'a' has been deleted. The proxy is implementing native object 
semantics. Of course it is possible to implement inconsistent object semantics 
with proxies -- this is true of host objects in general (especially prior to 
ES5, but even in ES5 -- see ES5 8.6.2, the paragraphs toward the end -- and of 
course implementations may defy the standard, or simply be buggy or old).

Proxies are thus an in-language facility for implementing host objects. This is 
an evolutionary path toward cleaning up host objects in various DOM 
implementations. TC39 thinks this is important; it may save us from the worst 
of the browser DOMs (the IE DOM can claim that title, but all browsers have 
quirky host objects in my experience).

I also implemented the iterate trap, which is lazy, in preference to 
implementing the commented-out enumerate trap, which is eager and used only to 

Re: Day 2 meeting notes

2010-07-31 Thread Dmitry A. Soshnikov

On 31.07.2010 1:37, Brendan Eich wrote:

On Jul 30, 2010, at 1:38 PM, Dmitry A. Soshnikov wrote:

   

Another thing to mention regarding array comprehensions is /pattern matching/ 
(in less common, but related to JS, case -- /destructing assignment/). 
Currently, it's implemented in JS 1.7 in simple for/each-in loops:

for each ({a: x} in [{a: 10}, {a: 20}, {a: 30}]) {
  alert(x); // 10, 20, 30
}

Yes, it can be useful to pattern match {a: x} extracting a value of the a property into 
the x variable. Array comprehensions of JS 1.7 in contrast with a loop do not have such 
sugar:

let a = [x for each ({a: x} in [{a: 10}, {a: 20}, {a: 30}]) if (x  2)]; // 
SyntaxError
 

You don't need each to make that work in JS1.7:

js  let a = [x.a for each (x in [{a: 10}, {a: 20}, {a: 30}]) if (x.a  2)];
js  a
[10, 20, 30]

Notice that you can use each in JS1.7 after for (E4X was in JS1.6 and up).

But you are quite right that we did not allow the same left-hand sides of 'in' 
in comprehensions as we did in equivalent loops:

js  let a = []; for each ({a: x} in [{a: 10}, {a: 20}, {a: 30}]) if (x  2) 
a[a.length] = x; a
[10, 20, 30]

That is just a flaw in JS1.7, possibly even not a design flaw but an 
implementation bug (I honestly don't remember).

   


Yeah, I just mention exactly an element's structure filtering, not 
touching _real_ filtering within already /structure filtered/ elements. 
From the other hand, maybe current JS destructuring (but not 
irrefutable match) even better -- in respect that it's more flexible -- 
structure filtering can be moved to the if-filter section (i.e. 
technically it's easy to achieve, I just meant some sugar, but at the 
same time I thought, this sugar (irrefutable match) is not so flexible 
for JS):


// only first element will be in a array

let a = [x
  for each (x in [{a: 10, b: 20}, {a: 1, b: 20}, skip, {a: 30}])
if (
  // filtering needed structure first
  (typeof x == object)  (a in x)  (b in x) 
  // and then already real filters within needed structure elements
  x.a  1
)
];

It's more flexible, because lets (without exact structure filtering) get 
{a: x} from {a: 10, b: 20} and {a: 30}.



For Harmony, we do not propose to standardize |for each|. Instead, the 
iteration and array comprehensions proposals for Harmony (see the wiki) propose 
that programmers choose keys, values, items (properties), or other iteration 
protocols by saying what they mean more precisely on the right-hand side of 
'in':

for (k in keys(o)) ...
for (v in values(o)) ...
for ([k, v] in properties(o)) ... // Python's items

This seems better in TC39 members' views than adding ambiguous 'each' as a 
contextual keyword.


   


So, they (keys, values, properties) result iterators. Are the keys(o) is 
the same, but just more explicit version of a simple iteration over the 
`o' object?


for (k in o)  and for (k in keys(o))  -- are they the same (excluding 
implementation, e.g. lazy evaluation possibly or sort of, only the end 
result is interesting)?


If `keys`, `values` and `properties` simple functions are not global 
functions, does a user should always import them from basic iteration 
module (i.e. if you want this sugar -- then import, if not -- use old 
for-in over properties)? Or will they be imported automatically before 
evaluation every module/context? If the later, then they are 
(semantically) global functions.


Actually, for programmers familiar with iterators, the following case 
shouldn't cause ambiguity:


for (k in o) // default -- always over keys
for (k in keys(o)) // the same, explicitly mention keys

let value = values(o);
for (v in values) // over values, because a programmer see that he 
iterates over the special iterator object


etc. It seems convenient.

For not so familiar -- yeah, it may cause some ambiguities when we can't 
say exactly looking on just one line -- for (z in o) -- over what does 
it iterate (in case if `o' was set something else of course) -- keys, 
values, items? So the programmer should back and look what is `o' -- 
in contrast with `for each' or `for (values of object)', etc. additional 
syntax keywords.



Also using pattern matching, it's useful sometimes to filter needed values of 
an array in the pattern matching parameter itself, but not using filter section 
(actually, it's hard to use filter section to filter exactly values which are 
not of the needed structure). For example (code on Erlang with its list 
comprehensions):

List = [{1,2}, skip, {3,4}],

FilteredList = [X + Y || {X, Y}- List].

Result is: [3, 7]. Pattern matching filtered atom `skip' and took only {X, Y} 
structures (1st and 3rd elements in list) extracting values into the X and Y 
variables.

This is useful feature, I was needed it on practice. In contrast lists:map + 
lists:filter (that's desugared list comprehensions) cannot handle this case, 
because for the `skip' atom will be `bad match' error and we can't map a list 
the same elegant as with 

Re: Day 2 meeting notes

2010-07-31 Thread Dmitry A. Soshnikov

On 31.07.2010 15:45, Dmitry A. Soshnikov wrote:


for (k in o)  and for (k in keys(o))  -- are they the same (excluding 
implementation, e.g. lazy evaluation possibly or sort of, only the end 
result is interesting)?




Sorry, already have read later explanation in this thread.

Dmitry.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread felix

On 7/29/10 16:55, Oliver Hunt wrote:


On Jul 29, 2010, at 2:47 PM, Waldemar Horwat wrote:


Comprehensions:  To be useful, need to have a bunch of basic helpers
such as range(), properties(), values(), etc. with short names that
can be used to construct comprehensions.  These will be added to the
proposal.

Would like to be able to interleave for and if clauses:
[x*y for (x in range(...)) if (isprime(x)) for (y in range(x+1...)) if
(isprime(y))]


I keep seeing code like this, I simply don't see it as viable to have for (.. in 
...) sometimes enumerate property names, and some times enumerate keys, it seems 
like it could be both confusing and error prone.  esp. given the simplest example: [x for 
(value in [1,2,3])] you would not get the desired behaviour, unless in comprehensions 
for(in) behaves differently from everywhere else.

It seems far better to just define a distinct syntax for enumerating values of 
an object.


actionscript 3 has
  for (key in a) {}
  for each (val in a) {}
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Re: Day 2 meeting notes

2010-07-30 Thread Douglas Crockford

 On 11:59 AM, Oliver Hunt wrote:
I keep seeing code like this, I simply don't see it as viable to have 
for (.. in ...) sometimes enumerate property names, and some times 
enumerate keys, it seems like it could be both confusing and error 
prone. esp. given the simplest example: [x for (value in [1,2,3])] you 
would not get the desired behaviour, unless in comprehensions for(in) 
behaves differently from everywhere else.

It seems far better to just define a distinct syntax for enumerating values of 
an object.
I agree. We talked about swapping out the preposition, so for..in 
produces keys, and for..of or for..from  produces values.

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Dmitry A. Soshnikov

On 30.07.2010 23:06, felix wrote:

On 7/29/10 16:55, Oliver Hunt wrote:


On Jul 29, 2010, at 2:47 PM, Waldemar Horwat wrote:


Comprehensions:  To be useful, need to have a bunch of basic helpers
such as range(), properties(), values(), etc. with short names that
can be used to construct comprehensions.  These will be added to the
proposal.

Would like to be able to interleave for and if clauses:
[x*y for (x in range(...)) if (isprime(x)) for (y in range(x+1...)) if
(isprime(y))]


I keep seeing code like this, I simply don't see it as viable to have 
for (.. in ...) sometimes enumerate property names, and some times 
enumerate keys, it seems like it could be both confusing and error 
prone.  esp. given the simplest example: [x for (value in [1,2,3])] 
you would not get the desired behaviour, unless in comprehensions 
for(in) behaves differently from everywhere else.


It seems far better to just define a distinct syntax for enumerating 
values of an object.


actionscript 3 has
  for (key in a) {}
  for each (val in a) {}


Not only ActionScript, but JavaScript too (e.g. SpiderMonkey 1.7).

Another thing to mention regarding array comprehensions is /pattern 
matching/ (in less common, but related to JS, case -- /destructing 
assignment/). Currently, it's implemented in JS 1.7 in simple 
for/each-in loops:


for each ({a: x} in [{a: 10}, {a: 20}, {a: 30}]) {
  alert(x); // 10, 20, 30
}

Yes, it can be useful to pattern match {a: x} extracting a value of the 
a property into the x variable. Array comprehensions of JS 1.7 in 
contrast with a loop do not have such sugar:


let a = [x for each ({a: x} in [{a: 10}, {a: 20}, {a: 30}]) if (x  2)]; 
// SyntaxError

alert(a);

Also using pattern matching, it's useful sometimes to filter needed 
values of an array in the pattern matching parameter itself, but not 
using filter section (actually, it's hard to use filter section to 
filter exactly values which are not of the needed structure). For 
example (code on Erlang with its list comprehensions):


List = [{1,2}, skip, {3,4}],

FilteredList = [X + Y || {X, Y} - List].

Result is: [3, 7]. Pattern matching filtered atom `skip' and took only 
{X, Y} structures (1st and 3rd elements in list) extracting values into 
the X and Y variables.


This is useful feature, I was needed it on practice. In contrast 
lists:map + lists:filter (that's desugared list comprehensions) cannot 
handle this case, because for the `skip' atom will be `bad match' error 
and we can't map a list the same elegant as with list comprehension:


List = [{1,2}, skip, {3,4}],
lists:map(fun({X, Y}) - X + Y end, List).  % bad_match error for the 
second element - `skip' atom


Syntactically JavaScript has similar construction, but semantically 
result differs:


for each ({a: x, b: y} in [{a: 10, b: 20}, skip, {a: 30, b: 40}]) {
  alert(x, y); // 10, 20 | undefined, undefined | 30, 40
}

String skip isn't pattern matched, but the object is created with 
`undefined' values for x and y. And again for array comprehensions this 
shows SyntaxError (that, for consistency with for/each-in loop should not).


Dmitry.

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Brendan Eich
On Jul 30, 2010, at 12:06 PM, felix wrote:

 actionscript 3 has
  for (key in a) {}
  for each (val in a) {}

This is from ECMA-357, E4X, and it is in SpiderMonkey and Rhino too -- it's not 
original to AS3.

It's also something we agreed (crock too, IIRC) was too vague: each does not 
scream value, not key.

But beyond that, iteration in general is not necessarily visiting properties in 
an object, and then you have to choose an obscure keyword or preposition to 
choose value or key. Iteration is a stream of values, no properties needed at 
all.

In that light, and in light of Mathematics as well as Python and JS1.7+, it is 
hard to beat for ... in  For all elements in set, for all items in 
list, for all [key, value] pairs in dict, etc.

This might suggest using all, but that too is vague, and it also may suggest 
eagerness or completeness. But iteration is needed in JS precisely for laziness.

Infinite sequences or streams where the consumer decides when to stop asking 
for the next value are currently underserved use-cases. This point came up when 
reviewing

http://wiki.ecmascript.org/doku.php?id=harmony:proxies
 Waldemar raised objections against the current Proxy API to proxy objects with 
a large number of properties. The problematic traps are fix and enumerate. 
W.r.t enumerate, a proxy could return a proxy for an array. Additionally, 
enumerate should be modified as soon as there is a solid proposal for 
generators/iterators. Proxies for large objects could resist being fixed. This 
solution is satisfactory as long as no part of the spec depends on an object 
being non-extensible/sealed/frozen.
Of course this does not say what the syntax for a meta-programmable iteration 
construct should be, but laziness suggests all is not precisely on target.

/be___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Brendan Eich
On Jul 30, 2010, at 1:38 PM, Dmitry A. Soshnikov wrote:

 Another thing to mention regarding array comprehensions is /pattern matching/ 
 (in less common, but related to JS, case -- /destructing assignment/). 
 Currently, it's implemented in JS 1.7 in simple for/each-in loops:
 
 for each ({a: x} in [{a: 10}, {a: 20}, {a: 30}]) {
  alert(x); // 10, 20, 30
 }
 
 Yes, it can be useful to pattern match {a: x} extracting a value of the a 
 property into the x variable. Array comprehensions of JS 1.7 in contrast 
 with a loop do not have such sugar:
 
 let a = [x for each ({a: x} in [{a: 10}, {a: 20}, {a: 30}]) if (x  2)]; // 
 SyntaxError

You don't need each to make that work in JS1.7:

js let a = [x.a for each (x in [{a: 10}, {a: 20}, {a: 30}]) if (x.a  2)];
js a
[10, 20, 30]

Notice that you can use each in JS1.7 after for (E4X was in JS1.6 and up).

But you are quite right that we did not allow the same left-hand sides of 'in' 
in comprehensions as we did in equivalent loops:

js let a = []; for each ({a: x} in [{a: 10}, {a: 20}, {a: 30}]) if (x  2) 
a[a.length] = x; a
[10, 20, 30]

That is just a flaw in JS1.7, possibly even not a design flaw but an 
implementation bug (I honestly don't remember).

For Harmony, we do not propose to standardize |for each|. Instead, the 
iteration and array comprehensions proposals for Harmony (see the wiki) propose 
that programmers choose keys, values, items (properties), or other iteration 
protocols by saying what they mean more precisely on the right-hand side of 
'in':

for (k in keys(o)) ...
for (v in values(o)) ...
for ([k, v] in properties(o)) ... // Python's items

This seems better in TC39 members' views than adding ambiguous 'each' as a 
contextual keyword.


 Also using pattern matching, it's useful sometimes to filter needed values of 
 an array in the pattern matching parameter itself, but not using filter 
 section (actually, it's hard to use filter section to filter exactly values 
 which are not of the needed structure). For example (code on Erlang with its 
 list comprehensions):
 
 List = [{1,2}, skip, {3,4}],
 
 FilteredList = [X + Y || {X, Y} - List].
 
 Result is: [3, 7]. Pattern matching filtered atom `skip' and took only {X, Y} 
 structures (1st and 3rd elements in list) extracting values into the X and Y 
 variables.
 
 This is useful feature, I was needed it on practice. In contrast lists:map + 
 lists:filter (that's desugared list comprehensions) cannot handle this case, 
 because for the `skip' atom will be `bad match' error and we can't map a list 
 the same elegant as with list comprehension:
 
 List = [{1,2}, skip, {3,4}],
 lists:map(fun({X, Y}) - X + Y end, List).  % bad_match error for the second 
 element - `skip' atom
 
 Syntactically JavaScript has similar construction, but semantically result 
 differs:
 
 for each ({a: x, b: y} in [{a: 10, b: 20}, skip, {a: 30, b: 40}]) {
  alert(x, y); // 10, 20 | undefined, undefined | 30, 40
 }

Syntax aside, destructuring in JS is not irrefutable match. It is simply 
shorthand for assigning (and declaring) variables whose names are supplied in 
the value position in array and object initialisers, where the assigned 
values for these variables come from property values named by the keys in the 
corresponding key position. Failure in the sense of pulling undefined out of 
a non-existing property *is* an option:

js let [x, y] = {not_an_array: 42};
js x
js y

and of course if you dig deeper, you can get failure dereferencing undefined:

js let [x, [y, z]] = {nor_here: 99};
typein:20: TypeError: (void 0) is undefined

(SpiderMonkey uses (void 0) not undefined since prior to ES5, the global 
property named undefined was writable and could be spoofed.)


 String skip isn't pattern matched, but the object is created with 
 `undefined' values for x and y. And again for array comprehensions this shows 
 SyntaxError (that, for consistency with for/each-in loop should not).

I agree that some fairly common JS use-cases want irrefutable match. Dave 
Herman pointed out how the SpiderMonkey and Rhino extended catch syntax, 
guarded catches, is a kind of matching:

try {
   throw random_exception_generator();
} catch (e if typeof e == number) {
   ...
} catch (e if typeof e == string) {
   ...
} catch {
  // default case, if you forget it e will be rethrown for you
}

This was proposed for ES3 but not accepted. It has the advantage cited by the 
comment in the default catch clause.

Perhaps there's a generalization of such guards, which could re-use the 
initialiser-derived pattern syntax from destructuring, and which would provide 
irrefutable match as a primitive with good compositionality.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread felix

On 7/30/10 14:10, Brendan Eich wrote:

On Jul 30, 2010, at 12:06 PM, felix wrote:


actionscript 3 has
for (key in a) {}
for each (val in a) {}


This is from ECMA-357, E4X, and it is in SpiderMonkey and Rhino too --
it's not original to AS3.

It's also something we agreed (crock too, IIRC) was too vague: each
does not scream value, not key.


oh, right, forgot about e4x.


Of course this does not say what the syntax for a meta-programmable
iteration construct should be, but laziness suggests all is not
precisely on target.


so why not make it for each?  for-each iterates over a stream, and in 
the case of arrays the stream is the array values.


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread felix

On 7/30/10 14:37, Brendan Eich wrote:

For Harmony, we do not propose to standardize |for each|. Instead, the 
iteration and array comprehensions proposals for Harmony (see the wiki) propose 
that programmers choose keys, values, items (properties), or other iteration 
protocols by saying what they mean more precisely on the right-hand side of 
'in':

for (k in keys(o)) ...
for (v in values(o)) ...
for ([k, v] in properties(o)) ... // Python's items

This seems better in TC39 members' views than adding ambiguous 'each' as a 
contextual keyword.


I'm wary of that because this looks to me confusing:
   a = keys(o);
   for (k in a) ...

or is keys(o) special syntax that only works within a for() statement?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Brendan Eich
On Jul 30, 2010, at 2:37 PM, Brendan Eich wrote:

 For Harmony, we do not propose to standardize |for each|. Instead, the 
 iteration and array comprehensions proposals for Harmony (see the wiki) 
 propose that programmers choose keys, values, items (properties), or other 
 iteration protocols by saying what they mean more precisely on the right-hand 
 side of 'in':
 
 for (k in keys(o)) ...
 for (v in values(o)) ...
 for ([k, v] in properties(o)) ... // Python's items
 
 This seems better in TC39 members' views than adding ambiguous 'each' as a 
 contextual keyword.

In case it's unclear, these keys, values, etc. iterator factories are just 
functions. Of course their names would not be reserved identifiers, and they 
wouldn't be global functions. The reader should assume they've been imported 
from a standard module.

/be

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Brendan Eich
On Jul 30, 2010, at 2:43 PM, felix wrote:

 Of course this does not say what the syntax for a meta-programmable
 iteration construct should be, but laziness suggests all is not
 precisely on target.
 
 so why not make it for each?  for-each iterates over a stream, and in the 
 case of arrays the stream is the array values.

Reasons not to add each:

1. Avoid another contextual keyword (few implemented E4X).
2. Avoid confusion over what each means.
3. Even assuming we added each based on E4X, the objection that |for each (x 
in y)| loops would need to cope with y being a proxy that customizes 
value-iteration exists.

Point 3 is Waldemar's objection w.r.t. |for-in| becoming customizable (as it is 
in JS1.7 and Python). It applies equally to |for-each-in| given the E4X 
precedent of non-proxy object on right of 'in' being enumerated (iterated over 
its enumerable keys), and its enumerable keys' values returned.

One can bikeshed for days on all sorts of vague and wrongly general words such 
as each. Instead, focusing on the right side of in, providing an explicit 
iterator-factory call, seems strictly better.

/be


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Brendan Eich
On Jul 30, 2010, at 2:47 PM, felix wrote:

 On 7/30/10 14:37, Brendan Eich wrote:
 For Harmony, we do not propose to standardize |for each|. Instead, the 
 iteration and array comprehensions proposals for Harmony (see the wiki) 
 propose that programmers choose keys, values, items (properties), or other 
 iteration protocols by saying what they mean more precisely on the 
 right-hand side of 'in':
 
 for (k in keys(o)) ...
 for (v in values(o)) ...
 for ([k, v] in properties(o)) ... // Python's items
 
 This seems better in TC39 members' views than adding ambiguous 'each' as a 
 contextual keyword.
 
 I'm wary of that because this looks to me confusing:
   a = keys(o);
   for (k in a) ...

The confusion here seems to be assuming that |a| is an Array instance. It's 
not. It is an iterator, so you'll get the keys (property names) found in o -- 
you won't get 0, 1, ... a.length-1.

To avoid this confusion you can add new syntax (|for each| or whatever, doesn't 
matter). I've argued in recent posts that it is better from a global and 
long-term point of view to reform for-in after Python, than to condemn it and 
grow the language with new and generally more verbose, yet similar, syntax.


 or is keys(o) special syntax that only works within a for() statement?

No.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Oliver Hunt

On Jul 30, 2010, at 2:56 PM, Brendan Eich wrote:

 On Jul 30, 2010, at 2:47 PM, felix wrote:
 
 On 7/30/10 14:37, Brendan Eich wrote:
 For Harmony, we do not propose to standardize |for each|. Instead, the 
 iteration and array comprehensions proposals for Harmony (see the wiki) 
 propose that programmers choose keys, values, items (properties), or other 
 iteration protocols by saying what they mean more precisely on the 
 right-hand side of 'in':
 
 for (k in keys(o)) ...
 for (v in values(o)) ...
 for ([k, v] in properties(o)) ... // Python's items
 
 This seems better in TC39 members' views than adding ambiguous 'each' as a 
 contextual keyword.
 
 I'm wary of that because this looks to me confusing:
  a = keys(o);
  for (k in a) ...
 
 The confusion here seems to be assuming that |a| is an Array instance. It's 
 not. It is an iterator, so you'll get the keys (property names) found in o -- 
 you won't get 0, 1, ... a.length-1.
 
 To avoid this confusion you can add new syntax (|for each| or whatever, 
 doesn't matter). I've argued in recent posts that it is better from a global 
 and long-term point of view to reform for-in after Python, than to condemn it 
 and grow the language with new and generally more verbose, yet similar, 
 syntax.

It annoys me that this doesn't leave a convenient way to iterate arrays, for 
(... in someArray) will forever do the braindead thing.  If we look to pythonic 
behaviour we see that python's for..in syntax has always iterated arrays by 
value rather than index.  By overloading for(in) we are effectively saying that 
there will never be a simple way to iterate arrays by value directly, because 
no one can even extend the builtin array type be have a generator for iteration 
because doing so would be too fragile.

--Oliver

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Maciej Stachowiak

On Jul 30, 2010, at 2:53 PM, Brendan Eich wrote:

 On Jul 30, 2010, at 2:43 PM, felix wrote:
 
 Of course this does not say what the syntax for a meta-programmable
 iteration construct should be, but laziness suggests all is not
 precisely on target.
 
 so why not make it for each?  for-each iterates over a stream, and in the 
 case of arrays the stream is the array values.
 
 Reasons not to add each:
 
 1. Avoid another contextual keyword (few implemented E4X).
 2. Avoid confusion over what each means.
 3. Even assuming we added each based on E4X, the objection that |for each 
 (x in y)| loops would need to cope with y being a proxy that customizes 
 value-iteration exists.
 
 Point 3 is Waldemar's objection w.r.t. |for-in| becoming customizable (as it 
 is in JS1.7 and Python). It applies equally to |for-each-in| given the E4X 
 precedent of non-proxy object on right of 'in' being enumerated (iterated 
 over its enumerable keys), and its enumerable keys' values returned.
 
 One can bikeshed for days on all sorts of vague and wrongly general words 
 such as each. Instead, focusing on the right side of in, providing an 
 explicit iterator-factory call, seems strictly better.

I think that while for each ... in or for all ... in is a potentially 
confusing distinction vs. for ... in, it still seems less potentially 
confusing to me than having no distinction at all.

Another entry for the bikeshedding pile: for values ... in. That definitely 
screams values, not keys.

Regards,
Maciej

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Brendan Eich
On Jul 30, 2010, at 3:02 PM, Oliver Hunt wrote:

 On Jul 30, 2010, at 2:56 PM, Brendan Eich wrote:
 
 To avoid this confusion you can add new syntax (|for each| or whatever, 
 doesn't matter). I've argued in recent posts that it is better from a global 
 and long-term point of view to reform for-in after Python, than to condemn 
 it and grow the language with new and generally more verbose, yet similar, 
 syntax.
 
 It annoys me that this doesn't leave a convenient way to iterate arrays, for 
 (... in someArray) will forever do the braindead thing.

Me too, and I've seen people (myself included) make the mistake of writing

 for (i in [0,1,1,2,3,5,8,13]) ...

wanting the values not the keys.


  If we look to pythonic behaviour we see that python's for..in syntax has 
 always iterated arrays by value rather than index.

Indeed.


  By overloading for(in) we are effectively saying that there will never be a 
 simple way to iterate arrays by value directly, because no one can even 
 extend the builtin array type be have a generator for iteration because doing 
 so would be too fragile.

This never be a simple way is not true in JS1.7+:

js Array.prototype.__iterator__ = function () { for (let i = 0; i  
this.length; i++) yield this[i]; };
(function () {for (let i = 0; i  this.length; i++) {yield this[i];}})
js for (v in [3,4,5]) print(v)
3
4
5

The unstratified, ugly-named __iterator__ meta-method is the getter or factory 
for finding or creating an appropriate iterator. I use a generator, since it is 
the simplest way of writing such a factory.

With Harmony we stratify such meta-programming using proxies, so you can't use 
the prototype chain to find the iterate handler-trap -- you must directly 
reference a Proxy instance after 'in' in the for-in head.

Could we fix Harmony to iterate values not keys for Arrays, by fiat, and say 
opt-in versioning, pay this migration tax, it is worth it? I don't think so, 
but we can discuss.

Perhaps there's a modular way to allow one-time, explicit opting into a mode 
where for-in iterates array values, not keys. The obvious criticism is modes 
are bad, don't add more knobs to the language.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Oliver Hunt

On Jul 30, 2010, at 3:35 PM, Brendan Eich wrote:

 On Jul 30, 2010, at 3:02 PM, Oliver Hunt wrote:
 
 On Jul 30, 2010, at 2:56 PM, Brendan Eich wrote:
 
 To avoid this confusion you can add new syntax (|for each| or whatever, 
 doesn't matter). I've argued in recent posts that it is better from a 
 global and long-term point of view to reform for-in after Python, than to 
 condemn it and grow the language with new and generally more verbose, yet 
 similar, syntax.
 
 It annoys me that this doesn't leave a convenient way to iterate arrays, for 
 (... in someArray) will forever do the braindead thing.
 
 Me too, and I've seen people (myself included) make the mistake of writing
 
 for (i in [0,1,1,2,3,5,8,13]) ...
 
 wanting the values not the keys.
 
 
 If we look to pythonic behaviour we see that python's for..in syntax has 
 always iterated arrays by value rather than index.
 
 Indeed.
 
 
 By overloading for(in) we are effectively saying that there will never be a 
 simple way to iterate arrays by value directly, because no one can even 
 extend the builtin array type be have a generator for iteration because 
 doing so would be too fragile.
 
 This never be a simple way is not true in JS1.7+:
 
 js Array.prototype.__iterator__ = function () { for (let i = 0; i  
 this.length; i++) yield this[i]; };
 (function () {for (let i = 0; i  this.length; i++) {yield this[i];}})
 js for (v in [3,4,5]) print(v)
 3
 4
 5
 
 The unstratified, ugly-named __iterator__ meta-method is the getter or 
 factory for finding or creating an appropriate iterator. I use a generator, 
 since it is the simplest way of writing such a factory.

I recognised that was possible -- the problem i was saying is that you can't do 
that due to it polluting the global array prototype in away that effects 
language semantics

I'll need to read the spec behaviour more carefully before i'm willing to go 
too deeply down that rabbit hole though.

--Oliver

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Faisal Vali
 -- Forwarded message --
 From: Douglas Crockford doug...@crockford.com
 To: Oliver Hunt oli...@apple.com
 Date: Fri, 30 Jul 2010 13:09:33 -0700
 Subject: Re: Re: Day 2 meeting notes
  On 11:59 AM, Oliver Hunt wrote:

 I keep seeing code like this, I simply don't see it as viable to have for 
 (.. in ...) sometimes enumerate property names, and some times enumerate 
 keys, it seems like it could be both confusing and error prone. esp. given 
 the simplest example: [x for (value in [1,2,3])] you would not get the 
 desired behaviour, unless in comprehensions for(in) behaves differently from 
 everywhere else.
 It seems far better to just define a distinct syntax for enumerating values 
 of an object.

 I agree. We talked about swapping out the preposition, so for..in produces 
 keys, and for..of or for..from  produces values.


What about using 'for .. vin' - i.e. value-in for value enumeration

And adding a redundant 'for .. kin' - i.e. key-in for key enumeration
(for those who prefer explicitness over using the ambiguously named
'for .. in' which would retain its original key iteration behavior)?

Or are 'vin' and 'kin' too nonsensical to gain any acceptance?

regards,
Faisal Vali
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Brendan Eich
On Jul 30, 2010, at 3:49 PM, Oliver Hunt wrote:

 By overloading for(in) we are effectively saying that there will never be a 
 simple way to iterate arrays by value directly, because no one can even 
 extend the builtin array type be have a generator for iteration because 
 doing so would be too fragile.
 
 This never be a simple way is not true in JS1.7+:
 
 js Array.prototype.__iterator__ = function () { for (let i = 0; i  
 this.length; i++) yield this[i]; };
 (function () {for (let i = 0; i  this.length; i++) {yield this[i];}})
 js for (v in [3,4,5]) print(v)
 3
 4
 5
 
 The unstratified, ugly-named __iterator__ meta-method is the getter or 
 factory for finding or creating an appropriate iterator. I use a generator, 
 since it is the simplest way of writing such a factory.
 
 I recognised that was possible -- the problem i was saying is that you can't 
 do that due to it polluting the global array prototype in away that effects 
 language semantics

Yeah, and it was hardly a simple way as I wrote it, but these little 
headaches are fixable:

js Object.defineProperty(Array.prototype, '__iterator__', {value: function () 
{ for (let i = 0; i  this.length; i++) yield this[i]; }});
[]
js for (v in [3,4,5])print(v)
3
4
5

And put the Object.defineProperty call into some init-time code in JQuery ;-).

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Brendan Eich

On Jul 30, 2010, at 3:53 PM, Faisal Vali wrote:

 -- Forwarded message --
 From: Douglas Crockford doug...@crockford.com
 To: Oliver Hunt oli...@apple.com
 Date: Fri, 30 Jul 2010 13:09:33 -0700
 Subject: Re: Re: Day 2 meeting notes
  On 11:59 AM, Oliver Hunt wrote:
 
 I keep seeing code like this, I simply don't see it as viable to have for 
 (.. in ...) sometimes enumerate property names, and some times enumerate 
 keys, it seems like it could be both confusing and error prone. esp. given 
 the simplest example: [x for (value in [1,2,3])] you would not get the 
 desired behaviour, unless in comprehensions for(in) behaves differently 
 from everywhere else.
 It seems far better to just define a distinct syntax for enumerating values 
 of an object.
 
 I agree. We talked about swapping out the preposition, so for..in produces 
 keys, and for..of or for..from  produces values.
 
 
 What about using 'for .. vin' - i.e. value-in for value enumeration
 
 And adding a redundant 'for .. kin' - i.e. key-in for key enumeration
 (for those who prefer explicitness over using the ambiguously named
 'for .. in' which would retain its original key iteration behavior)?
 
 Or are 'vin' and 'kin' too nonsensical to gain any acceptance?

Yes, they're too nonsensical. Sorry, but you asked (and answered ;-).

Let's avoid bikeshedding just yet. It's really not going to resolve any 
usability concerns, and the prior question of whether we should design for the 
longer term and the bigger picture, rather than just adding more syntax to 
mitigate the concern about old for-in code running an iterator unexpectedly, 
should be addressed first (if possible).

There is a usability problem, I think everyone agrees. It has several aspects:

1. for-in is underspecified and not interoperably implemented, yet it is useful 
and used in spite of this -- its syntax is sweet, and (at least in small-world 
/ my own code settings), reliable if used with some care.

2. for-in on arrays enumerates keys, just as with other objects, but this is 
often not what users want or expect.

3. for-in walks up the prototype chain. This is independent of 1 and 2, in the 
sense that even if we specify enumeration interoperably and engines do it, and 
even with ES5's Object.defineProperty to control enumerability, often enough 
users just Do Not Want.

With Harmony building on ES5 strict mode by default and inevitably adding new 
syntax, therefore requiring opt-in versioning, we hope to fix at least (1), 
which may impose a migration tax on some web content that works cross-browser 
today. Here's some detail on how:

We experimented in Firefox 4 nightlies with a pure snapshot model, where at 
the start of the for-in loop, the direct object and its prototypes are 
enumerated, with shadowing, and the property names saved. We left out 
suppression of names deleted after the loop starts but before the loop would 
visit the name in the snapshot -- we let those names be visited. This broke too 
much, so we added delete suppression, but only for the direct object. This 
seems web-compatbile enough, pending new negative results.

TC39 favored the snapshot model at the May meeting. This week's meeting was 
where we Mozillans relayed the need for delete suppression, at least for the 
direct object. The use-case is the iterate a worklist one, but not with 
adding to the worklist, only deleting. It's not formally nice, but it is done 
(e.g. event listeners in library-created listener arrays or maps). We do not 
yet propose to standardize snapshot-with-direct-object-only-delete-suppression, 
BTW.

I suspect we can't afford the migration tax imposed by fixing (2) and (3) 
above, especially (2). It's hard to know without running the experiment at 
scale -- and then it's hard to change course.

Nevertheless, it is conceivable that one day, for-in will be significantly more 
usable under a future Edition.

I believe that making for-in meta-programmable increases the odds of that day 
arriving, without in practice creating proxy vs. non-proxy enumeration 
confusion, because it lets JS authors and not just TC39 (with a few ugly new 
and hardcoded contextual keywords) add their good ideas and run local 
experiments, using iterators provided in the future Edition or by their own 
libraries.

This worked for Python. Why not for JS?

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread Dean Landolt
On Sat, Jul 31, 2010 at 12:06 AM, felix feli...@gmail.com wrote:

 On 7/30/10 14:56, Brendan Eich wrote:

 On Jul 30, 2010, at 2:47 PM, felix wrote:

  On 7/30/10 14:37, Brendan Eich wrote:

 For Harmony, we do not propose to standardize |for each|. Instead, the
 iteration and array comprehensions proposals for Harmony (see the wiki)
 propose that programmers choose keys, values, items (properties), or other
 iteration protocols by saying what they mean more precisely on the
 right-hand side of 'in':

 for (k in keys(o)) ...
 for (v in values(o)) ...
 for ([k, v] in properties(o)) ... // Python's items

 This seems better in TC39 members' views than adding ambiguous 'each' as
 a contextual keyword.


 I'm wary of that because this looks to me confusing:
   a = keys(o);
   for (k in a) ...


 The confusion here seems to be assuming that |a| is an Array instance.
 It's not. It is an iterator, so you'll get the keys (property names) found
 in o -- you won't get 0, 1, ... a.length-1.

 To avoid this confusion you can add new syntax (|for each| or whatever,
 doesn't matter). I've argued in recent posts that it is better from a global
 and long-term point of view to reform for-in after Python, than to condemn
 it and grow the language with new and generally more verbose, yet similar,
 syntax.


 I should have used a letter other than 'a'.  my expectation from current
 javascript is that 'a' is an object, and that 'for (k in a)' will iterate
 over the object's properties.


That's a fair assumption given the current state of the language, but
assumptions will change with time. Perhaps if you named a something like
aIter (wow, this example makes for a good argument for the snakecase
a_iter), you're expectations would be re-framed.

I think the common usage pattern will be using these iteration protocols at
the point of consumption, as with the examples Brendan's given -- and in
this case they're effectively anonymous and naming is a non-issue. You could
expect functions like keys(a), values(a) -- or whatever protocol functions
your library-of-choice provides -- to do *just *what they say. In this light
I don't believe an iterator's for..in behavior is surprising at all, even w/
collective our es3 baggage.



 it seems odd to me that if 'a' is an iterator, it will iterate over the
 iterator's value stream instead of the iterator's properties, unless you
 define the two to be identical, which would be strange.  eg, if you have an
 input stream iterator f, would f.hasOwnProperty('bacon') work or not?


But they're different objects entirely. If a's a values iterator it's not
iterating over it's *own* value stream -- it's iterating over some other
object's value stream. Thus, f.hasOwnProperty('bacon') shouldn't work
(unless you've bacon'd your iterator, of course, or done some magic with
proxy objects). So if f is iterating over an object's value stream then you
have a reference to the underlying object if you want to do anything like
hasOwnProperty.


 yes, I'd like generalized iterators like python, so this is not really an
 argument.


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-30 Thread felix

On 7/30/10 21:33, Dean Landolt wrote:



On Sat, Jul 31, 2010 at 12:06 AM, felix feli...@gmail.com
mailto:feli...@gmail.com wrote:

On 7/30/10 14:56, Brendan Eich wrote:

On Jul 30, 2010, at 2:47 PM, felix wrote:

On 7/30/10 14:37, Brendan Eich wrote:

For Harmony, we do not propose to standardize |for
each|. Instead, the iteration and array comprehensions
proposals for Harmony (see the wiki) propose that
programmers choose keys, values, items (properties), or
other iteration protocols by saying what they mean more
precisely on the right-hand side of 'in':

for (k in keys(o)) ...
for (v in values(o)) ...
for ([k, v] in properties(o)) ... // Python's items

This seems better in TC39 members' views than adding
ambiguous 'each' as a contextual keyword.


I'm wary of that because this looks to me confusing:
   a = keys(o);
   for (k in a) ...


The confusion here seems to be assuming that |a| is an Array
instance. It's not. It is an iterator, so you'll get the keys
(property names) found in o -- you won't get 0, 1, ... a.length-1.

To avoid this confusion you can add new syntax (|for each| or
whatever, doesn't matter). I've argued in recent posts that it
is better from a global and long-term point of view to reform
for-in after Python, than to condemn it and grow the language
with new and generally more verbose, yet similar, syntax.


I should have used a letter other than 'a'.  my expectation from
current javascript is that 'a' is an object, and that 'for (k in a)'
will iterate over the object's properties.


That's a fair assumption given the current state of the language, but
assumptions will change with time. Perhaps if you named a something
like aIter (wow, this example makes for a good argument for the
snakecase a_iter), you're expectations would be re-framed.

I think the common usage pattern will be using these iteration protocols
at the point of consumption, as with the examples Brendan's given -- and
in this case they're effectively anonymous and naming is a non-issue.
You could expect functions like keys(a), values(a) -- or whatever
protocol functions your library-of-choice provides -- to do /just /what
they say. In this light I don't believe an iterator's for..in behavior
is surprising at all, even w/ collective our es3 baggage.


it seems odd to me that if 'a' is an iterator, it will iterate over
the iterator's value stream instead of the iterator's properties,
unless you define the two to be identical, which would be strange.
  eg, if you have an input stream iterator f, would
f.hasOwnProperty('bacon') work or not?


But they're different objects entirely. If a's a values iterator it's
not iterating over it's /own/ value stream -- it's iterating over some
other object's value stream. Thus, f.hasOwnProperty('bacon') shouldn't
work (unless you've bacon'd your iterator, of course, or done some magic
with proxy objects). So if f is iterating over an object's value stream
then you have a reference to the underlying object if you want to do
anything like hasOwnProperty.


but that breaks functions like

function shallowCopy(o) {
  var p = {};
  for (var k in o) {
if (o.hasOwnProperty(k)) {
  p[k] = o[k];
}
  }
  return p;
}

now I have to add a test to that function for the unexpected case that o 
is an infinite iterator and the for..in loop goes forever instead of 
enumerating some finite property list.  that's just one example.  I 
expect that if iteration uses the existing for..in syntax, there will be 
many similar bits of code that will need to be modified to treat 
iterators as a special case.

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-29 Thread Oliver Hunt

On Jul 29, 2010, at 2:47 PM, Waldemar Horwat wrote:

 Comprehensions:  To be useful, need to have a bunch of basic helpers
 such as range(), properties(), values(), etc. with short names that
 can be used to construct comprehensions.  These will be added to the
 proposal.
 
 Would like to be able to interleave for and if clauses:
 [x*y for (x in range(...)) if (isprime(x)) for (y in range(x+1...)) if
 (isprime(y))]

I keep seeing code like this, I simply don't see it as viable to have for (.. 
in ...) sometimes enumerate property names, and some times enumerate keys, it 
seems like it could be both confusing and error prone.  esp. given the simplest 
example: [x for (value in [1,2,3])] you would not get the desired behaviour, 
unless in comprehensions for(in) behaves differently from everywhere else.

It seems far better to just define a distinct syntax for enumerating values of 
an object.

--Oliver

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Day 2 meeting notes

2010-07-29 Thread Brendan Eich
On Jul 29, 2010, at 4:55 PM, Oliver Hunt wrote:

 On Jul 29, 2010, at 2:47 PM, Waldemar Horwat wrote:
 
 Comprehensions:  To be useful, need to have a bunch of basic helpers
 such as range(), properties(), values(), etc. with short names that
 can be used to construct comprehensions.  These will be added to the
 proposal.
 
 Would like to be able to interleave for and if clauses:
 [x*y for (x in range(...)) if (isprime(x)) for (y in range(x+1...)) if
 (isprime(y))]
 
 I keep seeing code like this, I simply don't see it as viable to have for 
 (.. in ...) sometimes enumerate property names, and some times enumerate 
 keys, it seems like it could be both confusing and error prone.  esp. given 
 the simplest example: [x for (value in [1,2,3])] you would not get the 
 desired behaviour, unless in comprehensions for(in) behaves differently from 
 everywhere else.
 
 It seems far better to just define a distinct syntax for enumerating values 
 of an object.

This, if I understand correctly, is Waldemar's position as well.

On the other side both Python and JS1.7 and up in SpiderMonkey and Rhino make 
for-in meta-programmable. Python however makes sequence types by fiat iterate 
values, not keys, where sequence type includes list, which is []-bracketed like 
JS array initialisers.

The counter-argument is that the language has coveted syntax, for-in, which has 
broken semantics, and rather than essentially abandon it, we should *reform* 
it. To the extent that JS1.7+ is meaningful, I argue we have done so without 
user confusion. Yes, users wish arrays were iterated by for-in returning 
values, not keys, but you can say

for (i in values(a))

if you need to be sure. Likewise, if you must have property names,

for (k in keys(o))

for any object o will guarantee keys, not values, and not Fibonacci numbers.

The bottom line is that adding new syntax for custom iteration is missing the 
forest for the trees, arguing about how one more tree is safer and less 
confusing. In reality, the forest needs to stay small, and reform efforts can 
result in users understanding how to harvest the trees that we have, instead of 
having to understand and make good use of yet more trees.

/be

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss