Re: July TC39 meeting notes, day 2

2011-08-05 Thread Brendan Eich
On Aug 4, 2011, at 9:50 PM, Oliver Hunt wrote:

 The grammar at http://wiki.ecmascript.org/doku.php?id=harmony:classes does 
 not restrict Statement at all, currently. The 
 return-the-result-of-an-expression restriction could be done grammatically 
 but it is easier to do with semantics, prose in this case.
 
 Indeed, one way to support this would be to have modes in the grammar.  If 
 memory serves me correctly ANTLR supports such a concept, although I'm not 
 sure how widely the idea ever spread.  Logically this is syntactic sugar 
 around the large expansion of productions that would typically be necessary.

Parameterized productions are cool, but we have an LR(1) normative grammar and 
the reasons for keeping and validating LR(1) have been covered quite a bit, 
even this year, on es-discuss.

Generally, losing parameterization means duplication (the -NoIn vs. unsuffixed 
productions in ES1-5's grammar), or a semantic restriction (which can be an 
early error, e.g. return outside of a function, break outside of a loop, 
switch, or labeled statement, etc. -- even now we do not overcomplicate the 
grammar to forbid such things from parsing).


 I think part of what's confusing is I am still unclear whether class member 
 functions are expected to apply to arbitrary objects.  My assumption has 
 always been that member functions would throw when applied to an object of 
 the wrong class, and I don't see a good argument for an instance of a class 
 having (essentially) a mutable shape.

Please read the classes proposal. It's just syntax, this is required for 
Harmony. We are not adding new runtime or (horrors) static semantics by which 
classes would make objects you could not make otherwise.

True, we could freeze -- 'const class' does some freezing and sealing -- but 
not by default. And we could insert |this| class checks in all methods, but 
those too are the exception, not the rule. I'm not sure 'const class' binds 
methods.

If we accept arrow function syntax, then using it in classes to allow 
this-binding is plausible, but this creates a bound method object per method 
per class instance. Heavy tax, akin to closuer pattern. Doing this avoids the 
|this| class check, of course.


 To me when a developer says class ... { they are opting out of an object 
 is a generic map semantics, and actually want a fixed object shape.

Including the class prototype? I think not.

Anyway, classes that restrict instance and prototype shape, thereby allowing 
private foo to be referenced via 'foo', do not address the other.foo issue. 
Ruby after Smalltalk has *instance-private* instance variables, not 
class-private as we propose. That's why @x works in Ruby and you don't need 
other@x.

We agreed to class-private not instance-private, and that's what the 
harmony:classes proposal aims at (even with the straw and now burned 
private(this)/private(other) syntax). But per last week's meeting, we're going 
to take out private magic syntax from classes and try using private name 
objects: this[foo], other[foo] for private name object denoted foo.

I'm open to @ for private access, personally. (We can also support decorators 
using @ syntax if need be, but that's not currently proposed.) But any such @ 
for private access would also be an infix operator, so you could say other@foo. 
Private name objects used with or without magic syntax for privacy in class 
instance variables are class-private, not instance-private. You could use 
private name objects freshly generated per instance, too, if you wanted to -- 
but we aren't even deferring syntax for that use-case.

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


July TC39 meeting notes, day 2

2011-08-04 Thread Brendan Eich
A week late, I missed some of the morning due to a conflict. Thanks to Alex 
Russell for whiteboard photos. Others in attendance, please fill in and correct 
as needed. Thanks.

== Overview of initial working draft for 6th edition and discuss work flow for 
developing 6th edition draft ==

Allen presented the draft 6th edition and how best to develop it:

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

The phrase extended code as a way of specifying semantics for Harmony above 
and beyond strict mode code received some discussion (I missed most of it). 
In the end no one had a better term than extended.

Allen also presented the use of cover grammars (Supplemental Syntax) to 
specify destructuring assignment and possibly other syntactic extensions. The 
problem here is that an LR(1) grammar cannot distinguish an object or array 
literal from a destructuring pattern of the same form, until parsing reaches 
the '=' after the pattern. GLR or ordered choice top-down parsing techniques 
can cope, but LR(1) and therefore LL(1) cannot -- such an LR(1) grammar is 
ambiguous.

Note that ES1-5 cope with the existing ambiguity where x.y.z and x.y.z = w both 
start with a member expression by pushing the ambiguity off to the semantics, 
creating a spec-internal Reference type, which remembers the base object (what 
x.y evaluated to) and property name ('z'), and only getting the value 
(GetValue) if the x.y.z expression is an rvalue, otherwise using the Reference 
type lvalue  to assign to the named property (PutValue).

Computing a Reference tree or minimal AST for whole and arbitrarily large 
literal patterns, to defer evaluation till an assignment operator is parsed and 
we know the pattern is a destructuring lvalue rather than an object/array 
literal rvalue (after which GetValue or PutValue would process the tree 
according to its rvalue or lvalue nature) is not feasible.

This is due to the generality of the PropertyAssignment and  ElementList 
productions' AssignmentExpressions, which may embed function expressions and 
thus most of the grammar. We do not want to add an explicit and nearly-complete 
parse tree or AST to the spec.

The committee seemed to agree that the cover grammar approach seems like the 
best technique.

== Review/resolve open issues and change requests for 6 edition ==

https://bugs.ecmascript.org/buglist.cgi?order=Importancelist_id=384field0-0-0=flagtypes.nameresolution=---query_format=advancedtype0-0-0=substringvalue0-0-0=TC39product=Draft%20for%206th%20Edition

(Bug rows from the above query follow, starting with bug numbers.)

145 nor Normal All al...@wirfs-brock.com CONF --- eliminate uint32 length 
restriction the the length of array objects.
146 nor Normal All al...@wirfs-brock.com CONF --- Array generic array methods 
should not ToUint32 covert the length of non-generic arrays

We deferred these, agreeing that they seem worth trying to make as relaxations 
of existing index/length semantics for arrays, to align with String and avoid 
bogus uint32-domain work that cannot handle the overflow case of length == 
2^32. They will change edge-case behavior. The changes may break only 
testsuites, but you never know.

178 nor Normal All al...@wirfs-brock.com CONF --- Must settle scoping details 
for block-scoped bindings

Much discussion here. The issue is whether let and const bindings hoist to 
block top, or start a new implicit scope (the let* or, let's call it, C++ 
rule). The prior work was nicely diagrammed by Waldemar in:

https://mail.mozilla.org/pipermail/es-discuss/2008-October/007807.html

Quoting from Waldemar's message (note the future-proofing for guards):

--- begin quote ---

There are four ways to do this:
A1. Lexical dead zone.  References textually prior to a definition in the same 
block are an error.
A2. Lexical window.  References textually prior to a definition in the same 
block go to outer scope.
B1. Temporal dead zone.  References temporally prior to a definition in the 
same block are an error.
B2. Temporal window.  References temporally prior to a definition in the same 
block go to outer scope.

Let's take a look at an example:

let x = outer;
function g() {return outer}

{
  g();
  function f() { ... x ... g ... g() ... }
  f();
  var t = some_runtime_type;
  const x:t = inner;
  function g() { ... x ... }
  g();
  f();
}

B2 is bad because then the x inside g would sometimes refer to outer and 
sometimes to inner.

A1 and A2 introduce extra complexity but doesn't solve the problem.  You'd need 
to come up with a value for x to use in the very first call to g().  
Furthermore, for A2 whether the window occurred or not would also depend on 
whether something was a function or not; users would be surprised that x shows 
through the window inside f but g doesn't.

That leaves B1, which matches the semantic model (we need to avoid referencing 
variables before we know their types and before we know the values of 
constants).

--- end quote ---


Re: July TC39 meeting notes, day 2

2011-08-04 Thread Oliver Hunt

On Aug 4, 2011, at 2:29 PM, Brendan Eich wrote:
 1. return allowed from constructor?
 ...
 Consensus is: RESOLVED, return disallowed from class constructor body.

What about return with no value -- there are cases where such early returns are 
useful, and you would not be allowed to specify your own value (eg. there's an 
implicit return of |this|).  Most class-oriented languages have this behaviour 
(C++, Java, C#, etc), those that don't support early returns, frequently don't 
support return-statements at all (eg. the various object-pascal dialects).

 3. private variable use-syntax

My 2c:  i've always felt a prefix should be required to access a globally 
scoped variable/property in general, but no doubt people would complain about 
that degree of verbosity.  That said I'm unsure why there's such a desire to 
avoid standard scoping rules of every other language (where the properties of 
|this| are implicitly in scope), with a mechanism to disambiguate access to the 
global scope if necessary (As C++ does, although i'm not suggesting C++'s 
syntax).

--Oliver

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


Re: July TC39 meeting notes, day 2

2011-08-04 Thread Brendan Eich
On Aug 4, 2011, at 3:15 PM, Oliver Hunt wrote:

 On Aug 4, 2011, at 2:29 PM, Brendan Eich wrote:
 1. return allowed from constructor?
 ...
 Consensus is: RESOLVED, return disallowed from class constructor body.
 
 What about return with no value -- there are cases where such early returns 
 are useful, and you would not be allowed to specify your own value (eg. 
 there's an implicit return of |this|).  Most class-oriented languages have 
 this behaviour (C++, Java, C#, etc), those that don't support early returns, 
 frequently don't support return-statements at all (eg. the various 
 object-pascal dialects).

That is a good point, one I think someone raised at the meeting (my note-taking 
failed there). This resolution was about banning return expression; in 
constructors, but not banning return; used well to avoid tortured and 
over-indented control flow.

The grammar at http://wiki.ecmascript.org/doku.php?id=harmony:classes does not 
restrict Statement at all, currently. The return-the-result-of-an-expression 
restriction could be done grammatically but it is easier to do with semantics, 
prose in this case.


 3. private variable use-syntax
 
 My 2c:  i've always felt a prefix should be required to access a globally 
 scoped variable/property in general, but no doubt people would complain about 
 that degree of verbosity.  That said I'm unsure why there's such a desire to 
 avoid standard scoping rules of every other language (where the properties of 
 |this| are implicitly in scope),

You must mean languages that have static typing.

We have covered this before:

https://mail.mozilla.org/pipermail/es-discuss/2011-June/015125.html
https://mail.mozilla.org/pipermail/es-discuss/2011-June/015129.html
https://mail.mozilla.org/pipermail/es-discuss/2011-June/015196.html


 with a mechanism to disambiguate access to the global scope if necessary (As 
 C++ does, although i'm not suggesting C++'s syntax).

Object != scope, the Harmony scoping model is lexical. Mutable instances with 
mutable prototypes violate lexical scope if injected into scope environments.

Even if you managed to put just the private names that were declared by the 
class as private instance variable names (we agreed to take out the syntax for 
this, for the moment), how would you know whether other.foo where foo was 
private in the class should be the private name object, or the string-equated 
'foo'?

Think of Point with private x, y and an equals method. Another method has to 
access a plain old object with public property x. You can't try private and 
then public (won't be right for edge cases with both names mapped, possibly 
differently along the prototype chain; won't be efficient). Unlike languages 
with static type information about |this| and other parameters, in JS you need 
to say when you mean to access a private-name-keyed property.

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


Re: July TC39 meeting notes, day 2

2011-08-04 Thread Oliver Hunt

On Aug 4, 2011, at 6:45 PM, Brendan Eich wrote:

 On Aug 4, 2011, at 3:15 PM, Oliver Hunt wrote:
 
 On Aug 4, 2011, at 2:29 PM, Brendan Eich wrote:
 1. return allowed from constructor?
 ...
 Consensus is: RESOLVED, return disallowed from class constructor body.
 
 What about return with no value -- there are cases where such early returns 
 are useful, and you would not be allowed to specify your own value (eg. 
 there's an implicit return of |this|).  Most class-oriented languages have 
 this behaviour (C++, Java, C#, etc), those that don't support early returns, 
 frequently don't support return-statements at all (eg. the various 
 object-pascal dialects).
 
 That is a good point, one I think someone raised at the meeting (my 
 note-taking failed there). This resolution was about banning return 
 expression; in constructors, but not banning return; used well to avoid 
 tortured and over-indented control flow.
 
 The grammar at http://wiki.ecmascript.org/doku.php?id=harmony:classes does 
 not restrict Statement at all, currently. The 
 return-the-result-of-an-expression restriction could be done grammatically 
 but it is easier to do with semantics, prose in this case.

Indeed, one way to support this would be to have modes in the grammar.  If 
memory serves me correctly ANTLR supports such a concept, although I'm not sure 
how widely the idea ever spread.  Logically this is syntactic sugar around the 
large expansion of productions that would typically be necessary.

 
 
 3. private variable use-syntax
 
 My 2c:  i've always felt a prefix should be required to access a globally 
 scoped variable/property in general, but no doubt people would complain 
 about that degree of verbosity.  That said I'm unsure why there's such a 
 desire to avoid standard scoping rules of every other language (where the 
 properties of |this| are implicitly in scope),
 
 You must mean languages that have static typing.
 
 We have covered this before:
 
 https://mail.mozilla.org/pipermail/es-discuss/2011-June/015125.html
 https://mail.mozilla.org/pipermail/es-discuss/2011-June/015129.html
 https://mail.mozilla.org/pipermail/es-discuss/2011-June/015196.html
 
 
 with a mechanism to disambiguate access to the global scope if necessary (As 
 C++ does, although i'm not suggesting C++'s syntax).
 
 Object != scope, the Harmony scoping model is lexical. Mutable instances with 
 mutable prototypes violate lexical scope if injected into scope environments.
 
 Even if you managed to put just the private names that were declared by the 
 class as private instance variable names (we agreed to take out the syntax 
 for this, for the moment), how would you know whether other.foo where foo was 
 private in the class should be the private name object, or the string-equated 
 'foo'?
 
 Think of Point with private x, y and an equals method. Another method has to 
 access a plain old object with public property x. You can't try private and 
 then public (won't be right for edge cases with both names mapped, possibly 
 differently along the prototype chain; won't be efficient). Unlike languages 
 with static type information about |this| and other parameters, in JS you 
 need to say when you mean to access a private-name-keyed property.

I think part of what's confusing is I am still unclear whether class member 
functions are expected to apply to arbitrary objects.  My assumption has always 
been that member functions would throw when applied to an object of the wrong 
class, and I don't see a good argument for an instance of a class having 
(essentially) a mutable shape.

To me when a developer says class ... { they are opting out of an object is 
a generic map semantics, and actually want a fixed object shape.  Essentially 
any class definition and any instance of a class is |sealed| -- at this point 
lexical scoping can be performed as it is in other languages.  This isn't about 
having mutable objects on the scope chain, if you see a property access that 
references a property name that is present in the lexical scope, you statically 
bind to it -- the scope chain is not involved, you know that if you're a member 
of class X, and you access a property P that is defined in the class X, you 
will be performing a lookup off of |this|, you're not exposed to mutation.

I don't buy the parameter vs. property name argument as most modern languages 
have this problem and it doesn't appear to be a significant issue.  The 
remaining problem is the equals issue, and while i recognise that as a 
problem that would need to be solved (syntactically or otherwise) but i don't 
see why we must therefore add a penalty to the _common_ case where you want to 
access a member.  Given the amount of noise made about removing parentheses, 
etc it seems stunning to then say adding syntactic overhead to basic member 
access is a good thing.

If you want classes to produce mutable objects, and to prefix access to members 
of said class in instances then you might