Fw: [WebIDL] summary of topics discussed at TC39 meeting

2010-11-23 Thread Cameron McCormack
[Please follow up to public-script-co...@w3.org, thanks.]

- Forwarded message from Cameron McCormack  -

From: Cameron McCormack 
Date: Wed, 24 Nov 2010 15:54:38 +1300
To: public-script-co...@w3.org
Subject: [WebIDL] summary of topics discussed at TC39 meeting
Organization: Mozilla Corporation
Archived-At: 

Here is a summary of the Web IDL-related topics that were discussed at
the TC39 meeting last week.  Corrections to my mis-rememberings/notings
welcome.  I expect various topics will generate discussion, so please
change the subject line if replying to a particular topic!


= Spec organisation =

There was concern primarily from MS people that having the ECMAScript
semantic extensions (i.e., custom [[DefineOwnProperty]], etc.) simply
woven through the text without explicitly calling them out as extensions
would (1) lead to spec writers using these features even though they
exist only to help define legacy features, and (2) make it hard for TC39
people to know what the set of extensions are so that eventually some of
them may come to be supported by the ECMAScript language itself.

I agreed to do some editorial work to make these extensions clear.

Another request was to link to real world examples for IDL features
where they exist, which is reasonable enough.  (Although it may not be
the case that all features will be used by the time Web IDL will need to
be frozen for publication.)


= Modules =

I had wondered whether the module construct should be hooked up to the
proposed ES Harmony module system.  We agreed this would be premature.

Modules at the moment won’t have an effect in the ECMAScript binding
(unless [NamespaceObject] is specified – this is being used by the BONDI
folks, IIRC).  Since the module story for ES is not yet straight, and
all existing web specifications expect interface objects to go on the
global object, I think I’m ready to suggest that spec writers using Web
IDL for web specifications not use modules at all for now.

One consideration is that Java interfaces for particular specs currently
need to be in particular packages – notably, DOM Events interfaces go in
org.w3c.dom.events and SVG interfaces go in org.w3c.dom.svg.  So far I
have seen no concrete benefit to this division, but for compatibility
with existing libraries these interfaces need to remain in those
packages.

When it comes to writing the next versions of DOM Events and SVG using
Web IDL, I suggest that prose be written to require the Java interfaces
be in their historical packages.  The IDL interfaces themselves wouldn’t
be placed within a module.


= Static members =

We discussed the desire to have static members, and there were no great
issues brought up with this.  We would allow them on both the “concrete”
and “abstract” interfaces.  As with constants, this would cause
properties to exist on the concrete interface’s interface object.


= Operation overloading =

There was a desire from everyone to simplify how overloading is
currently specified – perhaps to remove it altogether, if that is
possible.  I took an action to look into existing uses of overloading in
existing specifications, which I have begun and will post in more detail
about separately.


= Special operations =

There was mostly agreement that the special operations for getters,
setters, creators, deleters and callers are an anti-pattern – due to the
fact that they are un-JavaScripty (as a consequence of not being able to
be implemented by user script, at least without proxies) and because of
the collision issues with properties coming from prototypes – and should
be reserved for describing legacy APIs.  We would mark these as not
being suitable for new APIs.

There was a desire from some to allow Array to be subclassed in ES,
which would give a better foundation for the kinds of APIs like NodeList
and so on, which need to provide methods but also to expose a list of
values by index.  This would be the solution for new APIs wanting to
provide index getter kind of access to values (when it is eventually
worked on).


= int53_t and uint53_t =

There was not a strong objection to introducing these types.  It was
pointed out that ES might gain a 64-bit integer type (and bigints) in
the future, and that might cause 53-bit integer types to be irrelevant.
I think it was agreed that the harm isn’t significant, so if there is
demand for such types they can be introduced.

So: if anyone particularly wants these types for their specs
(IndexedDB?), let me know.


= Sequence and arrays =

People were happy with sequences except for the requirement on coercing
their elements to the right type when passing an Array (or some other
object with a length property) to an object expecting the sequence.  On
one hand, you’d like predictable coercion because the coercion can cause
side effects.  On the other hand, the Array might be very large, and the
operation you pass it to might only be intereste

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

2010-11-23 Thread Allen Wirfs-Brock
Thanks for the test examples.  They point out that there are situations that 
need to be dealt with that don't naturally arise if a programmer writes code 
using the basic desugaring previous suggested.   However, I don't seen 
anything that is insurmountable in terms of defining the semantics.  It also 
points out that in general we may not get away with just saying syntax x 
desugars into form y.  You have to consider what static semantic 
expectations that the use of syntax x is likely to create for the programmer 
and deal with those expectations.


More specific responses marked with AWB below.

Allen

-Original Message- 
From: Waldemar Horwat

...
It's substantially worse here.  If we adopt block-scope, we get:

function f(b) {
  if (b)
return 43;
  static x = 1;
  return x++;
}

If we adopt the block-scope recommendation, refactoring it to:

function f(b) {
  if (b)  {
return 43;
  } else {
static x = 1;
return x++;
  }
}

will do something completely different.

AWB: I don't see how this is substantially different from the same issue 
using block scoped let.  When adding or removing block levels you have to 
pay attention to whether you are including or excluding existing 
declarations in the block.  This is the sort of thing that refactoring tools 
are supposed to help with.




- To avoid breaking refactoring, you'd need to allow "static static",
"static static static", etc.
AWB: ?? examples?? BTW, isn't it the job of refactoring tools to address
issues like this. We shouldn't assume that JavaScript programmers will
always be restricted to dump editors.


See example above.  The local way to fix the refactoring is to turn it into:

function f(b) {
  if (b) {
return 43;
  } else {
static static x = 1;
return x++;
  }
}

The same issue arises if we make a different decision on how far "static" 
hoists, but the examples are slightly bigger.


AWB:  and you could also do the same for let let but I don't think anybody 
would seriously propose that.  A good refactoring tool will tell you if a 
refactoring is changing the semantics.  A better one would place the 
declaration at the appropriate block level to maintain the previous 
semantics.

---
...


- When do the initializers run? What if it's a static const?
AWB: Before entering the scope it is hoisted out of. For function scope
this would be specified as part of "variable instantiation". static
const behavior has same scope-hole rules as regular const.


I asked about static const because now you have the new problem of multiple 
entry into the scope that does the const initialization.


AWB: See example A below, and assume that "static const x" is just like 
"static x" except that no assignments to x are allowed other than by the 
initializer. The static const would still be hoisted and evaluated in order 
with the initializer using the static scope as the current environment when 
evaluating the initialization expression, just like for non-const static. 
It's all still linear.

--


- What happens if you have two of the functions above, each trying to
hoist its own "x" into the same scope? Under which conditions do the x's
stay separate, and under which ones do they become the same variable?
AWB: They are always separate. Each function gets its own static scope
that exists between the function and its enclosing scope. This is
illustrated in Bga's "ES3 way" desugaring.


So what should the following examples do?

A.
function f() {
  x = 3;
  static x = 2;
  return x;
}

AWB:   The simplest desugaring would yield 3:
let f = function() {
   let x=2;
   return function f() {
   x=3;
   return x;
   }();
}

However, it would arguably be better to require that any use of x in f must 
come after its static declaration statement.  In that case, A would produce 
an early error.


---

B.
function f() {
  let x = 3;
  static x = 2;
  return x;
}

AWB: should be an early error, can't declare a variable as both a static and 
a non-static in the same scope.

-

C.
function f() {
  static x = 3;
  static x = 2;
  return x;
}
AWB: I'd also make this be an early error
---

D.
function f(b) {
  if (b) {
static x = 1;
return x++;
  }  else {
static x = 1;   // Same x or different?
return x++;
  }
}
AWB:  depends on the basic function/block scoping decisions. If block scoped 
statics then they are different x's.



Waldemar 


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


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

2010-11-23 Thread Waldemar Horwat

On 11/23/10 15:18, Allen Wirfs-Brock wrote:

- How far does "static" hoist? One let-scope? One block-scope? One
function-scope? One class-scope?
AWB: the simple answer would be one block-scope (isn't that the same as
a let-scope??). It probably will take some experimentation to verify
that the simple solution has reasonable use cases. If not, function
scope may be more appropriate. Until and unless we have class
declarations there really isn't anyway to consider class-scopes.

- Refactoring by adding or removing a scope becomes quite error-prone.
AWB: Just as it is for function and var declarations. Function scoping
static might actually alleviate refactoring issues.


It's substantially worse here.  If we adopt block-scope, we get:

function f(b) {
  if (b)
return 43;
  static x = 1;
  return x++;
}

If we adopt the block-scope recommendation, refactoring it to:

function f(b) {
  if (b)  {
return 43;
  } else {
static x = 1;
return x++;
  }
}

will do something completely different.


- To avoid breaking refactoring, you'd need to allow "static static",
"static static static", etc.
AWB: ?? examples?? BTW, isn't it the job of refactoring tools to address
issues like this. We shouldn't assume that JavaScript programmers will
always be restricted to dump editors.


See example above.  The local way to fix the refactoring is to turn it into:

function f(b) {
  if (b) {
return 43;
  } else {
static static x = 1;
return x++;
  }
}

The same issue arises if we make a different decision on how far "static" 
hoists, but the examples are slightly bigger.


- In what scope do you look up the initializer expressions? What if they
reference variables that were shadowed in between the scope where
they're actually present and the one into which they got hoisted?
AWB: The scope surrounding the construct they are hoisted out of (either
block or function depending upon the first design decision). If that
sort of shadowing is actually possible, it should be an early error if
it actually occurs. Also need to consider whether initializer
expressions can reference other statics in the same scope.

- When do the initializers run? What if it's a static const?
AWB: Before entering the scope it is hoisted out of. For function scope
this would be specified as part of "variable instantiation". static
const behavior has same scope-hole rules as regular const.


I asked about static const because now you have the new problem of multiple 
entry into the scope that does the const initialization.


- What happens if you have two of the functions above, each trying to
hoist its own "x" into the same scope? Under which conditions do the x's
stay separate, and under which ones do they become the same variable?
AWB: They are always separate. Each function gets its own static scope
that exists between the function and its enclosing scope. This is
illustrated in Bga's "ES3 way" desugaring.


So what should the following examples do?

A.
function f() {
  x = 3;
  static x = 2;
  return x;
}

B.
function f() {
  let x = 3;
  static x = 2;
  return x;
}

C.
function f() {
  static x = 3;
  static x = 2;
  return x;
}

D.
function f(b) {
  if (b) {
static x = 1;
return x++;
  }  else {
static x = 1;   // Same x or different?
return x++;
  }
}

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


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

2010-11-23 Thread Allen Wirfs-Brock
Waldemar has good questions, most of which would be addressed in a full 
proposal.  But some off the cuff answers are embedded below

Allen
-Original Message- 
From: Waldemar Horwat

Sent: Tuesday, November 23, 2010 1:07 PM
To: Bga
Cc: es-discuss@mozilla.org
Subject: Re: `static` keyword from C/C++ as own closured var declaration


This was already discussed at the September meeting.  Some interesting 
issues are:


- How far does "static" hoist?  One let-scope?  One block-scope?  One 
function-scope?   One class-scope?
AWB: the simple answer would be one block-scope (isn't that the same as a 
let-scope??).  It probably will take some experimentation to verify that the 
simple solution has reasonable use cases. If not, function scope may be more 
appropriate.  Until and unless we have class declarations there really isn't 
anyway to consider class-scopes.


- Refactoring by adding or removing a scope becomes quite error-prone.
AWB:  Just as it is for function and var declarations.  Function scoping 
static might actually alleviate refactoring issues.


- To avoid breaking refactoring, you'd need to allow "static static", 
"static static static", etc.
AWB: ?? examples??  BTW, isn't it the job of refactoring tools to address 
issues like this.  We shouldn't assume that JavaScript programmers will 
always be restricted to dump editors.


- In what scope do you look up the initializer expressions?  What if they 
reference variables that were shadowed in between the scope where they're 
actually present and the one into which they got hoisted?
AWB: The scope surrounding the construct they are hoisted out of (either 
block or function depending upon the first design decision).  If that sort 
of shadowing is actually possible, it should be an early error if it 
actually occurs.  Also need to consider whether initializer expressions can 
reference other statics in the same scope.


- When do the initializers run?  What if it's a static const?
AWB: Before entering the scope it is hoisted out of.  For function scope 
this would be specified as part of "variable instantiation".  static const 
behavior has same scope-hole rules as regular const.


- What happens if you have two of the functions above, each trying to hoist 
its own "x" into the same scope?  Under which conditions do the x's stay 
separate, and under which ones do they become the same variable?
AWB: They are always separate.  Each function gets its own static scope that 
exists between the function and its enclosing scope. This is illustrated in 
Bga's "ES3 way" desugaring.


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-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-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: `static` keyword from C/C++ as own closured var declaration

2010-11-23 Thread Waldemar Horwat

On 11/22/10 20:18, Bga wrote:

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


This was already discussed at the September meeting.  Some interesting issues 
are:

- How far does "static" hoist?  One let-scope?  One block-scope?  One 
function-scope?   One class-scope?
- Refactoring by adding or removing a scope becomes quite error-prone.
- To avoid breaking refactoring, you'd need to allow "static static", "static static 
static", etc.
- In what scope do you look up the initializer expressions?  What if they 
reference variables that were shadowed in between the scope where they're 
actually present and the one into which they got hoisted?
- When do the initializers run?  What if it's a static const?
- What happens if you have two of the functions above, each trying to hoist its own 
"x" into the same scope?  Under which conditions do the x's stay separate, and 
under which ones do they become the same variable?

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

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 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 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 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 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 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: `static` keyword from C/C++ as own closured var declaration

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

Sent: Tuesday, November 23, 2010 1:07 AM
To: Bga
Cc: es-discuss@mozilla.org
Subject: Re: `static` keyword from C/C++ as own closured var declaration

Allen suggested something like this in the September meeting. One issue 
people had with it was that it adds another violation of the equivalence 
between a statement  and (function())(), which is a refactoring 
hazard. Put differently, if you have some code with "static" declarations in 
it, you can't wrap the code in a function body without breaking the code, 
which makes it brittle.


Separate from that, I also don't really see how the idea really buys you all 
that much. The analogy to C is only so helpful, since C doesn't have nested 
functions (and static therefore always lifts to global scope), so mostly it 
just reads to me like a rather obscure way of saying "oops, I meant to bind 
this over there."


Dave


I agree that it doesn't appear to buy you much with simple, scalar valued 
statics like shown in these examples.  However, I think it is quite 
different if you look at actual JavaScript abstraction patterns.  For 
example:


function pointFactory(x,y) {
  static protoPoint = {
 moveTo: function (x,y) {...},
 distance: function (aPoint) {...},
 plus: function (aPoint) {...},
 minus: function(aPoint) {...),
 //etc.
  };
  var it=Object.create(protoPoint);
  it.x=x;
  it.y=y;
  return it;
  //I really want to just say: return {, x:x,y:y};
}

To me seems much more readable than:

let pointFactory = function() {
  let protoPoint = {
 moveTo: function (x,y) {...},
 distance: function (aPoint) {...},
 plus: function (aPoint) {...},
 minus: function(aPoint) {...),
 //etc.
  };
  return function (x,y) {
 var it=Object.create(protoPoint);
 it.x=x;
 it.y=y;
 return it;
  }
}();

Everybody on this list is quite confortable with using higher-order 
functions to express such abstractions.  This isn't the case for the vast 
majority of JavaScript programmers and I'm not sure it will ever be the 
case.  Instead, the pattern that would more likely be written as:


var protoPoint = {
  moveTo: function (x,y) {...},
  distance: function (aPoint) {...},
  plus: function (aPoint) {...},
  minus: function(aPoint) {...),
  //etc.
};

function pointFactory(x,y) {
  var it=Object.create(protoPoint);
  it.x=x;
  it.y=y;
  return it;
}

which breaks encapsulation.  It is also highly likely that many JavaScript 
programmer would just code it as:


function pointFactory(x,y) {
  var protoPoint = {
 moveTo: function (x,y) {...},
 distance: function (aPoint) {...},
 plus: function (aPoint) {...},
 minus: function(aPoint) {...),
 //etc.
  };
  var it=Object.create(protoPoint);
  it.x=x;
  it.y=y;
  return it;
}

without realizing that they aren't getting a shared prototype object. 
Teaching them that they should make shared prototype objects "static" seems 
like it would be much more likely to sink in than trying to teach any of the 
other more complex patterns.


The reason I originally proposed this use of static, is that I've personally 
found  that  the "own" variable pattern to be something that comes up 
frequently when defining abstractions using JavaScript.  Making it explicit 
would make it easier to both write and read such definitions.


Allen 


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


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

2010-11-23 Thread David Herman
Hm, that's an interesting point: *all* declaration forms are sensitive to being 
wrapped in a function, e.g.:

|(function() { var x })()| != |var x|

That pretty much nixes that critique!

Dave

On Nov 23, 2010, at 9:53 AM, Allen Wirfs-Brock wrote:

> How is your example any different from if you had said:
>  const foo=1;
> 
> In both cases, wrapping the declaration with a function changes its scope??
> 
> Allen
> 
> -Original Message- From: David Herman
> Sent: Tuesday, November 23, 2010 9:24 AM
> To: Dmitry A. Soshnikov
> Cc: es-discuss@mozilla.org
> Subject: Re: `static` keyword from C/C++ as own closured var declaration
> 
>> Can you give a small example (it's just interesting) -- to see the issue?
> 
> Sure thing. Say you're writing some code with a constant value, and somewhere 
> inside the code you use `static':
> 
>   var METERS_PER_SQUARE_KILOJOULE = 17.4;
>   ...
>   static foo = 1;
>   ...
>   f(foo, METERS_PER_SQUARE_KILOJOULE);
> 
> Now you decide you want to parameterize over the constant, instead of a fixed 
> constant:
> 
>   function(metersPerSquareKiloJoule) {
>   ...
>   static foo = 1;
>   ...
>   f(foo, metersPerSquareKiloJoule);
>   }
> 
> This change accidentally alters the scope of `foo'.
> 
> Dave
> 
> ___
> 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: `static` keyword from C/C++ as own closured var declaration

2010-11-23 Thread Allen Wirfs-Brock

How is your example any different from if you had said:
  const foo=1;

In both cases, wrapping the declaration with a function changes its scope??

Allen

-Original Message- 
From: David Herman

Sent: Tuesday, November 23, 2010 9:24 AM
To: Dmitry A. Soshnikov
Cc: es-discuss@mozilla.org
Subject: Re: `static` keyword from C/C++ as own closured var declaration


Can you give a small example (it's just interesting) -- to see the issue?


Sure thing. Say you're writing some code with a constant value, and 
somewhere inside the code you use `static':


   var METERS_PER_SQUARE_KILOJOULE = 17.4;
   ...
   static foo = 1;
   ...
   f(foo, METERS_PER_SQUARE_KILOJOULE);

Now you decide you want to parameterize over the constant, instead of a 
fixed constant:


   function(metersPerSquareKiloJoule) {
   ...
   static foo = 1;
   ...
   f(foo, metersPerSquareKiloJoule);
   }

This change accidentally alters the scope of `foo'.

Dave

___
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: `static` keyword from C/C++ as own closured var declaration

2010-11-23 Thread David Herman
> Can you give a small example (it's just interesting) -- to see the issue?

Sure thing. Say you're writing some code with a constant value, and somewhere 
inside the code you use `static':

var METERS_PER_SQUARE_KILOJOULE = 17.4;
...
static foo = 1;
...
f(foo, METERS_PER_SQUARE_KILOJOULE);

Now you decide you want to parameterize over the constant, instead of a fixed 
constant:

function(metersPerSquareKiloJoule) {
...
static foo = 1;
...
f(foo, metersPerSquareKiloJoule);
}

This change accidentally alters the scope of `foo'.

Dave

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


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

2010-11-23 Thread Mark S. Miller
On Tue, Nov 23, 2010 at 2:12 AM, Asen Bozhilov wrote:

> David Herman:
>
> >> // "new" more readable sugar
> >> function()
> >> {
> >>  static x = 1; // hello c/c++
> >>
> >>  return ++x;
> >> }
>
> This would produce incompatibilities with ECMAScript 5 non-strict
> code.  The word `static` can be used as an Identifier in ES5
> non-strict mode.
>

Any ES5 non-strict code that uses "static" as an identifier is already
incompat with ES5/strict, so this is not an issue. The case against "static"
seems strong, but this does make it stronger.


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



-- 
Cheers,
--MarkM
___
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: `static` keyword from C/C++ as own closured var declaration

2010-11-23 Thread Asen Bozhilov
David Herman:

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

This would produce incompatibilities with ECMAScript 5 non-strict
code.  The word `static` can be used as an Identifier in ES5
non-strict mode.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


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

2010-11-23 Thread Dmitry A. Soshnikov

On 23.11.2010 12:07, David Herman wrote:

Allen suggested something like this in the September meeting. One issue people had with it was that 
it adds another violation of the equivalence between a statement  and 
(function())(), which is a refactoring hazard. Put differently, if you have some code 
with "static" declarations in it, you can't wrap the code in a function body without 
breaking the code, which makes it brittle.



Can you give a small example (it's just interesting) -- to see the issue?


Separate from that, I also don't really see how the idea really buys you all that much. 
The analogy to C is only so helpful, since C doesn't have nested functions (and static 
therefore always lifts to global scope), so mostly it just reads to me like a rather 
obscure way of saying "oops, I meant to bind this over there."



It seems to me too that such a way may bring a confusion to JS 
development. And I also agree that in C it was caused by the _issue_ of 
absence nested functions with lexical scope.


Dmitry.


Dave

On Nov 22, 2010, at 8:18 PM, Bga wrote:


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

___
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: `static` keyword from C/C++ as own closured var declaration

2010-11-23 Thread David Herman
Allen suggested something like this in the September meeting. One issue people 
had with it was that it adds another violation of the equivalence between a 
statement  and (function())(), which is a refactoring hazard. Put 
differently, if you have some code with "static" declarations in it, you can't 
wrap the code in a function body without breaking the code, which makes it 
brittle.

Separate from that, I also don't really see how the idea really buys you all 
that much. The analogy to C is only so helpful, since C doesn't have nested 
functions (and static therefore always lifts to global scope), so mostly it 
just reads to me like a rather obscure way of saying "oops, I meant to bind 
this over there."

Dave

On Nov 22, 2010, at 8:18 PM, Bga wrote:

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

___
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
>> 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 has come up several times. For one, it's incompatible with ECMA-357 (E4X), 
which is implemented in SpiderMonkey and Rhino. But more importantly, IMO, the 
syntactic distinction between "for" and "for each" is not at all evocative of 
their semantic distinction. Indeed, "for" implicitly means "for each" already!

>> Fair enough. Another important question is whether for..in should continue 
>> to guarantee that all values enumerated would be strings.

A fair question, although as I believe Andreas pointed out earlier in the 
thread, it's subsumed by the more general question of whether for..in should 
continue to guarantee that all values enumerated would be keys.

>> Preserving that guarantee clearly makes for..in useless for the 
>> strawman:iterators purpose,
> 
> Why? The primary reason for the iterator protocol is avoiding eager 
> instantiation of the entire result set. If we force stringification in for-in 
> when used with an iterator, the protocol is still alive and well and useful.
> 
> We could avoid stringification if next() is called on iterators directly, or 
> provide an additional distinct new for-each or whatever syntax that doesn't 
> stringify.

IOW, we could usefully have:

1) only one for-in form, that is meta-programmable via iterate(), and that does 
not guarantee it only iterates over keys

2) two different forms:
a) for-in, which is meta-programmable but where the semantics enforces the 
invariant that all values iterated over are keys; and
b) another form (syntax TBD) which is meta-programmable but where the semantics 
does not modify the values iterated over

Most of this discussion has been about #1 vs. #2, but it's good to point out 
that 2a is still compatible with a meta-programmable API.

Dave

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


Re: Nov 18 notes

2010-11-23 Thread Andreas Gal

On Nov 23, 2010, at 12:11 AM, Maciej Stachowiak wrote:

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

Why? The primary reason for the iterator protocol is avoiding eager 
instantiation of the entire result set. If we force stringification in for-in 
when used with an iterator, the protocol is still alive and well and useful.

We could avoid stringification if next() is called on iterators directly, or 
provide an additional distinct new for-each or whatever syntax that doesn't 
stringify.

Andreas

> 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

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


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