Re: Guards are now ready for discussion (was: Nov 18 notes)

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

 On Mon, Nov 22, 2010 at 6:54 AM, Brendan Eich bren...@mozilla.com wrote:
 
 The ML-ish solution, which is forward compatible, is to parenthesize:
 
 let typedObj = { (prop1:type1): value1, (prop2:type2): value2, ... };
 
 The parentheses hurt too, but only this case. And it still may win to 
 annotate the entire ObjectLiteral sometimes, which would avoid (or move to 
 one common guard-type definition) the property-wise annotation overhead. 
 Comments?
 
 I wouldn't want to introduce forced parens for the sake of disambiguation for 
 the coder. I'd rather go with ::, # or @ ...

Those are not all equally good, and you're again sacrificing the common case 
(especially with ::) where there's no need to parenthesize, for the uncommon 
case of property-wise type annotation in an object initialiser.

Actually, one can use : just fine in an initialiser provided one or two colons 
are required per property initialiser. There's no need for :: or anything else 
except to avoid a confusing re-use of colon. Which is an issue, but :: doesn't 
exactly address it!

Fundamenally, though, you have to weight each use-case by frequency. If as I 
argue var x : T, function f(a: T, b: U): V {...}, etc. annotations dominate the 
rare var typedObj = ... case, then parens or whatever is needed (even a 
separated type annotation for the whole initialiser, as in ES4) is worth it.


 Actually, for object literal I'd go for an equal sign (=), but that obviously 
 won't fix var declarations where the colon is fine.

We're not changing object initialiser syntax.


 Can't the guards proposal be applied to function parameters as well? Or am I 
 stepping on land mines there? :) It seems like the same logic could be 
 applied. In that case the equal sign is maybe even more preferable.

What are you proposing = be used for, if not default parameter values (see the 
wiki) or assignment? No way does = make sense for type annotation.

But yes: type annotation (guard, contract, whateve -- not static types but 
that's not at issue) should be possible for function parameters, return types, 
local variables, let bindings, catch vars, etc.

/be

___
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: Guards are now ready for discussion (was: Nov 18 notes)

2010-11-22 Thread Peter van der Zee
On Mon, Nov 22, 2010 at 9:43 AM, Brendan Eich bren...@mozilla.com wrote:

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

 On Mon, Nov 22, 2010 at 6:54 AM, Brendan Eich bren...@mozilla.com wrote:


 The ML-ish solution, which is forward compatible, is to parenthesize:

 let typedObj = { (prop1:type1): value1, (prop2:type2): value2, ... };

 The parentheses hurt too, but only this case. And it still may win to
 annotate the entire ObjectLiteral sometimes, which would avoid (or move to
 one common guard-type definition) the property-wise annotation overhead.
 Comments?


 I wouldn't want to introduce forced parens for the sake of disambiguation
 for the coder. I'd rather go with ::, # or @ ...


 Those are not all equally good, and you're again sacrificing the common
 case (especially with ::) where there's no need to parenthesize, for the
 uncommon case of property-wise type annotation in an object initialiser.

 Actually, one can use : just fine in an initialiser provided one or two
 colons are required per property initialiser. There's no need for :: or
 anything else except to avoid a confusing re-use of colon. Which is an
 issue, but :: doesn't exactly address it!


As you noted yourself in the other thread, if iterators take on the syntax
of `for (var x : y : z)`, the single colon for guards would introduce
ambiguity. (And I believe :: could fix that?)




 Fundamenally, though, you have to weight each use-case by frequency. If as
 I argue var x : T, function f(a: T, b: U): V {...}, etc. annotations
 dominate the rare var typedObj = ... case, then parens or whatever is needed
 (even a separated type annotation for the whole initialiser, as in ES4) is
 worth it.


 Actually, for object literal I'd go for an equal sign (=), but that
 obviously won't fix var declarations where the colon is fine.


 We're not changing object initialiser syntax.



 Can't the guards proposal be applied to function parameters as well? Or am
 I stepping on land mines there? :) It seems like the same logic could be
 applied. In that case the equal sign is maybe even more preferable.


 What are you proposing = be used for, if not default parameter values (see
 the wiki) or assignment? No way does = make sense for type annotation.


I'm sorry, I did mean = for guard. But reading it back, you are right; it
doesn't make sense.


 But yes: type annotation (guard, contract, whateve -- not static types but
 that's not at issue) should be possible for function parameters, return
 types, local variables, let bindings, catch vars, etc.

 /be


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


Re: Guards are now ready for discussion (was: Nov 18 notes)

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

 On Mon, Nov 22, 2010 at 9:43 AM, Brendan Eich bren...@mozilla.com wrote:
 On Nov 22, 2010, at 12:37 AM, Peter van der Zee wrote:
 
 On Mon, Nov 22, 2010 at 6:54 AM, Brendan Eich bren...@mozilla.com wrote:
 
 The ML-ish solution, which is forward compatible, is to parenthesize:
 
 let typedObj = { (prop1:type1): value1, (prop2:type2): value2, ... };
 
 The parentheses hurt too, but only this case. And it still may win to 
 annotate the entire ObjectLiteral sometimes, which would avoid (or move to 
 one common guard-type definition) the property-wise annotation overhead. 
 Comments?
 
 I wouldn't want to introduce forced parens for the sake of disambiguation 
 for the coder. I'd rather go with ::, # or @ ...
 
 Those are not all equally good, and you're again sacrificing the common case 
 (especially with ::) where there's no need to parenthesize, for the uncommon 
 case of property-wise type annotation in an object initialiser.
 
 Actually, one can use : just fine in an initialiser provided one or two 
 colons are required per property initialiser. There's no need for :: or 
 anything else except to avoid a confusing re-use of colon. Which is an issue, 
 but :: doesn't exactly address it!
 
 
 As you noted yourself in the other thread, if iterators take on the syntax of 
 `for (var x : y : z)`, the single colon for guards would introduce ambiguity. 
 (And I believe :: could fix that?)

First, I did not argue that there was a formal grammar ambiguity. There may not 
be, but it still is ugly and confusing.

Second, you're arguing backwards -- we do not have for (x : z) today, it is not 
obvious we should add it to the language, so it does not follow that we must 
use :: for type annotations. The precedent for : as type annotation punctuator 
is stronger than the precedent for :: in the same role; meanwhile, from E4X and 
AS3 and other old-ES4 offshoots, we have :: for namespace qualification (C++ 
has that too). So :: is just wrong all around.

Before reaching in a reactive way for @, let's slow down and consider what got 
us here: over-eager bikeshedding of : instead of in to try to split for-in 
into two loops, to make programmers prejudge whether they want enumeration or 
something potentially meta-programmable (but not necessarily -- we did not 
decide that for (x : z) fails if z is not a proxy with an iterate trap, and 
that doesn't make much sense).

So as dherman pointed out, we're really just trying to replace for-in with 
for-: as the new for-in. But if the syntax is ugly and confusion, if not 
ambiguous, and if the new form won't work in old browsers anyway, what good are 
we doing? Defending against someone porting or mixing JS code into Harmony 
context and having a for-in loop that expects string keys fail because it got 
Fibonacci numbers?

/be

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


Re: instanceof trap - Useful to implement promises through proxies

2010-11-22 Thread Tom Van Cutsem
Ok, I see. So it's true that the current Proxy API doesn't support promises
that would throw on instanceof when unresolved and return a boolean when
resolved. The main reason is that we didn't want proxies to meddle with the
inheritance chain, in particular giving proxies the ability to implement
dynamic inheritance. While intercepting instanceof doesn't truly introduce
dynamic inheritance in the language, you could definitely create proxies
that are `instanceof` prototypes from unrelated hierarchies, which could
spell trouble.

If the prototype or constructor function of the to-be-calculated value of a
promise is known to the promise creator, it is possible to make `instanceof`
work somewhat sensibly for promises:

var pet = promiseFor(Cat); // promise implementor can now write:
Proxy.create(Cat.prototype, ...)
...
// assume pet is still unresolved:
pet instanceof Cat // true since the promise proxy already has the correct
prototype

I said somewhat sensibly since this may or may not be the behavior you'd
want for unresolved promises.

Note that even the proposed instanceof trap would not help if the
constructor function (Cat in the above example) is not in bed with the
promise abstraction, since `obj instanceof F` would trap on F's handler, not
on obj's handler. If F is a promise-aware function proxy, it could then
check whether obj is an unresolved promise and throw. But it would require
user code to write at least:

Cat = PromiseAwareWrapperFor(function () { ... }); // declare that my
instances can be promises

Cheers,
Tom

2010/11/19 Sebastian Markbåge sebast...@calyptus.eu

 Hi Tom,

 The idea here is that it's obj that's the proxy/promise.

 For example:

 var pet = future();

 var closure = function(){
   return pet instanceof Cat;
 };

 resolve(pet); // later

 closure(); //?

 I should've clarified that it's the [Prototype] of pet that needs to be
 delayed. Not prototype of Cat. It may be resolved to any number of different
 prototype chains depending on how the future/promise is resolved.

 Sebastian

 On Fri, Nov 19, 2010 at 4:38 PM, Tom Van Cutsem tomvc...@gmail.comwrote:

 Hi Sebastian,

 Could you clarify why trapping instanceof is required for promises? It
 seems your use case can be addressed already using the current Proxy API: if
 `FP` is a function proxy, then `obj instanceof FP` will query `FP` for its
 `prototype` property (as per the default algorithm) by calling the function
 proxy's `get` trap. Inside that `get` trap, you could check whether the
 prototype is unresolved or far and if so, throw an exception.

 Cheers,
 Tom

 2010/11/18 Sebastian Markbåge sebast...@calyptus.eu

 I thought I'd make the case for the instanceof trap
 in strawman:proxy_extensions - beyond multiple inheritance. I'm sure this
 point has been made before at some point.

 This is useful to implement various forms of promises using proxies. The
 prototype can be resolved at a later time perhaps after some IO or lazy
 operation. This should be able to fail if the promise is currently
 unresolved or far.

 It's the final piece missing to preserve the invariants that keep the JS
 lucid dream.

 I'm also curious to hear any objections to this proposal. I don't see the
 same issues as with mutable prototypes being applicable to proxies.

 Sebastian Markbåge

 ___
 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 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: Guards are now ready for discussion (was: Nov 18 notes)

2010-11-22 Thread Mark Miller
On Mon, Nov 22, 2010 at 12:37 AM, Peter van der Zee e...@qfox.nl wrote:


 Can't the guards proposal be applied to function parameters as well? Or am
 I stepping on land mines there? :)


Yes. Please look at the guards strawman. It's in there.

-- 

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


Re: Guards are now ready for discussion (was: Nov 18 notes)

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 5:42 AM, Mark S. Miller wrote:

 On Mon, Nov 22, 2010 at 1:09 AM, Brendan Eich bren...@mozilla.com wrote:
 [...] Before reaching in a reactive way for @, let's slow down and consider 
 what got us here: over-eager bikeshedding of : instead of in [...]
 
 That's not what got me here. For me the issue is uniformity of guard syntax 
 across all contexts where we need them -- including properties of object 
 literals. I agree it is the uncommon case. But the non-uniformity of using 
 one syntax for this case and another syntax for the more common cases bugs 
 me. Likewise, the technically unambiguous
 
 { foo : G : 33 }
 
 I find too visually confusing and ugly.

Agreed. My point in reply to Peter was that it may be formally unambiguous, but 
it's still ugly and confusing.


 As you are fond of saying, notation is user interface.

And how! But doubling a colon is not better interface. Especially when that 
double-tax hits all declarations, not just object initialisers.

Let's see if I can write down some alternatives and list trade-offs:

0. let typedObj = { foo : 33 } : { foo : G }; // a la ES4

1. let typedObj = { foo :: G : 33 };  // the guards strawman

2. let typedObj = { (foo : G) : 33 }; // the ML-ish way

3. let typedObj = { foo @ G : 33 };   // funny cartoon chars

Trade-offs:

0+ avoids running type^H^H^H^Hguard together with property name and value using 
:, ::, @, or whatever, instead paralleling the whole initialiser

0+ allows commoning the guard initialiser expression so it can be reused among 
multiple object value initialisers

0- parallel structure duplicates all property names (and order? not clear), 
which is tedious at any scale and error-prone for large initialisers

1+ avoids restating names (and order?)

1- imposes double-colon tax on all annotation contexts, even though only this 
one wants it for visual distinctiveness (not disambiguation of formal grammar)

1- :: is an eyesore (yet arguably not distinct enough from single : -- see last 
1- item), and has quite different precedent as namespace qualification operator 
in Ecma and other standards

2+ keeps : as annotation punctuator

2- at the price of parenthesizing the property name in object initialisers

3+ avoids overloading colon in object initialisers

3- flouts programming language (including JS derivatives) precedent for using : 
as annotation punctuator

3- may collide with JScript's preprocessor, also may collide with @attributes 
in E4X, uses up @ in a novel way where we might want to reserve it for another 
use

Comments:

We don't have too many other funny chars (# is wanted for concise function 
syntax). This suggests trying to use : and not breaking the common annotation 
case over this initialiser hard case.

Sometimes a (commoned, reusable) annotation at the end of the whole object 
initialiser is pure win. It's really not clear at this point that *only* at the 
end, or *only* interspersed guards, are the one way we should standardize.

If guards are uncommon in object initialisers, parenthesization is arguably 
fine, not only as a tax users can pay but as a visual flag that something is up.

Let's consider the likely far more common use-cases:

var x : T = v;

function f(a: U, b: V): W {...}

... { ... let x : T = v; ... }

while @ or another char could work, the tradition favoring : combined with the 
scarcity of unused punctuators makes me want to stick with colon. That, plus 
the relative rarity of annotated initialisers (in my best guess -- we can argue 
about this or try to estimate by adding guards to existing code), make me still 
favor (2).

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


Re: Guards are now ready for discussion (was: Nov 18 notes)

2010-11-22 Thread P T Withington
On 2010-11-22, at 13:13, Brendan Eich wrote:

 That, plus the relative rarity of annotated initialisers (in my best guess -- 
 we can argue about this or try to estimate by adding guards to existing 
 code), make me still favor (2).

The idea of guards as adjectives (ala C) is a non-starter?

Would keyword arguments ever be added to JS?  Any chance that would influence 
the choices made here?


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


Re: Guards are now ready for discussion (was: Nov 18 notes)

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 10:58 AM, P T Withington wrote:

 On 2010-11-22, at 13:13, Brendan Eich wrote:
 
 That, plus the relative rarity of annotated initialisers (in my best guess 
 -- we can argue about this or try to estimate by adding guards to existing 
 code), make me still favor (2).
 
 The idea of guards as adjectives (ala C) is a non-starter?

That is awkward if you do require a leading var/let/const in addition to the 
annotation:

  var Int32Like i = 0;

and we don't want to reserve the names of all possible guards.

Also, guards or runtime types are not static types, so it seems better to avoid 
reusing type declarator order from static languages in the C family.

Functions are easier to extend this way:

  function foo(MyGuardA a, MyGuardB b) GuardForReturnValue { ... }

but the point about not copying type-then-declarator stands.


 Would keyword arguments ever be added to JS?  Any chance that would influence 
 the choices made here?

Imponderable unless we reserve : in call expressions such as

foo(arg1: val1, arg3: val3);

to mean named formal parameter association -- keyword arguments if I understand 
what you meant by that. Yet this is both too close to an object initialiser, 
and also not ambiguous with annotations in declarations. This is an expression, 
not a declaration.

/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

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: Guards are now ready for discussion (was: Nov 18 notes)

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

 Would keyword arguments ever be added to JS?  Any chance that would 
 influence the choices made here?
 
 Imponderable unless we reserve : in call expressions such as
 
 foo(arg1: val1, arg3: val3);
 
 to mean named formal parameter association -- keyword arguments if I 
 understand what you meant by that. Yet this is both too close to an object 
 initialiser

by which I mean: what's the point? Just pass an object initialiser to a 
function that destructures it. Can be optimized to avoid constructing an 
object, in advanced implementations. But whatever the optimization, the 
language is crowded if we have both of

foo(arg1: val1, arg3: val3);

and today's works-in-all-browsers form:

foo({arg1: val1, arg3: val3});

Is losing the braces really worth the added complexity?

/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: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: Guards are now ready for discussion (was: Nov 18 notes)

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

 Is losing the braces really worth the added complexity?

Perhaps not.  Braces are surely as good a way to denote keyword args as any 
other flag.  It occurred to me that there is no equivalent of object literals 
in the languages I know that have keyword arguments.  There are strong 
parallels, which is probably why the discussion of the guarded literal syntax 
brought it to my mind.  But that makes me wonder how I would write a function 
with keyword arguments that were both guarded and had default values?

  function f (a:V, b:W=w {c:X=x, d:Y=y}) ...

or, the less parallel:

  function f (a:V, b:W=w {(c:X):x, (d:Y):y}) ...



___
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 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


Colons and other annotative characters

2010-11-22 Thread Waldemar Horwat

On 11/22/10 10:13, Brendan Eich wrote:

 { foo : G : 33 }


0. let typedObj = { foo : 33 } : { foo : G }; // a la ES4

1. let typedObj = { foo :: G : 33 };  // the guards strawman

2. let typedObj = { (foo : G) : 33 }; // the ML-ish way

3. let typedObj = { foo @ G : 33 };   // funny cartoon chars


Good list.  Out of those five, the only one I'd find compelling would be the 
first:

{ foo : G : 33 }

Alternatives 0, 1, and 3 have the problems that were already well-stated.  2 
has strange placement of parentheses.

If we're brainstorming, I'd throw out an alternative for the object initializer 
syntax:

{name: value}   // What we have now, for compatibility
{name = value}  // Identical behavior to {name: value}
{name: type = value}  // Adding a type annotation

If we're looking at other ASCII characters for type annotations, a few other 
characters such as the backtick might be an option:

{name`type: value}
{name!type: value}
{name%type: value}
{name~type: value}

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


Re: Colons and other annotative characters

2010-11-22 Thread Mike Shaver
I'd expect that

o = { a : b = 5 }

Was legal now, setting both o.a and b to 5.  Not at a shell, is there an
exception in the grammar for assignment expressions in the value position?

{ a = 5 : T } might work, though.

Mike
 On Nov 22, 2010 6:09 PM, Waldemar Horwat walde...@google.com wrote:
 On 11/22/10 10:13, Brendan Eich wrote:
 { foo : G : 33 }

 0. let typedObj = { foo : 33 } : { foo : G }; // a la ES4

 1. let typedObj = { foo :: G : 33 }; // the guards strawman

 2. let typedObj = { (foo : G) : 33 }; // the ML-ish way

 3. let typedObj = { foo @ G : 33 }; // funny cartoon chars

 Good list. Out of those five, the only one I'd find compelling would be
the first:

 { foo : G : 33 }

 Alternatives 0, 1, and 3 have the problems that were already well-stated.
2 has strange placement of parentheses.

 If we're brainstorming, I'd throw out an alternative for the object
initializer syntax:

 {name: value} // What we have now, for compatibility
 {name = value} // Identical behavior to {name: value}
 {name: type = value} // Adding a type annotation

 If we're looking at other ASCII characters for type annotations, a few
other characters such as the backtick might be an option:

 {name`type: value}
 {name!type: value}
 {name%type: value}
 {name~type: value}

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


Re: Colons and other annotative characters

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 3:08 PM, Waldemar Horwat wrote:

 On 11/22/10 10:13, Brendan Eich wrote:
 { foo : G : 33 }
 
 0. let typedObj = { foo : 33 } : { foo : G }; // a la ES4
 
 1. let typedObj = { foo :: G : 33 };  // the guards strawman
 
 2. let typedObj = { (foo : G) : 33 }; // the ML-ish way
 
 3. let typedObj = { foo @ G : 33 };   // funny cartoon chars
 
 Good list.  Out of those five, the only one I'd find compelling would be the 
 first:
 
 { foo : G : 33 }
 
 Alternatives 0, 1, and 3 have the problems that were already well-stated.  2 
 has strange placement of parentheses.

Parens do hurt, I always thought so -- I find 2 the least evil of 0-3 though.


 If we're brainstorming, I'd throw out an alternative for the object 
 initializer syntax:
 
 {name: value}   // What we have now, for compatibility
 {name = value}  // Identical behavior to {name: value}
 {name: type = value}  // Adding a type annotation

Isn't the last ambiguous with legal JS today (well, with const, but that's not 
important AFAICT):

js const T = {}
js function f(x) { return {p: T = x}; }   
js o = f(42)
({p:42})

ES5 strict mode is the basis for Harmony, so the assignment would be an early 
error, but are guard bindings required to be const?


 If we're looking at other ASCII characters for type annotations, a few other 
 characters such as the backtick might be an option:
 
 {name`type: value}
 {name!type: value}
 {name%type: value}
 {name~type: value}

Do you mean only for initialisers, or for all declarations. In a var x!T = v; 
example, he unary operator (! or ~) seems problematic here in light of ASI 
unless the production is restricted before the operator.

% as mod has some metaphorical appeal but really, these all seem like Perlish 
line noise compared to colon.

/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: Colons and other annotative characters

2010-11-22 Thread Waldemar Horwat

On 11/22/10 15:16, Brendan Eich wrote:

{name: type = value}  // Adding a type annotation


Isn't the last ambiguous with legal JS today (well, with const, but that's not 
important AFAICT):


Yeah, you're right.  This won't work.

Waldemar
___
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: Colons and other annotative characters

2010-11-22 Thread Andreas Gal

I think there is too much fear of changing the semantics of for-in. Its 
semantics is already rather fuzzy. Allowing meta-programmability of for-in 
(instead of creating a new for-:) syntax doesn't create any additional 
surprises or hazards for JS programmers.

1. We have already agreed on an enumerate() hook which is triggered by 
traditional for-in. It returns a list of strings, but those are not necessarily 
keys.
2. enumerate() can contain arbitrary JS code, so for-in can already trigger all 
sorts of random behavior, and people seem to be comfortable with it.
3. iterate() is a natural extension of enumerate(). As enumerate(), it should 
be triggered by for-in. The only difference to the proxy enumerate trap is that 
iterate() doesn't eagerly force the creation of the list of values to be 
returned, which may not be possible for very large meta objects (databases, 
i.e.).

Its seems entirely random to cut off between 2) and 3). We are fine with 
enumerate(), but iterate() is somehow evil? The only see 2 semantic differences 
between the outcomes of enumerate() and iterate().
a) enumerate guarantees that all values are strings
b) enumerate guarantees that all strings are unique

So it seems that some people feel that unique strings is an appropriate 
approximation for keys.

There isn't much I can say about a). I think it would be more flexible and 
future-proof to allow non-string return values from iterators, but if we have 
to stringify non-string values returned from iterators, I could live with that.

As for b), the guarantees for it are already extremely weak. With proxies one 
can already today write code that breaks the uniqueness assumption of for-in.

function visit_keys(obj, f) {
for (i in obj)
f(i);
}

visit_keys(obj, function(i) { delete obj.i; obj.i = 1; })

From my understand of the spec, a spec-conformant implementation is allowed to 
endless-loop on this code, continuously returning the same property name. So 
why do we cling to uniqueness where it doesn't exist in the first place?

Executive summary: iterate() is equivalent to enumerate(), both should work 
with for-in. We already agreed to accept enumerate, forcing iterate() into its 
own syntax is arbitrary. We can discuss sacrificing future-proofness and 
stringify return values of iterators, but rejecting iterators because they 
don't guarantee unique strings is bogus--that uniques doesn't exist elsewhere 
either.

Andreas

On Nov 22, 2010, at 3:40 PM, Waldemar Horwat wrote:

 On 11/22/10 15:16, Brendan Eich wrote:
 {name: type = value}  // Adding a type annotation
 
 Isn't the last ambiguous with legal JS today (well, with const, but that's 
 not important AFAICT):
 
 Yeah, you're right.  This won't work.
 
Waldemar
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

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


Re: 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: Colons and other annotative characters

2010-11-22 Thread Brendan Eich
On Nov 22, 2010, at 4:07 PM, Andreas Gal wrote:

 Executive summary: iterate() is equivalent to enumerate(), both should work 
 with for-in. We already agreed to accept enumerate, forcing iterate() into 
 its own syntax is arbitrary. We can discuss sacrificing future-proofness and 
 stringify return values of iterators

Stringify return values of iterators *only* when for-in is driving the 
iteration (I'm sure you meant ;-).

I somehow suspect stringifying the iterator next() return value from for-in 
machinery will not placate folks who want for-in not to be metaprogrammable. 
But harmony:proxies is already spec'ed with an enumerate trap. Something does 
not add up. You're right that the line between your items (2) and (3) is 
arbitrary.

BTW, I found a v8 implementation of proxies by Sam Shull, via TomVC's site:

https://github.com/brickysam26/node-proxy/tree/master/src/

Thought I'd pass that on along to es-discuss to make up for the usual 
interminable iteration arguments :-P.

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


Re: Colons and other annotative characters

2010-11-22 Thread David Herman
 I somehow suspect stringifying the iterator next() return value from for-in 
 machinery will not placate folks who want for-in not to be metaprogrammable.

Nor would it work -- you wouldn't be able to get the values() or properties() 
iteration behavior, for example. It would be the worst of all possible 
compromises.

 But harmony:proxies is already spec'ed with an enumerate trap. Something does 
 not add up. You're right that the line between your items (2) and (3) is 
 arbitrary.

Agreed.

Dave

___
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 an 

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 

`static` keyword from C/C++ as own closured var declaration

2010-11-22 Thread Bga
// es3 way
(function()
{
  var x = 1;
 
  return function()
  {
return ++x;
  }
})();

// current es6/SM1.8 way
let(x = 1) function()
{
  return ++x;
}

// new more readable sugar
function()
{
  static x = 1; // hello c/c++
 
  return ++x;
}

Implementation, when compiling source code, just collects 'static' vars
from scope and wraps current scope to closure scope with collected vars  




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


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