July TC39 meeting notes, day 2

Oliver Hunt oliver at apple.com
Thu Aug 4 21:50:37 PDT 2011


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 as well drop pre-definition of properties and follow the python or ruby models where you define member functions, but all member properties are dynamic.  eg.

class Point
    def initialize(x, y)
        @x = x
        @y = y
    end
end

or

class Point:
     def __init__(self, x, y):
          self.x = x
          self.y = y

Both of these seem to have the syntactic behaviour you're prefering, but neither language supports declarative definition of member properties -> objects of a class are still essentially property bags.  If we were to go in one these directions I guess I would prefer a ruby-esque model, but only because then i'd define the behaviour as hoisting all member property rights to the class body as if they were declared separately, and then error out if there's a read of a undeclared property.

> /be


--Oliver

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110804/7eaa069b/attachment.html>


More information about the es-discuss mailing list