Paren-Free (was: Re: Nov 18 notes)

2010-11-24 Thread Brendan Eich
http://brendaneich.com/2010/11/paren-free/

Fasten your seatbelts, it's going to be a bumpy night!

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


Re: Nov 18 notes

2010-11-24 Thread Tom Van Cutsem
I'd like to contribute what I think are three not-yet-voiced arguments to
this discussion:

1) Iterators != Collections
First, let me briefly restate what I preceive to be the main point of
contention: if we overload for-in, then client code that previously executed
for (x in obj) with obj being a regular object, and now finds itself in
Harmony-land where obj _is changed to_ an iterator, then for (x in obj)
may confuse the client, if the iterator produces non-string values.

Coming back to my point that regular objects don't just become iterator
objects overnight: it was not yet emphasized that in Dave's iterators API,
iterators are essentially considered as proxies for collections, usually
even constructed for one-off iteration use only. That is: the original
collection object itself is _not_ iterable, and that means that clients that
hold on to just the collection object can never become for-in-confused.

I feel that this tremendously reduces the risk of confusion, even though it
is still possible, and I have no empirical evidence to back this up.
However, reasoning by analogy: in pre 1.5 Java, one also asked a Collection
for an Iterator, then iterated using the Iterator, not the original
Collection. Of course, Java's static type system virtually rules out all
confusion since Iterator is not a subtype of Collection, but I would argue
that in this case, it was the _idiom_ more than the type system that avoided
confusion. Java programmers didn't get confused because it was idiomatic to
write: for (Iterator it = coll.iterator(); it.hasNext(); ) { ... it.next()
... }

In Harmony, as Dave has shown, it would be idiomatic to use iterators as
follows: for (var x in coll.iterator()) { ... }
Note: if a harmony programmer would, in a stroke of forgetfulness, forget
the .iterator() part, he'll get _the usual_ for-in enumeration behavior
for 'coll', since 'coll' is a normal collection object, not an iterator. Of
course, if the programmer meant to do iteration, this is a bug. But, more
importantly, if the programmer wasn't forgetful and he meant what he wrote
(i.e. enumerate the keys of the collection object), it'll do the right
thing.

If this is the idiom around which Harmony iterators are based, I would find
it unlikely (drawing from my experience with Java Iterators) that Harmony
programmers will start passing out references to coll.iterator() to clients
where they meant to pass 'coll'. I would only expect to see .iterator() in
or close to a for-in loop that immediately 'uses up' the iterator.

2) Avoid Iterators that pretend to be Collections
Now, in light of the above, one reservation I have about Iterators is the
API method called Iterator.for(coll), which creates and returns an iterator
that is _also_ a forwarding proxy to coll. This method gives an incentive to
users to pass this proxy where they could have also passed 'coll' to a
client. I think this is a mistake. Iterators should be distinct from
collections, as in Java. If iterators are indeed substitutable for
collection objects, then the chance of confusing clients becomes much
greater than it should be, effectively undermining argument 1)

3) Who is to blame for client confusion
Andreas, in the thread on guard syntax, observed that there is a very thin
line between a proxy enumerating duplicate/nonsensical keys (which is
possible using just the enumerate() trap, and perhaps even necessary to
emulate quirky host objects) and producing arbitrary values. Clients may get
confused either way.

It seems to me that we attribute different weights to these confusions
based on the perceived use of proxies. Why is this? Here's my take on it:

- proxies that use enumerate() to generate faux and/or duplicate keys are
considered by us to somehow abuse the trap. We cannot prevent anyone from
writing bad proxies, but we also don't expect code that does this to be
idiomatic, or part of a popular library. Hence, even though these proxies
may _deliberately_ confuse client code, we expect the consequences to be
contained. It's obvious who to blame for the confusion in this case.

- proxies that use iterate() to generate streams of arbitrary values are
considered a legitimate use case. Under the hypothesis that
strawman:iterators would become part of the language, it is our expectation
that such proxies _will_ become widespread. When they do, client code that
previously executed for (x in obj) might now find obj bound to an iterator
and get confused. Hence, even though it wasn't the intention of the iterator
proxy to confuse the client, the confusion happened anyway. This is
considered more problematic, because it's hard to figure out who to blame.
Both client and proxy meant to cooperate, but failed.

In short:
- Idiomatic use of iterators should prevent client code confusion in the
common case.
- Objects don't become iterators overnight. When porting ES5 code to
Harmony, I would expect ES5 objects used as collections to now get an
iterator() method that returns a 

Re: Nov 18 notes

2010-11-23 Thread Maciej Stachowiak

On Nov 22, 2010, at 11:35 PM, Brendan Eich wrote:

 On Nov 22, 2010, at 11:19 PM, Maciej Stachowiak wrote:
 
 Probably we need to take our time and not rush into a meta-programming-here 
 syntax variant of for-in. I'll not propose anything better right now.
 
 If the colon is less future-compatible than we like, why not:
 
 foreach (var i in x)
 
 All the new words are not reserved, so they could begin a function call 
 expression in extant code:
 
 hi = there
 foreach (i in x)
  print(i)
 
 means
 
 hi = there; foreach(i in x); print(i);
 
 today. Same if you s/foreach/iterate/ or any non-reserved identifier. 
 Wherefore Allen's co-opting of enum (plus with, a decent preposition given 
 enum but 8 chars in two keywords hurt kittens everywhere).

One possibility is to add a space as apparently a few other languages do:

for each (var i in x)

Should be unambiguously parsable and easy to understand.

 
 Anyway, the bikeshed is secondary. We need to agree on what meta-programmable 
 for-in means with the enumerate trap (specified by the wiki pages on 
 harmony:proxies), how that changes with the optional iterate trap 
 (strawman:iterators), and when it might matter (for all for-in loops, or only 
 those in Harmony code?).

Fair enough. Another important question is whether for..in should continue to 
guarantee that all values enumerated would be strings. Preserving that 
guarantee clearly makes for..in useless for the strawman:iterators purpose, but 
not for the harmony:proxies enumeration trap (and thus iterators would need new 
syntax to be usable).  Breaking the guarantee may cause problems for existing 
code. Breaking the guarantee only in Harmony mode creates additional migration 
tax. Thus, iterators create a potential motive for new syntax that the proxy 
enumeration trap does not. 

Given this, it is useful to identify candidate syntax that doesn't have 
perceived showstopper problems, so that we can evaluate the tradeoffs among the 
three prongs of the trilemma.

(As an even more concrete previously mentioned example, a new syntax allows 
sane defaults for arrays without breaking compatibility for the existing 
construct.)

Regards,
Maciej

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


Re: Nov 18 notes

2010-11-23 Thread P T Withington
On 2010-11-22, at 02:37, David Herman wrote:

 if we allowed for-in to be overloaded, I would tell people that they should 
 deprecate the legacy for-in and replace it with an explicit iterator such as:
 
for (x in keys(obj))

I have learned a mnemonic for for-in: that it is iterating using the `in` 
operator.  You propose that I unlearn that?  Or in your new hypothetical world 
does the `in` operator also get overloaded?

Ramdom thought: Can I use destructuring in for-in?

  for ({key:value} in enumerable)

  for ([value] in iterable)


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


Re: Nov 18 notes

2010-11-23 Thread Brendan Eich
On Nov 23, 2010, at 12:11 AM, Maciej Stachowiak wrote:

 One possibility is to add a space as apparently a few other languages do:
 
 for each (var i in x)
 
 Should be unambiguously parsable and easy to understand.

This is what ECMA-357, E4X, does, and it indeed iterates values not keys. The 
obvious criticism is that nothing except (dubious) history says for-in == keys 
while for-each-in == values. Other symmetries break down:

  for (i in o) assert(i in o)

lacks this parallel construct:

  for each (v in o) assert(o[what-was-v's-name-again?] === v)

JS1.7 allowed key-value destructuring

  for ([k, v] in o) assert(o[k] === v) // assume idemptotent has/get

but this broke a different symmetry:

  for ([s, v, o] in tripledb) ...

which wants other destructuring patterns to destructure the value returned by 
the iterator. Making the two-element-array destructuring pattern mean key-value 
destructuring frustrates people who want to iterate over a pairdb. So we fixed 
this in JS1.8, and dherman's iterator proposal has

  for (k in keys(o)) ...
  for (v in values(o)) ...
  for ([k, v] in properties(o)) ...

EIBTI once again.


 Anyway, the bikeshed is secondary. We need to agree on what 
 meta-programmable for-in means with the enumerate trap (specified by the 
 wiki pages on harmony:proxies), how that changes with the optional iterate 
 trap (strawman:iterators), and when it might matter (for all for-in loops, 
 or only those in Harmony code?).
 
 Fair enough. Another important question is whether for..in should continue to 
 guarantee that all values enumerated would be strings. Preserving that 
 guarantee clearly makes for..in useless for the strawman:iterators purpose,

Not quite, as Andreas already argued and (I see, reading ahead) reiterates with 
dherman adding emphasis.

Stringifying is not good for iterating arbitrary values, in particular property 
values or key-value pairs, of course. But if you insist (I don't) that for-in 
always stringify, forever, there are still lazy use-cases for the proposed 
iterate trap.


 but not for the harmony:proxies enumeration trap (and thus iterators would 
 need new syntax to be usable).  Breaking the guarantee may cause problems for 
 existing code. Breaking the guarantee only in Harmony mode creates additional 
 migration tax. Thus, iterators create a potential motive for new syntax that 
 the proxy enumeration trap does not. 

We're going in circles. Clearly, we could add new syntax. It's also conceivable 
that we could extend for-in. Trade-offs abound and data on usability hazards is 
absent in our experience (JS1.7 and up).


 Given this, it is useful to identify candidate syntax that doesn't have 
 perceived showstopper problems, so that we can evaluate the tradeoffs among 
 the three prongs of the trilemma.

It's a problem if showstopper criteria are not shared in a committee. Then 
anyone can stop the show based on divergent principles or unarticulated beliefs.

It therefore seems more important to achieve consensus on principles, and less 
important to force new syntax as a compromise that may be founded on bad 
committee game theory.


 (As an even more concrete previously mentioned example, a new syntax allows 
 sane defaults for arrays without breaking compatibility for the existing 
 construct.)

Mozilla-specific JS hackers do use

  for each (v in a) ...

to iterate values in an array |a|. This is better than

  for (i in a) { v = a[i]; ... }

but it's not so much better that TC39 members are happy to adopt for-each-in 
from ECMA-357. Maybe we will, in the end. It is overlong and each is 
redundant or ambiguous (take your pick), but at this point it beats the rushed 
for-: ugliness of last week.

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


Re: Nov 18 notes

2010-11-23 Thread Brendan Eich
On Nov 23, 2010, at 5:19 AM, P T Withington wrote:

 On 2010-11-22, at 02:37, David Herman wrote:
 
 if we allowed for-in to be overloaded, I would tell people that they should 
 deprecate the legacy for-in and replace it with an explicit iterator such as:
 
   for (x in keys(obj))
 
 I have learned a mnemonic for for-in: that it is iterating using the `in` 
 operator.  You propose that I unlearn that?  Or in your new hypothetical 
 world does the `in` operator also get overloaded?

Excellent question. One (Java extension language) answer:

http://www.cs.cornell.edu/Projects/jmatch/

Python allows unstratified meta-programming of both its for-in 
loop/comprehension syntax *and* its |in| operator.

Harmony Proxies allow meta-programming of |in| already, via the |has| trap. So 
the answer to your quesiton does the `in` operator also get overloaded? is 
Yes, but you have to write two traps, iterate and has.


 Ramdom thought: Can I use destructuring in for-in?
 
  for ({key:value} in enumerable)
 
  for ([value] in iterable)

Absolutely. Destructuring (separate proposal but composes well) applies to all 
LHS and binding forms.

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


Re: Nov 18 notes

2010-11-23 Thread Brendan Eich
On Nov 23, 2010, at 11:12 AM, Brendan Eich wrote:

 Given this, it is useful to identify candidate syntax that doesn't have 
 perceived showstopper problems, so that we can evaluate the tradeoffs among 
 the three prongs of the trilemma.
 
 It's a problem if showstopper criteria are not shared in a committee. Then 
 anyone can stop the show based on divergent principles or unarticulated 
 beliefs.
 
 It therefore seems more important to achieve consensus on principles, and 
 less important to force new syntax as a compromise that may be founded on bad 
 committee game theory.

The principle could be refined from Dave's restatement of Allen's (1a):

1a'. If existing syntax is given new semantics, it should extend the existing 
semantics conservatively. Otherwise, the new semantics should get new syntax.

But conservatively needs defining.

I think rather than try to nail down an abstract principle, we should look at 
the particular things in themselves. Tom's post did this:

I think that's a key point worth re-iterating: iterators and regular objects 
are sufficiently distinct so that there's no risk of automatically converting 
one into the other. There is only a risk to existing client-code if a Harmony 
programmer changes a normal object into an iterator. But at that point the 
programmer knows he's making a non-upwards-compatible change and clients should 
be changed accordingly. I don't see how the for-in case differs in this 
respect, fundamentally, from say, renaming a method.

[https://mail.mozilla.org/pipermail/es-discuss/2010-November/012208.html]

This is an argument about APIs. If an object exposed by an API, say returned 
from an API function, was a plain old object with keys to enumerate, but now 
(with Harmony implementations targeted) returns a proxy with an iterate trap, 
*and* the iterator returns non-strings non-keys (but key is ill-defined if not 
string), then client code *could* break.

But this is an intentional API change. It is analogous to renaming a method, 
and plausibly, object detection if not renaming would be used to deal with 
downrev clients.

What about unintended consequences? An accidental proxy leak from Harmony code 
to pre-Harmony code is possible. This is why I raised the idea of runtime 
semantics under Harmony opt-in being required to meta-program for-in. The same 
opt-in is required to remove the global object from the scope chain in favor of 
a lexical top frame.

We can (and have!) argue about limits on migration taxation, implementor 
burdens, etc. But as ES5 strict changed runtime semantics, it seems Harmony 
will too (lexical scope). So it is not absolutely inconceivable, or even 
obviously wrong, that for-in might become metaprogrammable based on its 
static code in Harmony property.


 (As an even more concrete previously mentioned example, a new syntax allows 
 sane defaults for arrays without breaking compatibility for the existing 
 construct.)
 
 Mozilla-specific JS hackers do use
 
  for each (v in a) ...
 
 to iterate values in an array |a|. This is better than
 
  for (i in a) { v = a[i]; ... }
 
 but it's not so much better that TC39 members are happy to adopt for-each-in 
 from ECMA-357. Maybe we will, in the end. It is overlong and each is 
 redundant or ambiguous (take your pick), but at this point it beats the 
 rushed for-: ugliness of last week.

Lest anyone think I'm throwing in the towel -- I'm not. We need better 
principles and detailed arguments justifying them or we won't have lasting and 
sound consensus to do much of anything with the language.

Proxies moved to harmony:proposals status because they were designed carefully, 
very well specified, and prototype implemented (and the prototyping was 
essential to completing the spec and getting the design right). On one point of 
contention in the July meeting, I urged TC39 to let the champions of the 
proposal (Mark and Tom), decide what to do.

I'd like to continue this champion-decides approach. Committees are terrible at 
designing, specifying, and implementing. It would be much better if we had 
multiple Proxy implementations (one for v8 is on github, Tom noted recently: 
https://github.com/brickysam26/node-proxy), including the iterate trap as 
proposed, and then some early adopters using proxies and beating on the 
iteration protocol.

At that point we would have more information on the usability issues. In the 
mean time, we can try to refine our principles based on concrete analysis. Just 
making abstract never do X rules won't cut it.

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


Re: Nov 18 notes

2010-11-23 Thread P T Withington
On 2010-11-23, at 14:14, Brendan Eich wrote:

 On Nov 23, 2010, at 5:19 AM, P T Withington wrote:
 
 On 2010-11-22, at 02:37, David Herman wrote:
 
 if we allowed for-in to be overloaded, I would tell people that they should 
 deprecate the legacy for-in and replace it with an explicit iterator such 
 as:
 
  for (x in keys(obj))
 
 I have learned a mnemonic for for-in: that it is iterating using the `in` 
 operator.  You propose that I unlearn that?  Or in your new hypothetical 
 world does the `in` operator also get overloaded?
 
 Excellent question. One (Java extension language) answer:
 
 http://www.cs.cornell.edu/Projects/jmatch/
 
 Python allows unstratified meta-programming of both its for-in 
 loop/comprehension syntax *and* its |in| operator.
 
 Harmony Proxies allow meta-programming of |in| already, via the |has| trap. 
 So the answer to your quesiton does the `in` operator also get overloaded? 
 is Yes, but you have to write two traps, iterate and has.

How does the `in` in for-in decide which of it's overloaded meanings applies?  
Based on the type of the operand?  Based on the existence of the enumerate or 
iterate trap on the operand?

And despite the `in` in for-in either enumerating or iterating, the `in` 
operator only has a single associated trap.  The non-parallelism is bugging me. 

 Ramdom thought: Can I use destructuring in for-in?
 
 for ({key:value} in enumerable)
 
 for ([value] in iterable)
 
 Absolutely. Destructuring (separate proposal but composes well) applies to 
 all LHS and binding forms.

I was being too subtle.  I was suggesting something like your JS 1.7 example, 
where the 'top-level' destructuring is a pattern for the `in` operation.  
`{key: value}` means I want the property keys and their values, `[value]` means 
I want the values, and `key` is (backward-compatible) shorthand for `{key: _}`. 
 Destructuring iteration over an hash of triples:

  for ({key: [s, v, o]} in tripledb) ...

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


Re: Nov 18 notes

2010-11-23 Thread Waldemar Horwat

On 11/23/10 11:12, Brendan Eich wrote:

   for (k in keys(o)) ...
   for (v in values(o)) ...
   for ([k, v] in properties(o)) ...


What are keys, values, and properties here?  Global functions?  How would 
a new object abstraction T customize them just for instances of T?

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


Re: Nov 18 notes

2010-11-23 Thread David Herman
   for (k in keys(o)) ...
   for (v in values(o)) ...
   for ([k, v] in properties(o)) ...
 
 What are keys, values, and properties here?  Global functions?

Those are API's suggested in the strawman:iterators proposal. They would be 
importable from a standard module.

  How would a new object abstraction T customize them just for instances of T?

By writing its own custom iteration protocol via proxies with the iterate() 
trap implemented appropriately. E.g.:

function MyCollection() { }
MyCollection.prototype = {
iterator: function() {
var self = this;
return Proxy.create({
iterate: function() { ... self ... },
...
});
}
}

Dave

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


Re: Nov 18 notes

2010-11-23 Thread Brendan Eich
On Nov 23, 2010, at 12:14 PM, P T Withington wrote:

 Harmony Proxies allow meta-programming of |in| already, via the |has| trap. 
 So the answer to your quesiton does the `in` operator also get overloaded? 
 is Yes, but you have to write two traps, iterate and has.
 
 How does the `in` in for-in decide which of it's overloaded meanings applies? 
  Based on the type of the operand?  Based on the existence of the enumerate 
 or iterate trap on the operand?

A proxy's handler is a single object with trap methods. These traps work 
together to create an abstraction. It should be a coherent abstraction 
(ideally, don't you think? ;-).

If you're implementing an iterator, then the iterate and has traps are enough 
to make for-in and in agree. From Python experience, just iterate is enough. 
(JMatch is cute because it can synthesize both iteration and membership testing 
from Boolean formulae, but we're not going to try for anything like it.)

If you're implementing a container, then questions of mutability arise. 
Immutable container proxies could have iterate, has,  and get. Mutable 
containers might rather vend iterators via specific API methods, where the 
iterators are separate proxies that iterate over snapshots. There are lots of 
possibilities.


 And despite the `in` in for-in either enumerating or iterating, the `in` 
 operator only has a single associated trap.  The non-parallelism is bugging 
 me. 

There are at least two reasons for this:

1. Large and lazy objects cannot afford to enumerate all keys eagerly, as the 
enumerate trap wants.
2. in maps to the has trap, which must eagerly compute a boolean result.

With just harmony:proxies as proposed, (1) motivates adding a derived trap, 
call it iterate, that can be used instead of enumerate. This is the proposed 
solution to the large/lazy object problem that we agreed to fix when moving 
Proxies to harmony:proposals status.

Notice how in does not have a large/lazy problem. Membership queries must be 
answered eagerly, all at once, with a boolean result. This is (2).

Another reason (3) is to support iterators as a special kind of proxy. All 
objects can be enumerated if not iterated, but not all objects are iterators. 
Adding a derived, lazy-iteration trap to use instead of enumerate allows 
proxies to implement iterators for arbitrary value streams. This is something 
we propose separately from proxies, but build on proxies (rather than 
reinventing obvious wheels). We thus handle large/lazy object enumeration 
(string typed key streams) as well as custom iterateion (arbitrarily typed 
value streams).

The particulars matter. Tom invokes Einstein's famous as simple as possible, 
but not simpler dictum in his talks on proxies. Both JS's particulars, and 
hard realities to-do with scaling to large or lazily built objects, motivate 
non-parallel trap structure here.

Trying to oversimplify will just make an unusably simplistic metaprogramming 
API that falls down on some use-cases, or too easily leads to incoherent 
abstractions.


 Ramdom thought: Can I use destructuring in for-in?
 
 for ({key:value} in enumerable)
 
 for ([value] in iterable)
 
 Absolutely. Destructuring (separate proposal but composes well) applies to 
 all LHS and binding forms.
 
 I was being too subtle.  I was suggesting something like your JS 1.7 example, 
 where the 'top-level' destructuring is a pattern for the `in` operation.  
 `{key: value}` means I want the property keys and their values,

No, that destructuring pattern {key: value} captures only the key property's 
value, bound to the name value on each turn of the loop.

Making it a special form just breaks destructuring for no good reason.


 `[value]` means I want the values,

No, that means get the 0 property of the iterated value and bind it to the 
name value.

http://wiki.ecmascript.org/doku.php?id=harmony:destructuring


 and `key` is (backward-compatible) shorthand for `{key: _}`.  Destructuring 
 iteration over an hash of triples:
 
  for ({key: [s, v, o]} in tripledb) ...
 
 Too cute?

Too restrictive and verbose, also does violence to destructuring by 
reinterpreting its syntax.

Destructuring lets you pull properties from objects using object and array 
patterns modeled on initialisers, in a way that honestly desugars to property 
references and assignments.

Iteration (whatever the syntax) lets you visit a sequence of values, whatever 
their type and deeper structure.

Destructuring the iterated value conveniently binds values from the deeper 
structure to names or local variables declared in the iteration's loop syntax 
and used in the loop body.

Thus there is no good reason to hardcode key as a name, or any particular 
one- or two-property pattern, in order to deal with objects as key/value stores 
using destructuring and iteration. We can leave destructuring unaltered and 
provide different iterators for the key, value, and key-value (and triple, 
quad, etc.) use cases.

As dherman noted, iteration 

Re: Nov 18 notes

2010-11-23 Thread David Herman
 How would a new object abstraction T customize them just for instances of T?
 
 By writing its own custom iteration protocol via proxies with the iterate() 
 trap implemented appropriately. E.g.:
 
function MyCollection() { }
MyCollection.prototype = {
iterator: function() {
var self = this;
return Proxy.create({
iterate: function() { ... self ... },
...
});
}
}

I left out the last step: clients would then use this via:

var coll = new MyCollection();
...
for (var x in coll.iterator()) {
...
}

Dave

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


Re: Nov 18 notes

2010-11-23 Thread Brendan Eich
On Nov 23, 2010, at 1:05 PM, Brendan Eich wrote:

 If you're implementing a container, then questions of mutability arise. 
 Immutable container proxies could have iterate, has,  and get. Mutable 
 containers might rather vend iterators via specific API methods, where the 
 iterators are separate proxies that iterate over snapshots. There are lots of 
 possibilities.

For some reason I typed container where I meant collection -- could be that 
both terms work, but collection is better.

/be

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


Re: Nov 18 notes

2010-11-23 Thread Waldemar Horwat

On 11/23/10 13:05, David Herman wrote:

How would a new object abstraction T customize them just for instances of T?


By writing its own custom iteration protocol via proxies with the iterate() 
trap implemented appropriately. E.g.:

function MyCollection() { }
MyCollection.prototype = {
iterator: function() {
var self = this;
return Proxy.create({
iterate: function() { ... self ... },
...
});
}
}


I left out the last step: clients would then use this via:

 var coll = new MyCollection();
 ...
 for (var x in coll.iterator()) {
 ...
 }

Dave


That misses the point of my question.  Sure you can define the meaning of
  for (k in MyNewFunction(o))
or
  for (k in o.MyMethod())

However, I asked how a new object abstraction T would customize keys, values, and 
properties just for instances of T so that instances of T could be usable under the standard 
pattern:

   for (k in keys(o)) ...
   for (v in values(o)) ...
   for ([k, v] in properties(o)) ...

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


Re: Nov 18 notes

2010-11-22 Thread Peter van der Zee
On Mon, Nov 22, 2010 at 8:37 AM, David Herman dher...@mozilla.com wrote:

  for (var i : x) ...  // must be new iteration
  for (var i : T : x) ...  // iteration again, but parsed how?
  for (var i : T in x) ... // for-in with annotated var

 Bummer!

 I'm beginning to feel more strongly again that overloading for-in, as
 opposed to introducing yet another syntactic variant of `for', is the right
 way to go.

 thought experiment
 Imagine we made Harmony backwards-incompatible in the following way: for-in
 loops would *only* work on iterable objects, and would dynamically fail on
 non-iterable objects. So if you wanted the legacy keys behavior, you would
 have to explicitly call a `keys' library function.
 /thought experiment


If we're gonna go invent new keywords why not use the obvious?

iterate (var x in y) ...
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Nov 18 notes

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 12:49 AM, Peter van der Zee wrote:

 On Mon, Nov 22, 2010 at 8:37 AM, David Herman dher...@mozilla.com wrote:
  for (var i : x) ...  // must be new iteration
  for (var i : T : x) ...  // iteration again, but parsed how?
  for (var i : T in x) ... // for-in with annotated var
 
 Bummer!
 
 I'm beginning to feel more strongly again that overloading for-in, as opposed 
 to introducing yet another syntactic variant of `for', is the right way to go.
 
 thought experiment
 Imagine we made Harmony backwards-incompatible in the following way: for-in 
 loops would *only* work on iterable objects, and would dynamically fail on 
 non-iterable objects. So if you wanted the legacy keys behavior, you would 
 have to explicitly call a `keys' library function.
 /thought experiment
 
 
 If we're gonna go invent new keywords why not use the obvious?
 
 iterate (var x in y) ...
 

Did you read Dave's previous post, or mine? We are not going to go invent 
some new overlong non-reserved word. for is the right word.

One might try retasking do but it's ambiguous: do-while loops do not require 
braces (KR style favors them even for one-liners but it's just a convention).

Dave's point about getting people to use one universal quantifying loop 
structure is good. If that loop syntax is not for-in, it will have to be 
something new that works even when there is no iterate trapping proxy. But that 
will just be a suckier version of the universal (enumerating if not 
custom-iterating) for-in from JS1.7.

So what good are we really doing by forking for-in into bastard children (the 
one we have, definitely a bastard -- I should know! :-/) and a new one with red 
hair?

/be

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


Re: Nov 18 notes

2010-11-22 Thread Tom Van Cutsem
My arguments in favor of keeping the existing for-in syntax and making it
meta-programmable:

- Simplicity. Don't underestimate the complexity creep of introducing a new
looping construct. Many small changes add up quickly. Especially for
novices, having two looping constructs that are so similar will be terribly
confusing.
- Keeping the existing syntax means that the tons of JS code already out
there can instantly become client-code to iterators. As Brendan noted: you
can use iterators to generate a stream of keys (strings) without confusing
clients.
- Client code to proxies that emulate objects with lots of properties can
continue to use for-in. It just feels wrong that client code should change
because of pure implementation details of an object (i.e. whether it eagerly
or lazily generates its keys).

Of course, if an object changes its behavior from iterating keys to
iterating values, this breaks clients and they should be modified to use
for (var k in keys(obj)). But I don't see how this differs from any other
such changes made to an object. The important thing to note here is that
turning an object into an iterator requires explicit action by the
programmer. If iterators were implemented ala Python using a magical
__iterate__ hook, then I'd complain because Harmony code could silently
turn normal objects into iterators. But there's no such risk with this
proposal.

I think that's a key point worth re-iterating: iterators and regular objects
are sufficiently distinct so that there's no risk of automatically
converting one into the other. There is only a risk to existing client-code
if a Harmony programmer changes a normal object into an iterator. But at
that point the programmer knows he's making a non-upwards-compatible change
and clients should be changed accordingly. I don't see how the for-in case
differs in this respect, fundamentally, from say, renaming a method.

Cheers,
Tom

2010/11/22 Brendan Eich bren...@mozilla.com

 On Nov 22, 2010, at 12:49 AM, Peter van der Zee wrote:

 On Mon, Nov 22, 2010 at 8:37 AM, David Herman dher...@mozilla.com wrote:

  for (var i : x) ...  // must be new iteration
  for (var i : T : x) ...  // iteration again, but parsed how?
  for (var i : T in x) ... // for-in with annotated var

 Bummer!

 I'm beginning to feel more strongly again that overloading for-in, as
 opposed to introducing yet another syntactic variant of `for', is the right
 way to go.

 thought experiment
 Imagine we made Harmony backwards-incompatible in the following way:
 for-in loops would *only* work on iterable objects, and would dynamically
 fail on non-iterable objects. So if you wanted the legacy keys behavior, you
 would have to explicitly call a `keys' library function.
 /thought experiment


 If we're gonna go invent new keywords why not use the obvious?

 iterate (var x in y) ...


 Did you read Dave's previous post, or mine? We are not going to go invent
 some new overlong non-reserved word. for is the right word.

 One might try retasking do but it's ambiguous: do-while loops do not
 require braces (KR style favors them even for one-liners but it's just a
 convention).

 Dave's point about getting people to use one universal quantifying loop
 structure is good. If that loop syntax is not for-in, it will have to be
 something new that works even when there is no iterate trapping proxy. But
 that will just be a suckier version of the universal (enumerating if not
 custom-iterating) for-in from JS1.7.

 So what good are we really doing by forking for-in into bastard children
 (the one we have, definitely a bastard -- I should know! :-/) and a new one
 with red hair?

 /be


 ___
 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: Nov 18 notes

2010-11-22 Thread Oliver Hunt

On Nov 22, 2010, at 2:08 AM, Tom Van Cutsem wrote:

 My arguments in favor of keeping the existing for-in syntax and making it 
 meta-programmable:
 
 - Simplicity. Don't underestimate the complexity creep of introducing a new 
 looping construct. Many small changes add up quickly. Especially for novices, 
 having two looping constructs that are so similar will be terribly confusing.

You're not saving the addition of a looping construct, in making for-in behave 
differently depending on what is on the right hand side of 'in' you're merely 
adding an additional looping that is not syntactically observable.

 - Keeping the existing syntax means that the tons of JS code already out 
 there can instantly become client-code to iterators. As Brendan noted: you 
 can use iterators to generate a stream of keys (strings) without confusing 
 clients.

And all existing standards compliant code can no longer rely on for in doing 
what it has done for years.  Suddently for in _behaviour_ may change based on 
the prototype chain.

 - Client code to proxies that emulate objects with lots of properties can 
 continue to use for-in. It just feels wrong that client code should change 
 because of pure implementation details of an object (i.e. whether it eagerly 
 or lazily generates its keys).

My understanding was that proxies would have a trap to allow them to generate 
an array of strings to be used.

 
 Of course, if an object changes its behavior from iterating keys to iterating 
 values, this breaks clients and they should be modified to use for (var k in 
 keys(obj)). But I don't see how this differs from any other such changes 
 made to an object. The important thing to note here is that turning an object 
 into an iterator requires explicit action by the programmer. If iterators 
 were implemented ala Python using a magical __iterate__ hook, then I'd 
 complain because Harmony code could silently turn normal objects into 
 iterators. But there's no such risk with this proposal.
 
 I think that's a key point worth re-iterating: iterators and regular objects 
 are sufficiently distinct so that there's no risk of automatically converting 
 one into the other. There is only a risk to existing client-code if a Harmony 
 programmer changes a normal object into an iterator. But at that point the 
 programmer knows he's making a non-upwards-compatible change and clients 
 should be changed accordingly. I don't see how the for-in case differs in 
 this respect, fundamentally, from say, renaming a method.
I do not expect the behaviour of for(in) to change from harmony to non-harmony 
code.  Ignoring all other concerns it would mean the behaviour of objects 
passed from a harmony context to a non-harmony context would be unexpected.

I'm kind of frustrated that after discussing all this last week, and apparently 
getting to some kind of consensus, we've more or less instantly gone back to 
what we had at the beginning of the meeting, where for(in) gets magically 
overloaded and a developer has some magical way to understand what a given 
for(in) loop is going to do.  If this was going to be the outcome why did we 
even spend time discussing this?

--Oliver

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


Re: Nov 18 notes

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 11:14 AM, Oliver Hunt wrote:

 On Nov 22, 2010, at 2:08 AM, Tom Van Cutsem wrote:
 
 My arguments in favor of keeping the existing for-in syntax and making it 
 meta-programmable:
 
 - Simplicity. Don't underestimate the complexity creep of introducing a new 
 looping construct. Many small changes add up quickly. Especially for 
 novices, having two looping constructs that are so similar will be terribly 
 confusing.
 
 You're not saving the addition of a looping construct, in making for-in 
 behave differently depending on what is on the right hand side of 'in' you're 
 merely adding an additional looping that is not syntactically observable.

Is the additional aspect important enough to split syntax over?

If so, would you make the new form *only* work on proxies and throw given a 
non-proxy on the right of in?

If not, why not?


 - Keeping the existing syntax means that the tons of JS code already out 
 there can instantly become client-code to iterators. As Brendan noted: you 
 can use iterators to generate a stream of keys (strings) without confusing 
 clients.
 
 And all existing standards compliant code can no longer rely on for in doing 
 what it has done for years.  Suddently for in _behaviour_ may change based on 
 the prototype chain.

That's true in Harmony, and as you noted on the list a while ago, also true in 
ES5 strict. I decried too much migration tax but allowed we want to break 
compatibility for important wins. Lexical scope all the way up is one such 
proposed win, justifying removing the global object from the scope chain.

In my view, letting for-in be reformed by library authors is another case where 
the migration tax is worth it.

Now, I need to ask whether you are making an absolute statement: Harmony must 
be runtime as well as syntactically compatible with ES5 strict, i.e., a 
superset language?


 - Client code to proxies that emulate objects with lots of properties can 
 continue to use for-in. It just feels wrong that client code should change 
 because of pure implementation details of an object (i.e. whether it eagerly 
 or lazily generates its keys).
 
 My understanding was that proxies would have a trap to allow them to generate 
 an array of strings to be used.

That's true, the fundamental trap is enumerate, but as noted on the wiki and 
pointed out by Waldemar when we reviewed proxies and moved them to 
harmony:proposals status, this does not work well for large and infinite 
objects.

We moved proxies to harmony:proposals status with the agreement that the 
iteration protocol would address such hard cases. The iterators proposal does 
that, including details about proxies as prototypes of other objects (you don't 
want to switch to iterate if you start with enumeration -- you must call the 
proxy handler's enumerate trap).

Last week we agreed toward the end of the meeting, with some lack of clarity 
about *how* to do this, to recast for (x in y) as for (x : keys(y)) and allow 
either enumerate or (if provided) iterate to be used to handle large/infinite 
objects.

Now the for-: syntax looks like a mistake, and we still haven't reworked things 
to address the required large/infinite cases.

I'm reviewing all this because I do not think everyone has kept up with the 
details. But the details matter, and they have some irreducible complexity we 
can't wish away. They motivate more than just the enumerate trap which eagerly 
returns all the property keys


 Of course, if an object changes its behavior from iterating keys to 
 iterating values, this breaks clients and they should be modified to use 
 for (var k in keys(obj)). But I don't see how this differs from any other 
 such changes made to an object. The important thing to note here is that 
 turning an object into an iterator requires explicit action by the 
 programmer. If iterators were implemented ala Python using a magical 
 __iterate__ hook, then I'd complain because Harmony code could silently 
 turn normal objects into iterators. But there's no such risk with this 
 proposal.
 
 I think that's a key point worth re-iterating: iterators and regular objects 
 are sufficiently distinct so that there's no risk of automatically 
 converting one into the other. There is only a risk to existing client-code 
 if a Harmony programmer changes a normal object into an iterator. But at 
 that point the programmer knows he's making a non-upwards-compatible change 
 and clients should be changed accordingly. I don't see how the for-in case 
 differs in this respect, fundamentally, from say, renaming a method.

 I do not expect the behaviour of for(in) to change from harmony to 
 non-harmony code.  Ignoring all other concerns it would mean the behaviour of 
 objects passed from a harmony context to a non-harmony context would be 
 unexpected.

That is a risk but it is not an absolute. It is one end of a trade-off. The 
other end is the benefit of avoiding new and hard-to-make-winning syntax, 

Re: Nov 18 notes

2010-11-22 Thread Oliver Hunt

On Nov 22, 2010, at 11:49 AM, Brendan Eich wrote:

 On Nov 22, 2010, at 11:14 AM, Oliver Hunt wrote:
 
 On Nov 22, 2010, at 2:08 AM, Tom Van Cutsem wrote:
 
 My arguments in favor of keeping the existing for-in syntax and making it 
 meta-programmable:
 
 - Simplicity. Don't underestimate the complexity creep of introducing a new 
 looping construct. Many small changes add up quickly. Especially for 
 novices, having two looping constructs that are so similar will be terribly 
 confusing.
 
 You're not saving the addition of a looping construct, in making for-in 
 behave differently depending on what is on the right hand side of 'in' 
 you're merely adding an additional looping that is not syntactically 
 observable.
 
 Is the additional aspect important enough to split syntax over?
 
 If so, would you make the new form *only* work on proxies and throw given a 
 non-proxy on the right of in?
 
 If not, why not?

Proxies need to have a way to work with for(in) which is the only reason I 
believe they should be allowed to have a trap for for(in) enumeration.  It's 
necessary if you ever want to have DOM objects like NodeList be defined in 
terms of proxies.

 - Keeping the existing syntax means that the tons of JS code already out 
 there can instantly become client-code to iterators. As Brendan noted: you 
 can use iterators to generate a stream of keys (strings) without confusing 
 clients.
 
 And all existing standards compliant code can no longer rely on for in doing 
 what it has done for years.  Suddently for in _behaviour_ may change based 
 on the prototype chain.
 
 That's true in Harmony, and as you noted on the list a while ago, also true 
 in ES5 strict. I decried too much migration tax but allowed we want to break 
 compatibility for important wins. Lexical scope all the way up is one such 
 proposed win, justifying removing the global object from the scope chain.
 
 In my view, letting for-in be reformed by library authors is another case 
 where the migration tax is worth it.
 
 Now, I need to ask whether you are making an absolute statement: Harmony must 
 be runtime as well as syntactically compatible with ES5 strict, i.e., a 
 superset language?

I'm not sure what relevance pure lexical scoping in harmony has to a discussion 
on the behaviour of for(in).  If we're saying that every new API and language 
feature being discussed for harmony will only be available in harmony, then yes 
harmony can do whatever it wants, but you've also caused me to lose any 
interest in implementing harmony at that point.  If every feature being 
discussed is only usable inside harmony code then the migration cost of 
individual features won't be relevant as it's a distinct language with no 
impact on ES.

 - Client code to proxies that emulate objects with lots of properties can 
 continue to use for-in. It just feels wrong that client code should change 
 because of pure implementation details of an object (i.e. whether it 
 eagerly or lazily generates its keys).
 
 My understanding was that proxies would have a trap to allow them to 
 generate an array of strings to be used.
 
 That's true, the fundamental trap is enumerate, but as noted on the wiki and 
 pointed out by Waldemar when we reviewed proxies and moved them to 
 harmony:proposals status, this does not work well for large and infinite 
 objects.
 
 We moved proxies to harmony:proposals status with the agreement that the 
 iteration protocol would address such hard cases. The iterators proposal does 
 that, including details about proxies as prototypes of other objects (you 
 don't want to switch to iterate if you start with enumeration -- you must 
 call the proxy handler's enumerate trap).
 
 Last week we agreed toward the end of the meeting, with some lack of clarity 
 about *how* to do this, to recast for (x in y) as for (x : keys(y)) and allow 
 either enumerate or (if provided) iterate to be used to handle large/infinite 
 objects.
 
 Now the for-: syntax looks like a mistake, and we still haven't reworked 
 things to address the required large/infinite cases.
I don't understand why : was a mistake, the only counter argument i saw was 
that it didn't work well with type annotations, which i see no value in and 
aren't being discussed for harmony or es-next.  Honestly I wish people would 
stop treating type annotations as something important -- ES is a dynamically 
typed language, trying to shoe-horn static typing in seems strange.

 I'm reviewing all this because I do not think everyone has kept up with the 
 details. But the details matter, and they have some irreducible complexity we 
 can't wish away. They motivate more than just the enumerate trap which 
 eagerly returns all the property keys
 
 
 Of course, if an object changes its behavior from iterating keys to 
 iterating values, this breaks clients and they should be modified to use 
 for (var k in keys(obj)). But I don't see how this differs from any other 
 such changes made to an 

Re: Nov 18 notes

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 12:09 PM, Oliver Hunt wrote:

 On Nov 22, 2010, at 11:49 AM, Brendan Eich wrote:
 
 On Nov 22, 2010, at 11:14 AM, Oliver Hunt wrote:
 
 On Nov 22, 2010, at 2:08 AM, Tom Van Cutsem wrote:
 
 My arguments in favor of keeping the existing for-in syntax and making 
 it meta-programmable:
 
 - Simplicity. Don't underestimate the complexity creep of introducing a 
 new looping construct. Many small changes add up quickly. Especially for 
 novices, having two looping constructs that are so similar will be 
 terribly confusing.
 
 You're not saving the addition of a looping construct, in making for-in 
 behave differently depending on what is on the right hand side of 'in' 
 you're merely adding an additional looping that is not syntactically 
 observable.
 
 Is the additional aspect important enough to split syntax over?
 
 If so, would you make the new form *only* work on proxies and throw given a 
 non-proxy on the right of in?
 
 If not, why not?
 
 Proxies need to have a way to work with for(in) which is the only reason I 
 believe they should be allowed to have a trap for for(in) enumeration.  It's 
 necessary if you ever want to have DOM objects like NodeList be defined in 
 terms of proxies.

Yes, that's already in the harmony:proxies design via the enumerate trap.

You didn't answer my questions, though. If we were to add for (x : y) as you 
among others seemed to want last week, would it throw on a non-proxy on the 
right of :?

The answer matters both so we can hope to define for-: (whatever its syntax, if 
not for-in), and so we can reach agreement on premises. One premise: new users 
of Harmony implementations can just always use for-: as dherman said. They 
never have to use for-in. For enumeration, they use for (k in keys(o)). Agree 
or disagree? If you are indifferent then you're not really participating :-/.


 - Keeping the existing syntax means that the tons of JS code already out 
 there can instantly become client-code to iterators. As Brendan noted: you 
 can use iterators to generate a stream of keys (strings) without confusing 
 clients.
 
 And all existing standards compliant code can no longer rely on for in 
 doing what it has done for years.  Suddently for in _behaviour_ may change 
 based on the prototype chain.
 
 That's true in Harmony, and as you noted on the list a while ago, also true 
 in ES5 strict. I decried too much migration tax but allowed we want to break 
 compatibility for important wins. Lexical scope all the way up is one such 
 proposed win, justifying removing the global object from the scope chain.
 
 In my view, letting for-in be reformed by library authors is another case 
 where the migration tax is worth it.
 
 Now, I need to ask whether you are making an absolute statement: Harmony 
 must be runtime as well as syntactically compatible with ES5 strict, i.e., a 
 superset language?
 
 I'm not sure what relevance pure lexical scoping in harmony has to a 
 discussion on the behaviour of for(in).

It's a breaking change to the language's runtime semantics, but not to any 
syntax. It seems entirely analogous to the case of migrating for-in code from 
pre-Harmony into Harmony, and as I guessed last time, losing the global object 
looks strictly riskier in terms of unintended global property aliasing breakage.


 If we're saying that every new API and language feature being discussed for 
 harmony will only be available in harmony, then yes harmony can do whatever 
 it wants,

We are not saying that because we do not want gratuitous differences for users 
or implementors. This is pretty clear from all our work. If we really wanted a 
totally new language, not only would it make for roughly 2x the learning curve 
for users, and lots of confused-mode bugs, it would make implementors do a 
bunch more work, approaching 2x.

And as I also argued last week, TC39 would never pull it off. It would be 
design by committee and it would fail.

So (in case this isn't obvious; I thought it was), we are trying to extend ES5 
strict mode with only a few well-chosen runtime semantic shifts. Possibly few 
will be one: the global object removal in favor of lexical scope.

New syntax brings new semantics of course.


 but you've also caused me to lose any interest in implementing harmony at 
 that point.

That's a straw man of your own devising, and I just knocked it down. Can we 
please get back to the crucial issues?


  If every feature being discussed is only usable inside harmony code then the 
 migration cost of individual features won't be relevant as it's a distinct 
 language with no impact on ES.

There's still a migration tax in porting from old to new language, however 
similar they are. You yourself raised this re: ES5 strict, which changes 
runtime semantics without any syntactic change (eval-of-var, arguments). It is 
the same point I'm making about lexical scope removing the global object. I 
hope it is clear now, both as a risk and an opportunity!


Re: Nov 18 notes

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 12:39 PM, Brendan Eich wrote:

 On Nov 22, 2010, at 12:09 PM, Oliver Hunt wrote:
 
 How do library authors help?  They can't add value enumeration of anything 
 as that will break any existing code that uses for(in) over any of their 
 objects.
 
 As Tom pointed out (re-read his message :-|), they can make enumeration work 
 for large/lazy/infinite objects. No non-string non-keys required.

The important point here is that for-in won't choke old browsers. New library 
code in the near term (when Harmony and pre-Harmony impls are in the field), 
assuming we let for-in be metaprogrammed in Harmony, can object-detect and 
meta-program for-in, and client *and* library code can use for-in and it will 
fail soft or fall back by other means.

Not so if we add new syntax (for-: or anything old browsers will choke on).

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


Re: Nov 18 notes

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 11:49 AM, Brendan Eich wrote:

 On Nov 22, 2010, at 11:14 AM, Oliver Hunt wrote:
 And all existing standards compliant code can no longer rely on for in doing 
 what it has done for years.  Suddently for in _behaviour_ may change based 
 on the prototype chain.
 
 That's true in Harmony,

I think I misread your based on the prototype chain words.

I was making the general case for runtime semantic fixes -- few and worth 
making -- in Harmony as in ES5 strict.

But I think you were supposing a proxy on a non-proxy's prototype chain could 
start returning non-string non-keys via its iterate trap. Not so. Here's a 
session with a fresh js shell (Firefox 4 latest code):

js var proxy = Proxy.create({
has: function () { return false; },
enumerate: function () { return [a, b, c]; },
iterate: function () { for (let i = 0; i  10; i++) yield i; }
});
js 
js var obj = Object.create(proxy);
js 
js for (var i in proxy)
print(i);
0
1
2
3
4
5
6
7
8
9
js 
js for (var i in obj)
print(i);
a
b
c

Once for-in starts up a non-proxy object's prototype chain, only enumerate 
traps -- never iterate. And enumerate is fundamental, so if missing, the for in 
fails:

js var proxy = Proxy.create({
has: function () { return false; },
iterate: function () { for (let i = 0; i  10; i++) yield i; }
});
js 
js var obj = Object.create(proxy);
js 
js for (var i in proxy)
print(i);
0
1
2
3
4
5
6
7
8
9
js 
js for (var i in obj)
print(i);
typein:11: TypeError: enumerate is not a function

/be

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


Re: Nov 18 notes

2010-11-22 Thread Allen Wirfs-Brock
Rather than adding additional confusion by trying to comment on snippets 
from this thread, I think I'll just state my current opinions on the subject 
and the principles that they are based upon:


1a)  New semantics should use new syntax in a manner that clearly avoids 
confusion with existing syntax.
1b)  Syntax should generally be suggestive of a reasonable interpretation of 
the semantic

1c)  Harmony is not being designed using the no new syntax rule
1d)  There is nothing sacred about for as the initial keyword of an 
enumeration statement.


From these I conclude that new iteration semantics should be syntactically 
distinct from the current for-in and probably the greater the syntactic 
distance from for-in the better.  Following these principles, here is a 
suggestion for a new enumeration statement that makes use of existing 
reserved words:


enum key with keys(x) {
   alert(key)
}

enum val with values(x) {
   alert(val)
}

enum  [key, val] with properties(x) {
   alert(x. + key +  =  + val);
}

Since this is a new form, it can impose new syntactic conventions.  For 
example, it always creates new bindings in the block that it iterates.  An 
explicit var or let keyword is not needed. Also with has much broader 
semantic implications than in


2) Whenever possible, less general pre-existing syntactic forms should be 
redefined to desugar into new more general forms.


ES1-5 for-in can be defined via desugaring to enum-with, for example:

//desugar:   for (var x in foo) {alert(foo[x])}
var x;
enum __x with __ES5forinEnumerator(x) {
  x=__x;
  {alert(foo[x])}
}

3) Proxy traps should be defined based upon the new, more general semantics 
not legacy less general semantics.


Define the traps necessary to support enum-with and depend upon the 
desugaring to take care of legacy for-in.


4) Provide builtin-library alternatives for new statements that can be used 
without down-rev syntax errors:


Iterator.prototype.enumWith = function (func) {
   enum each with this {
   func(each)
   }
}

keys(x).enumWith(function(key){alert(key)});
values(x).enumWith(function(val){alert(val)});
properties(x).enumWith(function([key,val]){alert(x. + key +  =  + 
val)});


Leave it to library writers as to whether or not down-rev libraries are 
actually implemented.



-Original Message- 
From: Brendan Eich

Sent: Monday, November 22, 2010 12:48 PM
To: Oliver Hunt
Cc: es-discuss
Subject: Re: Nov 18 notes

On Nov 22, 2010, at 12:39 PM, Brendan Eich wrote:


On Nov 22, 2010, at 12:09 PM, Oliver Hunt wrote:


How do library authors help?  They can't add value enumeration of 
anything as that will break any existing code that uses for(in) over any 
of their objects.


As Tom pointed out (re-read his message :-|), they can make enumeration 
work for large/lazy/infinite objects. No non-string non-keys required.


The important point here is that for-in won't choke old browsers. New 
library code in the near term (when Harmony and pre-Harmony impls are in the 
field), assuming we let for-in be metaprogrammed in Harmony, can 
object-detect and meta-program for-in, and client *and* library code can use 
for-in and it will fail soft or fall back by other means.


Not so if we add new syntax (for-: or anything old browsers will choke on).

/be
___
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: Nov 18 notes

2010-11-22 Thread David Herman
 1a)  New semantics should use new syntax in a manner that clearly avoids 
 confusion with existing syntax.
 1b)  Syntax should generally be suggestive of a reasonable interpretation of 
 the semantic
 1c)  Harmony is not being designed using the no new syntax rule
 1d)  There is nothing sacred about for as the initial keyword of an 
 enumeration statement.

Nobody said sacred -- I'm not genuflecting. :) Seriously, the reason for 
using for is that it's one of the most stable, common, and universally-used 
keywords for iteration in almost all languages. Introducing a new initial 
keyword is straying really far from precedent, both in JS and other imperative 
languages.

But I appreciate your spelled-out premises. I think my main quibble is with 1a 
as a rule. I might prefer something like:

2a) If existing syntax is given new semantics, it should extend the existing 
semantics conservatively. Otherwise, the new semantics should get new syntax.

 From these I conclude that new iteration semantics should be syntactically 
 distinct from the current for-in and probably the greater the syntactic 
 distance from for-in the better.  Following these principles, here is a 
 suggestion for a new enumeration statement that makes use of existing 
 reserved words:
 
 enum key with keys(x) {
   alert(key)
 }

This is clever, but it just seems to go off the deep end: the syntax is too 
inconsistent with JS precedent. Also, enum is the wrong keyword -- in JS 
parlance, this is iteration not enumeration.

I guess I'm still open to new syntaxes, but I also still feel that when you 
step back and weigh the trade-offs, the cost of all this new syntax is 
incommensurate with the amount of new semantics, and moreover the traditional 
for-in syntax is still the sweetest I've seen for custom iteration. I would 
rather extend the best syntax and leave the legacy special case as a very small 
wart than have a warty syntax with a supremely orthogonal semantics.

 2) Whenever possible, less general pre-existing syntactic forms should be 
 redefined to desugar into new more general forms.

I think this is pretty uncontroversial; whatever syntax we decide on, the 
specific legacy construct can be defined in terms of the more general new 
construct.

 3) Proxy traps should be defined based upon the new, more general semantics 
 not legacy less general semantics.
 
 Define the traps necessary to support enum-with and depend upon the 
 desugaring to take care of legacy for-in.

You don't think for-in should even allow the enumerate trap? This seems to go 
against the design approach of proxies; it's not just for introducing new 
meta-programmable constructs, but also for meta-programming existing facilities.

 4) Provide builtin-library alternatives for new statements that can be used 
 without down-rev syntax errors:

This seems like a good idea.

Dave

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


Re: Nov 18 notes

2010-11-22 Thread David Herman
 2a) If existing syntax is given new semantics, it should extend the existing 
 semantics conservatively. Otherwise, the new semantics should get new syntax.

Perhaps I should have numbered that 1a'). :)

Dave

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


Re: Nov 18 notes

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 3:17 PM, Allen Wirfs-Brock wrote:

 Rather than adding additional confusion by trying to comment on snippets from 
 this thread, I think I'll just state my current opinions on the subject and 
 the principles that they are based upon:
 
 1a)  New semantics should use new syntax in a manner that clearly avoids 
 confusion with existing syntax.
 1b)  Syntax should generally be suggestive of a reasonable interpretation of 
 the semantic
 1c)  Harmony is not being designed using the no new syntax rule
 1d)  There is nothing sacred about for as the initial keyword of an 
 enumeration statement.

I will echo Dave in saying thanks for spelling out principles. Also that 
sacred is a bit one-sided -- I do not think your (1a) is sacred either. Are 
we even? :-|

The forest-for-the-trees meta-point is that if we conservatively add new syntax 
when meta-programming existing would have gone over without incident, we've 
made the language irrevocably bigger. We can't ever take back the new syntax or 
get rid of the old. We will have a long wait switching developers over to the 
new, which has ripple effects as Tom's post pointed out.

But no need to beat that drum again, I will stifle.


 From these I conclude that new iteration semantics should be syntactically 
 distinct from the current for-in and probably the greater the syntactic 
 distance from for-in the better.  Following these principles, here is a 
 suggestion for a new enumeration statement that makes use of existing 
 reserved words:
 
 enum key with keys(x) {

This is a clever homage to with :-P.

The parenthesis-free head is unusual and invites Go-like innovation elsewhere: 
will Harmony drop mandatory parens around if, while, etc. heads?

Iteration is not numbering or naming, so taking enum for this purpose 
promulgates a misnomer *and* precludes us using enum for a categorical sum 
declaration of some sort.


 2) Whenever possible, less general pre-existing syntactic forms should be 
 redefined to desugar into new more general forms.
 
 ES1-5 for-in can be defined via desugaring to enum-with, for example:
 
 //desugar:   for (var x in foo) {alert(foo[x])}
 var x;
 enum __x with __ES5forinEnumerator(x) {
  x=__x;
  {alert(foo[x])}
 }

This goes against the Proxy design. A proxy shouldn't have to special case 
__ES5forinEnumerator to customize for-in as opposed to enum-with, and 
customizing for-in should not affect enum-with when up the proto chain as one 
of my recent posts showed with a js shell session.

If we must have new syntax to get customized iteration through TC39, we can 
spend way too much time coming up with acceptable syntax. But before we dive 
into that fun timekilling process, let's be really sure we are not missing the 
forest for the trees.

/be

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


Re: Nov 18 notes

2010-11-22 Thread Allen Wirfs-Brock
-Original Message- 
From: David Herman

Sent: Monday, November 22, 2010 3:55 PM
To: Allen Wirfs-Brock
Cc: Brendan Eich ; Oliver Hunt ; es-discuss
Subject: Re: Nov 18 notes

1a)  New semantics should use new syntax in a manner that clearly avoids 
confusion with existing syntax.
1b)  Syntax should generally be suggestive of a reasonable interpretation 
of the semantic

1c)  Harmony is not being designed using the no new syntax rule
1d)  There is nothing sacred about for as the initial keyword of an 
enumeration statement.


Nobody said sacred -- I'm not genuflecting. :) Seriously, the reason for 
using for is that it's one of the most stable, common, and 
universally-used keywords for iteration in almost all languages. Introducing 
a new initial keyword is straying really far from precedent, both in JS and 
other imperative languages.


AWB: Perhaps I should have been a bit more general in 1d and said something 
like: respect precedent, except when it gets in the way.   Precedent can 
mislead users as easily as it can help help them.  One think I suspect that 
we have all observed (and probably experience) is the experienced 
programmers who starts trying to write JavaScript programmers using invalid 
assumptions based upon their experience with other languages.


But I appreciate your spelled-out premises. I think my main quibble is with 
1a as a rule. I might prefer something like:


2a) If existing syntax is given new semantics, it should extend the existing 
semantics conservatively. Otherwise, the new semantics should get new 
syntax.


AWB:  Thanks, I like that.  Trying to articulate some principles was the 
main point.  I felt the thread was feeling like it getting hung up on 
unstated and/or unshared prinicples.


From these I conclude that new iteration semantics should be syntactically 
distinct from the current for-in and probably the greater the syntactic 
distance from for-in the better.  Following these principles, here is a 
suggestion for a new enumeration statement that makes use of existing 
reserved words:


enum key with keys(x) {
  alert(key)
}


This is clever, but it just seems to go off the deep end: the syntax is too 
inconsistent with JS precedent. Also, enum is the wrong keyword -- in JS 
parlance, this is iteration not enumeration.


AWB: This was mainly a first cut trying to look at the problem from a 
slightly different angle but starting by only using the currently available 
set of reserved words.  Other syntactic issues like usage of parenthesis 
could tweaked and in the end wouldn't seem particularly inconsistent with 
the syntax conventions for C-like languages.   I agree that we have 
generally called this semantics iteration rather than enumeration, but I was 
working from out available set of reserved words and enum seems like the 
closest fit.  I suspect that the majority of Javascript programmers couldn't 
really articulate the difference between enumeration and iteration (over). 
They will use whatever meaning we feed them via the language design.  Of 
course, we should be consistent in our terminology and if we went this route 
we might want to adjust other uses of these terms.  Also, it there are JS 
1.8 precedent issues--I'm just not sure whether that usage is broad enough 
to matter that much.


I guess I'm still open to new syntaxes, but I also still feel that when you 
step back and weigh the trade-offs, the cost of all this new syntax is 
incommensurate with the amount of new semantics, and moreover the 
traditional for-in syntax is still the sweetest I've seen for custom 
iteration. I would rather extend the best syntax and leave the legacy 
special case as a very small wart than have a warty syntax with a supremely 
orthogonal semantics.


AWB: I worry that it is hard for people to learn when the same name is 
applied to different concepts.  We already have two forms of the for 
statement that people have to learn.  Further complicating it feels like it 
would be a pedagogical nightmare.


2) Whenever possible, less general pre-existing syntactic forms should be 
redefined to desugar into new more general forms.


I think this is pretty uncontroversial; whatever syntax we decide on, the 
specific legacy construct can be defined in terms of the more general new 
construct.


3) Proxy traps should be defined based upon the new, more general 
semantics not legacy less general semantics.


Define the traps necessary to support enum-with and depend upon the 
desugaring to take care of legacy for-in.


You don't think for-in should even allow the enumerate trap? This seems to 
go against the design approach of proxies; it's not just for introducing new 
meta-programmable constructs, but also for meta-programming existing 
facilities.


I haven't really studied the specific Proxy traps in detail.  However, if we 
had a more generate iterate trap(s) that semantically subsumes the enumerate 
trap when used with appropriate desugaring, why would we need

Re: Nov 18 notes

2010-11-22 Thread Allen Wirfs-Brock
-Original Message- 
From: Brendan Eich

Sent: Monday, November 22, 2010 4:10 PM
To: Allen Wirfs-Brock
Cc: Oliver Hunt ; es-discuss
Subject: Re: Nov 18 notes

On Nov 22, 2010, at 3:17 PM, Allen Wirfs-Brock wrote:
...


enum key with keys(x) {


This is a clever homage to with :-P.

AWB: actually, when I made this up I was a bit concerned using with 
because of its heritage.  I got over it...


The parenthesis-free head is unusual and invites Go-like innovation 
elsewhere: will Harmony drop mandatory parens around if, while, etc. heads?


AWB: Since what comes immediately after enum is a declaration from there 
isn't any precedent for parens there.  They could be added after the with 
if that felt more familiar.


Iteration is not numbering or naming, so taking enum for this purpose 
promulgates a misnomer *and* precludes us using enum for a categorical sum 
declaration of some sort.


AWB: See my reply to Dave Herman on this issue.


2) Whenever possible, less general pre-existing syntactic forms should be 
redefined to desugar into new more general forms.


ES1-5 for-in can be defined via desugaring to enum-with, for example:

//desugar:   for (var x in foo) {alert(foo[x])}
var x;
enum __x with __ES5forinEnumerator(x) {
 x=__x;
 {alert(foo[x])}
}


This goes against the Proxy design. A proxy shouldn't have to special case 
__ES5forinEnumerator to customize for-in as opposed to enum-with, and 
customizing for-in should not affect enum-with when up the proto chain as 
one of my recent posts showed with a js shell session.


AWB:  Perhaps  and we have other use cases of property name enumeration 
(Object.key and getOwnPropertyNames, the in operator) that may need the 
enumerate trap. I know that trap design was one of the starting points of 
this discussion so I probably should look more closely at this.


If we must have new syntax to get customized iteration through TC39, we can 
spend way too much time coming up with acceptable syntax. But before we dive 
into that fun timekilling process, let's be really sure we are not missing 
the forest for the trees.


AWB: For what it's worth, in the Northwest we have a long tradition of 
cutting down trees and then latter realizing that we don't have a forest any 
more...


/be 


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


Re: Nov 18 notes

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 5:39 PM, Allen Wirfs-Brock wrote:

 AWB:  Thanks, I like that.  Trying to articulate some principles was the main 
 point.  I felt the thread was feeling like it getting hung up on unstated 
 and/or unshared prinicples.

I agree, and I try to make mine clear (let me know where I fail). It's 
important not only for reaching agreement (backing up and trying a different 
deductive path forward) but also in rejecting bogus premises, or reprioritizing.


 AWB: I worry that it is hard for people to learn when the same name is 
 applied to different concepts.  We already have two forms of the for 
 statement that people have to learn.

The C-based for(;;) loop is not really relevant in my experience. JS hackers 
use it (more below on why they might rather not), but they always distinguish 
it from for-in.

Some good fraction of JS hackers know Python, where for-in has enumeration like 
behavior on dictionaries (just like JS objects), but value iteration on lists.

The most frequent (in my hearing) unsatisfied expectation of users of for-in is 
not that it is a second form after the C-based for(;;) -- there's no mention of 
 for(;;). Rather, it is that for (v in [1,2,3]) fails to iterate 1,2,3, instead 
enumerating 0,1,2.

We can't satisfy this Pythonic expectation directly, but with meta-programmable 
for-in, users and library authors can help themselves, using keys, values, and 
other iterator factory functions.


  Further complicating it feels like it would be a pedagogical nightmare.

I think this is exaggerated -- there's really no relation to for(;;), and the 
first-year students move up and on.

The nightmare of unprogrammable for-in, if I may use that word, is both the 
non-interoperable mess of for-in today in ES3-ES5-level browsers, plus the 
enumerate trap of tomorrow -- never mind an iterate trap. But most programmers 
do not need to know about proxies.

So weigh the nightmares by how many students reach JS grad school, where they 
learn about proxies at all.

And give some weight to middling students of the future libraries, who will be 
able to for-in over array and other array-like objects' values. The C-style for 
(var i=0; i  a.length; i++) { var v = a[i]; ... } alternative-nightmare would 
be vanquished by the dawn of for (var v in values(a)) { ... }.

This is all kind of fluffy, on both sides of our argument. Are we really 
concerned about cognitive load of for (;;) vs. for-in? That ship sailed long 
ago and I argue it's as likely that meta-programmable for-in heals the rift, as 
it is that iterate on top of enumerate makes a new rift.

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


Re: Nov 18 notes

2010-11-22 Thread Oliver Hunt
 The most frequent (in my hearing) unsatisfied expectation of users of for-in 
 is not that it is a second form after the C-based for(;;) -- there's no 
 mention of  for(;;). Rather, it is that for (v in [1,2,3]) fails to iterate 
 1,2,3, instead enumerating 0,1,2.
 
 We can't satisfy this Pythonic expectation directly, but with 
 meta-programmable for-in, users and library authors can help themselves, 
 using keys, values, and other iterator factory functions.

Library authors can't really do this without providing their own array classes, 
modifying the array prototype would be too dangerous in a web environment to be 
done by a library as it would not work with other code that may expect current 
for-in behaviour, same applies to NodeList's, etc in the DOM.  This is another 
reason i'm in favour of a different syntax - we could make it iterate values as 
people expect.

 Further complicating it feels like it would be a pedagogical nightmare.
 
 I think this is exaggerated -- there's really no relation to for(;;), and the 
 first-year students move up and on.
 
 The nightmare of unprogrammable for-in, if I may use that word, is both the 
 non-interoperable mess of for-in today in ES3-ES5-level browsers, plus the 
 enumerate trap of tomorrow -- never mind an iterate trap. But most 
 programmers do not need to know about proxies.

I am most concerned about this making for-in much more complicated;  Yes python 
has had meta-programmable objects forever (give or take a few years :D) which 
shows people can understand the behaviour, but the default behaviour exhibited 
in python is different, and more in line with what people expect.  By changing 
for(in) behaviour in harmony you're trying to give python like meta-programming 
but with less than ideal defaults for new developers, and confusion for 
experienced developers.

I think the other problem i have is that what people really seem to want is 
value enumeration of arrays (and array-likes), and by re-using the syntax you 
basically ensure that at the very least arrays (and other array-likes) will 
never get that behaviour by default.  In addition to that it would be very 
dangerous for any library to override the iterate trap as libraries want to 
interact well with other libraries, and also provide a consistent development 
environment across multiple engines and versions.  That leads me to expect that 
libraries would not override the enumerate trap.

If we had a new syntax, in addition to allowing meta-programming from the 
get-go, we could also provide default enumerate traps for arrays, etc that is 
inline with what people expect.

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


Re: Nov 18 notes

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 7:07 PM, Oliver Hunt wrote:

 The most frequent (in my hearing) unsatisfied expectation of users of for-in 
 is not that it is a second form after the C-based for(;;) -- there's no 
 mention of  for(;;). Rather, it is that for (v in [1,2,3]) fails to iterate 
 1,2,3, instead enumerating 0,1,2.
 
 We can't satisfy this Pythonic expectation directly, but with 
 meta-programmable for-in, users and library authors can help themselves, 
 using keys, values, and other iterator factory functions.
 
 Library authors can't really do this without providing their own array 
 classes, modifying the array prototype would be too dangerous

Modifying the array prototype isn't relevant here (proxies on the prototype do 
not iterate, they enumerate -- see prior mail with js shell session excerpts). 
Not sure what you mean if not this -- adding methods to Array.protoype? 
PrototypeJS does this.


 in a web environment to be done by a library as it would not work with other 
 code that may expect current for-in behaviour, same applies to NodeList's, 
 etc in the DOM.

I think you're arguing against something not proposed.

for (var v in values(a)) ...

requires no prototype monkeypatching. Somehow inserting a proxy with a handler 
having an iterate trap at the front of the Array.prototype chain won't work as 
noted already. If you thought I meant this:

for (var v in [1,2,3]) print(v);

printing 1 2 3, as I wrote in words cited at the top of this message We can't 
satisfy this Pythonic expectation directly. Something like values would need 
to be called around the [1,2,3].


  This is another reason i'm in favour of a different syntax - we could make 
 it iterate values as people expect.

I'm sure you are in favor of different syntax, but the argument you just made 
doesn't support that and it seems to have been based on a misunderstanding.


 Further complicating it feels like it would be a pedagogical nightmare.
 
 I think this is exaggerated -- there's really no relation to for(;;), and 
 the first-year students move up and on.
 
 The nightmare of unprogrammable for-in, if I may use that word, is both the 
 non-interoperable mess of for-in today in ES3-ES5-level browsers, plus the 
 enumerate trap of tomorrow -- never mind an iterate trap. But most 
 programmers do not need to know about proxies.
 
 I am most concerned about this making for-in much more complicated;  Yes 
 python has had meta-programmable objects forever (give or take a few years 
 :D) which shows people can understand the behaviour, but the default 
 behaviour exhibited in python is different, and more in line with what people 
 expect.  By changing for(in) behaviour in harmony you're trying to give 
 python like meta-programming but with less than ideal defaults for new 
 developers, and confusion for experienced developers.

Let's not argue by asserting who will be confused. I've already replied to 
Allen that the sword has two edges, one pointed away from skilled programmers. 
It's simply selective arguing to say only bad things happen in one direction. 
You can get cut; you can cut someone not intended. The issue is not whether 
for-in should be meta-programmable -- Proxy has an enumerate trap -- but how 
much.


 I think the other problem i have is that what people really seem to want is 
 value enumeration of arrays (and array-likes), and by re-using the syntax you 
 basically ensure that at the very least arrays (and other array-likes) will 
 never get that behaviour by default.

If we wanted to change Harmony's runtime semantics to be even less compatible 
than it is with no global object, we could wave a spec-wand and do that. Why 
don't we? The reasons won't go away.

The best we can do in any mostly-compatible spec edition is add new forms, 
whether syntax or API, and see if the cows beat new paths.

Dave's early message then observed that if all the developer cows happily use 
the new iteration form, the old one is basically dead. Reforming for (var v in 
[1,2,3]) at that very late date to iterate over values, assuming such a 
compatibility break is acceptable, simply won't matter by the premise: the cows 
moved to the new field.


  In addition to that it would be very dangerous for any library to override 
 the iterate trap as libraries want to interact well with other libraries,

You can't override the iterate trap. Handlers are stratified and encapsulated. 
This is basic to the harmony:proxies design.


 and also provide a consistent development environment across multiple engines 
 and versions.  That leads me to expect that libraries would not override the 
 enumerate trap.

Do you mean wrap a proxy with a different proxy having a different enumerate or 
iterate trap? Wrapping is not overriding. No mutation, different object 
identities.

I'm worried we are talking past each other now.


 If we had a new syntax, in addition to allowing meta-programming from the 
 get-go, we could also provide default enumerate traps 

Re: Nov 18 notes

2010-11-22 Thread Maciej Stachowiak

On Nov 21, 2010, at 7:05 PM, Brendan Eich wrote:

 On Nov 18, 2010, at 4:08 PM, Waldemar Horwat wrote:
 
 Consensus that we should have iterators.
 
 For this, after all these years (JS1.7 added meta-programmable for-in in 
 2006), I'm grateful, although I wanted to add something your notes did not 
 report:
 
 To get consensus, we made a tentative agreement to leave for-in as it was and 
 not enable any meta-programmability of it, consigning it to the 
 historically-underspecified and non-interoperable enumeration mystery-meat 
 status.
 
 Instead, we did the committee-plays-it-safe thing of inventing new syntax for 
 meta-programmable iteration:
 
 for (var i : x) ...
 
 This is a break from Python and JS1.7+ in SpiderMonkey and Rhino -- although 
 it matches very late Java and C++ extensions that are similar (but not the 
 same), and really not relevant to JS.
 
 Worse, the use of colon in this new for syntax is confusingly similar to 
 long-standing future-proofing intentions around runtime type annotations (aka 
 guards or contracts).
 
 (BTW, I don't think :: is a good type annotation or guard punctuator, btw -- 
 it's the C++ namespace qualification operator, also specified for namespacing 
 by ECMA-357 (E4X) and used that way in ActionScript 3 (and in ES4, RIP). So I 
 was surprised to see :: used for annotation-like syntax in 
 http://wiki.ecmascript.org/doku.php?id=strawman:guards and 
 http://wiki.ecmascript.org/doku.php?id=strawman:trademarks.)
 
 for (var i : x) ...  // must be new iteration
 for (var i : T : x) ...  // iteration again, but parsed how?
 for (var i : T in x) ... // for-in with annotated var
 
 Depending on what T might be, grammatically, this could get sticky for 
 top-down parsers. It is confusing and ugly in any event, IMHO.
 
 Probably we need to take our time and not rush into a meta-programming-here 
 syntax variant of for-in. I'll not propose anything better right now.

If the colon is less future-compatible than we like, why not:

foreach (var i in x)

While for is slightly more common for a loop that iterates a container, 
foreach is also quite common, and indeed is often used to name the construct 
even in languages where the keyword is spelled for: 
http://en.wikipedia.org/wiki/Foreach.

This would allow us to reserve the colon, and also avoid a surprising change to 
the semantics of the existing for..in construct. It could even DTRT for arrays. 
Also, it will likely be easier for programmers to talk about the distinction 
between for..in loops and foreach..in loops than for..in loops and 
for..colon loops.

Regards,
Maciej


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


Re: Nov 18 notes

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 11:19 PM, Maciej Stachowiak wrote:

 Probably we need to take our time and not rush into a meta-programming-here 
 syntax variant of for-in. I'll not propose anything better right now.
 
 If the colon is less future-compatible than we like, why not:
 
 foreach (var i in x)

All the new words are not reserved, so they could begin a function call 
expression in extant code:

hi = there
foreach (i in x)
  print(i)

means

hi = there; foreach(i in x); print(i);

today. Same if you s/foreach/iterate/ or any non-reserved identifier. Wherefore 
Allen's co-opting of enum (plus with, a decent preposition given enum but 8 
chars in two keywords hurt kittens everywhere).

Anyway, the bikeshed is secondary. We need to agree on what meta-programmable 
for-in means with the enumerate trap (specified by the wiki pages on 
harmony:proxies), how that changes with the optional iterate trap 
(strawman:iterators), and when it might matter (for all for-in loops, or only 
those in Harmony code?).

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


Re: Nov 18 notes

2010-11-21 Thread Brendan Eich
On Nov 18, 2010, at 4:08 PM, Waldemar Horwat wrote:

 Consensus that we should have iterators.

For this, after all these years (JS1.7 added meta-programmable for-in in 2006), 
I'm grateful, although I wanted to add something your notes did not report:

To get consensus, we made a tentative agreement to leave for-in as it was and 
not enable any meta-programmability of it, consigning it to the 
historically-underspecified and non-interoperable enumeration mystery-meat 
status.

Instead, we did the committee-plays-it-safe thing of inventing new syntax for 
meta-programmable iteration:

for (var i : x) ...

This is a break from Python and JS1.7+ in SpiderMonkey and Rhino -- although it 
matches very late Java and C++ extensions that are similar (but not the same), 
and really not relevant to JS.

Worse, the use of colon in this new for syntax is confusingly similar to 
long-standing future-proofing intentions around runtime type annotations (aka 
guards or contracts).

(BTW, I don't think :: is a good type annotation or guard punctuator, btw -- 
it's the C++ namespace qualification operator, also specified for namespacing 
by ECMA-357 (E4X) and used that way in ActionScript 3 (and in ES4, RIP). So I 
was surprised to see :: used for annotation-like syntax in 
http://wiki.ecmascript.org/doku.php?id=strawman:guards and 
http://wiki.ecmascript.org/doku.php?id=strawman:trademarks.)

for (var i : x) ...  // must be new iteration
for (var i : T : x) ...  // iteration again, but parsed how?
for (var i : T in x) ... // for-in with annotated var

Depending on what T might be, grammatically, this could get sticky for top-down 
parsers. It is confusing and ugly in any event, IMHO.

Probably we need to take our time and not rush into a meta-programming-here 
syntax variant of for-in. I'll not propose anything better right now.

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


Re: Nov 18 notes

2010-11-21 Thread Brendan Eich
On Nov 21, 2010, at 7:21 PM, Chris Sells wrote:

 I'm a huge fan of iterators. As far as index goes, I'm not a fan of the use 
 of the colon. We should take our time, but something that I wanted to throw 
 into the pot would be to build on the key-based nature of for-in with syntax 
 like this:
 
 forvals ( var x in xs ) {...}
 
 Also, have we given any thought to making it easier to implement custom 
 iterators ala the C# yield return operator?

We've prototyped and shipped generators based on Python 2.5 (with a 
simplification that avoids introducing GeneratorExit) for years, in 
SpiderMonkey and Rhino. The yield operator is a low-precedence expression 
prefix whose presence in a function makes it a generator. Wiki link:

http://wiki.ecmascript.org/doku.php?id=strawman:generatorss=generators

This strawman wil be revised based on specific feedback (put something in the 
function preamble, not just yield expressions in the body, to make it clearly a 
generator, and the yield-in-try-with-finally argument), and prepared for 
discussion at the January 2011 TC39 meeting.

/be


 
 
 -Original Message-
 From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] 
 On Behalf Of Brendan Eich
 Sent: Sunday, November 21, 2010 7:05 PM
 To: Waldemar Horwat
 Cc: Mark S. Miller; es-discuss
 Subject: Re: Nov 18 notes
 
 On Nov 18, 2010, at 4:08 PM, Waldemar Horwat wrote:
 
 Consensus that we should have iterators.
 
 For this, after all these years (JS1.7 added meta-programmable for-in in 
 2006), I'm grateful, although I wanted to add something your notes did not 
 report:
 
 To get consensus, we made a tentative agreement to leave for-in as it was and 
 not enable any meta-programmability of it, consigning it to the 
 historically-underspecified and non-interoperable enumeration mystery-meat 
 status.
 
 Instead, we did the committee-plays-it-safe thing of inventing new syntax for 
 meta-programmable iteration:
 
 for (var i : x) ...
 
 This is a break from Python and JS1.7+ in SpiderMonkey and Rhino -- although 
 it matches very late Java and C++ extensions that are similar (but not the 
 same), and really not relevant to JS.
 
 Worse, the use of colon in this new for syntax is confusingly similar to 
 long-standing future-proofing intentions around runtime type annotations (aka 
 guards or contracts).
 
 (BTW, I don't think :: is a good type annotation or guard punctuator, btw -- 
 it's the C++ namespace qualification operator, also specified for namespacing 
 by ECMA-357 (E4X) and used that way in ActionScript 3 (and in ES4, RIP). So I 
 was surprised to see :: used for annotation-like syntax in 
 http://wiki.ecmascript.org/doku.php?id=strawman:guards and 
 http://wiki.ecmascript.org/doku.php?id=strawman:trademarks.)
 
 for (var i : x) ...  // must be new iteration
 for (var i : T : x) ...  // iteration again, but parsed how?
 for (var i : T in x) ... // for-in with annotated var
 
 Depending on what T might be, grammatically, this could get sticky for 
 top-down parsers. It is confusing and ugly in any event, IMHO.
 
 Probably we need to take our time and not rush into a meta-programming-here 
 syntax variant of for-in. I'll not propose anything better right now.
 
 /be
 ___
 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: Nov 18 notes

2010-11-21 Thread Brendan Eich
On Nov 21, 2010, at 7:21 PM, Chris Sells wrote:

 I'm a huge fan of iterators. As far as index goes, I'm not a fan of the use 
 of the colon. We should take our time, but something that I wanted to throw 
 into the pot would be to build on the key-based nature of for-in with syntax 
 like this:
 
 forvals ( var x in xs ) {...}

Resist bikeshedding early and all that, but there's already a strike against 
this or anything like it:

JS lacks run-together keywords apart from typeof and instanceof, which do not 
abbreviate as vals does.

In grasping for : instead of in, the committee was trying to keep the 
introductory keyword for. I think we had agreement that sticking with for 
is still worth using as a syntax design guide or back up and try another route 
forward [than 'in'] design point.

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


Re: Nov 18 notes

2010-11-21 Thread Brendan Eich
On Nov 21, 2010, at 7:41 PM, Brendan Eich wrote:

 On Nov 21, 2010, at 7:21 PM, Chris Sells wrote:
 
 I'm a huge fan of iterators. As far as index goes, I'm not a fan of the use 
 of the colon. We should take our time, but something that I wanted to throw 
 into the pot would be to build on the key-based nature of for-in with syntax 
 like this:
 
 forvals ( var x in xs ) {...}
 
 Resist bikeshedding early and all that, but there's already a strike against 
 this or anything like it:
 
 JS lacks run-together keywords apart from typeof and instanceof, which do not 
 abbreviate as vals does.
 
 In grasping for : instead of in, the committee was trying to keep the 
 introductory keyword for. I think we had agreement that sticking with for 
 is still worth using as a syntax design guide or back up and try another 
 route forward [than 'in'] design point.


And (sorry, I'll try to keep replies in one message next time) for vs. 
forvals does not exactly scream keys vs. values, since for is only 
about keys if you know ECMA-262 and expect the mystery meat of enumeration.

If we manage to make normative specifications for enumeration, which has been a 
goal recently, we'll still have for-in for that keys meaning. So there won' 
t be any keys : vals symmetry to play off of, just some longer or different 
syntax for meta-programmable iteration.

Which raises another point: meta-programmable iteration is not necessarily 
about values and not keys. A custom iterator could (and in the strawman 
does) return key/value pairs. The whole keys vs. values dilemma is a false one 
here.

/be

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


Re: Nov 18 notes

2010-11-21 Thread David Herman
 And (sorry, I'll try to keep replies in one message next time) for vs. 
 forvals does not exactly scream keys vs. values, since for is only 
 about keys if you know ECMA-262 and expect the mystery meat of enumeration.

IMO, forvals is a non-starter, as is foreach or for each. The for part 
of the syntax denotes quantification, and the stuff to the right of the 
variable denotes what is being iterated. In all cases, we are talking about 
universal quantification, so they should all be for.

 Which raises another point: meta-programmable iteration is not necessarily 
 about values and not keys. A custom iterator could (and in the strawman 
 does) return key/value pairs. The whole keys vs. values dilemma is a false 
 one here.

Indeed. There are an unbounded number of types of sequences that can be 
iterated over. Whether we provide 2 or 200 it will never be enough. Hence the 
need for a general, programmable iteration mechanism.

Dave

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