Re: An "extend" operator is a natural companion to <|

2011-07-20 Thread Brendan Eich
On Jul 20, 2011, at 2:22 AM, Axel Rauschmayer wrote:

> Then lhs and rhs are switched, though. What is the best description of what 
> this operator does? “Copy the own properties of an increment to an object”? 
> Whatever word(s) are chosen as an infix operator should reflect such a 
> description. “Extend” and even “increment” do not sound descriptive enough to 
> me.
> 
> More ideas:
> 
> obj <-copy- increment
> obj from increment
> obj loads increment
> obj imports increment
> increment to obj
> increment increments obj
> increment overrides obj

"increment" is confusing here, but I get it -- you mean the rhs in Allen's <& 
proposal. Best to use "source" or "src", "increment" suggests ++ and misleads.

I don't think we should use contextual keywords that aren't verbs for a 
mutating operator.

At this point I think a keyword operator is no better than a built-in method, 
especially from a built-in module, but even if just Object.extend.

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


Re: An "extend" operator is a natural companion to <|

2011-07-20 Thread Axel Rauschmayer
> From: Brendan Eich 
> Date: July 19, 2011 18:59:04 GMT+02:00
> To: Sean Eagan 
> Cc: es-discuss 
> Subject: Re: An "extend" operator is a natural companion to <|

> "owns" is ambiguous -- could still delegate. Can't use "extends", the 
> direction is wrong (and "extendedBy" is right out!). How about
> 
>  let b = B copies {...};
> 
> ?
> 
> There must be a better contextual keyword...



How about

increment copyto obj

Then lhs and rhs are switched, though. What is the best description of what 
this operator does? “Copy the own properties of an increment to an object”? 
Whatever word(s) are chosen as an infix operator should reflect such a 
description. “Extend” and even “increment” do not sound descriptive enough to 
me.

More ideas:

obj <-copy- increment
obj from increment
obj loads increment
obj imports increment
increment to obj
increment increments obj
increment overrides obj

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: An "extend" operator is a natural companion to <|

2011-07-20 Thread Axel Rauschmayer
> From: Brendan Eich 
> Date: July 19, 2011 21:16:29 GMT+02:00
> To: Luke Hoban 
> Cc: "es-discuss@mozilla.org" 
> Subject: Re: An "extend" operator is a natural companion to <|
> 
> 
> On Jul 19, 2011, at 11:56 AM, Luke Hoban wrote:
> 
>> The arguments in favor of a library alternative are:
>> 1) Immediately useful to all JS developers
>> 2) Simple, understandable syntax consistent with existing practice
> 
> I agree with all this, but demur here:
> 
> 
>> From discussions with some Microsoft dev teams, that could be a 3+ year 
>> difference in adoption timeline. 
> 
> If this is a give me the goods now argument, and the goods can be expressed 
> via functions, I'm with you.
> 
> If this is "new syntax takes too long to be usable due to downrev browsers, 
> mainly IE", then that's no reason to stall progress on usable and new syntax 
> for novel semantics (i.e., shallow continuations). Harmony requires not 
> putting the language into a no-new-syntax straightjacket. That was ES3.1 -> 
> ES5, and we are past it.
> 
> But I quite agree that we should consider functions as alternatives to 
> special forms where they are plausible (so, not for yield, to pick up the 
> shallow continuations example).


The <| operator looks so good and is so useful that I would consider the 
possibility of having both the operator and an Object.* (or module!) method 
that does the same, even though that is redundant. But it would allow you to 
use the method/function in portable code and use the operator in Harmony-only 
code.

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: An "extend" operator is a natural companion to <|

2011-07-20 Thread Axel Rauschmayer
My opinion can be summarized as follows: The operator is really useful, we need 
it or at least its functionality (alternatively, as a method). I suspect that 
the patterns are better supported via class literals that hides the details via 
sugaring, but they elegantly illustrate why the operator is so useful.

> My think was that the feature could always be extended in the future to allow 
> a non-literal RHS if we wanted to deal with those issues.

Makes sense.

>> From your examples, it looks as if the lhs would be modified, a bit similar 
>> to the += operator. Then the "arrow" should probably point in the opposite 
>> direction, e.g.:
>> 
>>> objToBeModified +> increment
> 
> I don't follow your logic for the pointer direction. 

True. <& points in the right direction. When I think about it, I actually 
object to it looking so similar to <| (which is perfect, especially how it 
looks). This suggests a sameness that does not exist. Compound assignment might 
be a better idea:

obj += increment; // overloaded for strings, why not for objects?
obj o= increment; // the circle means overriding in many algebraic theories
obj °= increment;

>> I love how the prototype is incremented here. What does "tthis" do? Wouldn't 
>> point simply return an object literal (no "this <&")?
> 
> No, because the [[Construct]] internal method set this to a new object whose 
> [[Prototype]] is correctly initialized to Point.prototype.  You could return:
>Point.prototype <| { ...

Got it. Nice.

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 6:12 PM, Gavin Barraclough wrote:

> On Jul 19, 2011, at 12:17 PM, Allen Wirfs-Brock wrote:
>> One issue is that <| conceptually modifies the [[Prototype]] of its RHS.  As 
>> an operator (whether special character or keyword based) we can restrict the 
>> RHS to be a literal and define the behavior such that no actual mutation of 
>> [[Prototype]] is necessary.
>> 
>> However, at the value level we have no way to distinguish an object that was 
>> created via a literal and which has no references other than the current 
>> argument value.  So, when we specify Object.make we have to accept an 
>> arbitrary object as the second argument  and specify either [[Prototype]] 
>> mutation or some sort of shallow copy, either of which can be problematic. 
>> 
> 
> On Jul 19, 2011, at 1:27 PM, Brendan Eich wrote:
>> We are *not* gonna standardize mutable [[Prototype]].
> 
> 
> The concept of an operator that logically modifies the RHS operand seems 
> unfortunate,

L <| R does not modify R's [[Prototype]] so much as "preset" it, since R is 
grammatically restricted to be a literal form (object, array, regexp, etc.).


> as does having an operator with an implicit requirement that the RHS be a 
> literal.  The fact that the only reason that setting the prototype is 
> acceptable to us is because the RHS is a literal seems to raise the question 
> whether this really should be the action of an operator?  Do we not just need 
> an extension to the object/array literal syntax to allow the prototype to be 
> specified within the literal?
> 
> Some engines already allow syntax to declare a prototype for an object 
> literal, e.g.:
> 
>   var o = { __proto__: protoObj, a:1, b:2 };
> 
> Does this produce the same results as:
> 
>   var o = protoObj <| { a:1, b:2 };
> 
> ?

Yes.


> I'm sure that we don't want to standardize __proto__, perhaps an option 
> closer to the spec would be:
> 
>   var o = { [[Prototype]]: protoObj, a:1, b:2 };
> 
> Though I'm sure this isn't particularly lovable syntax, particularly if we 
> want to support this for array literals.
> Maybe something based on the idea of the <| operator might work?, say:
> 
>   var o = { |> protoObj, a:1, b:2 };
> 
> Apologies in advance if I'm missing an understanding of an important detail 
> of the <| operator as proposed.

Part of the appeal of <| is that it lets us write class-like expressions:

class D extends B { ... }

vs.

let D = B <| { ... }

but this led down the prototype-first (B and D name prototype objects, not 
constructors) naming path, which I think is too different from current 
constructors-with-prototypes JS pattern. It also led to the class body is 
object literal idea, which I've been arguing against just today.

There are lots of plausible syntactic extensions for presetting [[Prototype]], 
but they all need enforcement that the right-hand side of <| (or the equivalent 
position for alternative syntaxes) is new and not yet accessible to code.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 4:33 PM, Allen Wirfs-Brock wrote:

> Actually, I'm trying to explore going the other direction.  What would it 
> take to allow object literals to use the same syntax as class declarations 
> for the things that they have in common. 

But why? Even if an object literal is method heavy, the commas are a 
longstanding separator (with a trailing one allowed, finally per ES5, de-facto 
in all but IE during the ES3 period).


>> Method bodies are braced and, like function declarations in ES1-5, do not 
>> require gratuitous ; or , termination or separation from following source 
>> elements.
> 
> but you are not also arguing for eliminating the requirement for a , after a 
> method property in an object.  Right?
> 
> let c = {
>   m1() {...}
>   m2() {...}
>   get g() {...}
>   set g() {...}
>   m3() {...}
> }

No, I've been clear -- I keep saying class body is *not* object literal. This 
cuts both ways!


> If this is correct, I don't see why you are making the argument for one 
> construct and not the other.

Because they are different constructs.

Different semantics should have different syntax. Method shorthand is not a 
strong enough attractor to pull these together.


>> This means data property declarations in a class *do* need some kind of 
>> termination, and the obvious candidate for parallelism with function 
>> declarations is the semicolon.
>> 
>> From this, I concede that data property declarations in a class should not 
>> try to look like property assignments (key: value) in an object literal.
> 
> Object literals and class declarations are very similar in some respects and 
> it seems likely that developers will be refactoring one to the other fairly 
> routinely.

Maybe, but they won't be putting commas after method bodies (including 
constructor) in classes they write fresh.


>  The more different the common elements are the most difficult that 
> refactoring will be.  It also increase, the leaning burden to have different 
> ways to express the same concept that must be used in different contexts.

Sorry, I think making commas optional after methods in object literals is a 
non-goal. I'm not even sure it is unambiguous with the various object literal 
extensions.

/be

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Gavin Barraclough
On Jul 19, 2011, at 12:17 PM, Allen Wirfs-Brock wrote:
> One issue is that <| conceptually modifies the [[Prototype]] of its RHS.  As 
> an operator (whether special character or keyword based) we can restrict the 
> RHS to be a literal and define the behavior such that no actual mutation of 
> [[Prototype]] is necessary.
> 
> However, at the value level we have no way to distinguish an object that was 
> created via a literal and which has no references other than the current 
> argument value.  So, when we specify Object.make we have to accept an 
> arbitrary object as the second argument  and specify either [[Prototype]] 
> mutation or some sort of shallow copy, either of which can be problematic. 
> 

On Jul 19, 2011, at 1:27 PM, Brendan Eich wrote:
> We are *not* gonna standardize mutable [[Prototype]].


The concept of an operator that logically modifies the RHS operand seems 
unfortunate, as does having an operator with an implicit requirement that the 
RHS be a literal.  The fact that the only reason that setting the prototype is 
acceptable to us is because the RHS is a literal seems to raise the question 
whether this really should be the action of an operator?  Do we not just need 
an extension to the object/array literal syntax to allow the prototype to be 
specified within the literal?

Some engines already allow syntax to declare a prototype for an object literal, 
e.g.:

var o = { __proto__: protoObj, a:1, b:2 };

Does this produce the same results as:

var o = protoObj <| { a:1, b:2 };

?
I'm sure that we don't want to standardize __proto__, perhaps an option closer 
to the spec would be:

var o = { [[Prototype]]: protoObj, a:1, b:2 };

Though I'm sure this isn't particularly lovable syntax, particularly if we want 
to support this for array literals.
Maybe something based on the idea of the <| operator might work?, say:

var o = { |> protoObj, a:1, b:2 };

Apologies in advance if I'm missing an understanding of an important detail of 
the <| operator as proposed.

cheers,
G.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2011, at 3:45 PM, Brendan Eich wrote:

> On Jul 19, 2011, at 3:13 PM, Allen Wirfs-Brock wrote:
> 
>> Also, why ; instead of , like in object literals
> 
> We've been over this before: because methods have braced bodies that should 
> not require either ; or , to be separate from adjacent methods. A class body 
> is not an ObjectLiteral grammatically. We do not want to require
> 
>   class C {
> m1() {...},
> m2() {...},
> m3() {...}
>   }
> 
> when top level functions do not need any such comma separation.
> 
> 
>>  (alternatively could we allow use of ; as a separator in object literals).
> 
> No one is looking for that extension.
> 
> 
>>  It seems desirable to have consistency of property definitions between 
>> object literals and class declarations.
> 
> I don't agree. A class body is not an object literal, even if the method 
> syntax is very close to the proposed ES.next method-in-object-literal syntax. 
> Trying to make a class body be an object literal imposes ugly, undesirable, 
> and likely-to-be-forgotten extra separator or even terminator punctuation (; 
> or,  -- doesn't matter).

Actually, I'm trying to explore going the other direction.  What would it take 
to allow object literals to use the same syntax as class declarations for the 
things that they have in common. 

> 
> Method bodies are braced and, like function declarations in ES1-5, do not 
> require gratuitous ; or , termination or separation from following source 
> elements.

but you are not also arguing for eliminating the requirement for a , after a 
method property in an object.  Right?

 let c = {
   m1() {...}
   m2() {...}
   get g() {...}
   set g() {...}
   m3() {...}
}
   
If this is correct, I don't see why you are making the argument for one 
construct and not the other.

> 
> This means data property declarations in a class *do* need some kind of 
> termination, and the obvious candidate for parallelism with function 
> declarations is the semicolon.
> 
> From this, I concede that data property declarations in a class should not 
> try to look like property assignments (key: value) in an object literal.

Object literals and class declarations are very similar in some respects and it 
seems likely that developers will be refactoring one to the other fairly 
routinely.  The more different the common elements are the most difficult that 
refactoring will be.  It also increase, the leaning burden to have different 
ways to express the same concept that must be used in different contexts.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Bob Nystrom
On Tue, Jul 19, 2011 at 3:45 PM, Brendan Eich  wrote:

> On Jul 19, 2011, at 3:13 PM, Allen Wirfs-Brock wrote:
>
> The plain name; also looks like a useless expression-statement.
>
>
> When we talked some people pretty strongly felt that it was very desirable
> to be able to explicitly declare the intended per instance properties.  In
> addition to document purposes such declaration might, for example, be used
> for things like linting for this.mispellings in the body of the function.
>  Such explicit  declarations are probably essential if they are private
> properties.  But I don't see any problem with requiring inclusion of an
> initial value, even it it is going to be |undefined.|
>
>
> It's fine to have privates declared, and I agree outside of the constructor
> is better than inside. But the syntax should not look like a useless
> identifier expression.
>
>
> Whether they can be declared outside the constructor is a separate issue.
> Perhaps if they have constant or constructor-invariant initializers, they
> can be initialized where declared too.
>
>
> This seemed to be a big issue in the past that caused a lot of thrashing
> about how to put such declarations inside the constructor.  Backing off from
> that requirement would be helpful.
>
>
> I don't think there was a requirement to put private instance property
> declarations inside the constructor. Rather, there were two bodies to choose
> from, and the class body was for prototype properties, absent some
> sectioning scheme such as Bob just proposed.
>
> Now that Bob has proposed it (and we did discuss C++-style labeled
> sections, briefly, in the run-up to the May TC39 meeting, IIRC, but we
> skipped over that approach for some reason I don't recall), we can indeed
> avoid putting special syntax for public and private instance property
> declaration into the constructor body syntax.
>
> This wins too because it lets constructor be a method like any other,
> syntactically.
>

This is very cool. Yay for simplifying.


>
>
> But declarations should look different from expressions. The alternative we
> keep returning to is the property assignment sub-grammar of object literals,
> which would want
>
>   new:
> numAttacks: 0;
>
> with a semicolon not a comma.
>
>
> some thoughts -- why does the punctuation following the new (or class or
> prototype or whatever).  For example, what about
>
>--new--
>  numAttacks: 0;
>
> that looks more distinctly like a section break and different from a
> property name (and otherwise how would one define a property name new or
> class or prototype or private?)
>
>
> Good point, I should have seen that one coming. The private and class names
> being reserved words may have caused false hope that they could not be used
> as property names, but ES5 allows them -- same with new.
>
> At this point, I'm going to withdraw the
>
>   new:
>  numAttacks: 0;
>
> idea, in favor of the assignment expression-statement form Bob sketched.
>
>
> Also, why ; instead of , like in object literals
>
>
> We've been over this before: because methods have braced bodies that should
> not require either ; or , to be separate from adjacent methods. A class body
> is not an ObjectLiteral grammatically. We do not want to require
>
>   class C {
> m1() {...},
> m2() {...},
> m3() {...}
>   }
>
> when top level functions do not need any such comma separation.
>
>
>  (alternatively could we allow use of ; as a separator in object literals).
>
>
> No one is looking for that extension.
>
>
>  It seems desirable to have consistency of property definitions between
> object literals and class declarations.
>
>
> I don't agree. A class body is not an object literal, even if the method
> syntax is very close to the proposed ES.next method-in-object-literal
> syntax. Trying to make a class body be an object literal imposes ugly,
> undesirable, and likely-to-be-forgotten extra separator or even terminator
> punctuation (; or,  -- doesn't matter).
>
> Method bodies are braced and, like function declarations in ES1-5, do not
> require gratuitous ; or , termination or separation from following source
> elements.
>
> This means data property declarations in a class *do* need some kind of
> termination, and the obvious candidate for parallelism with function
> declarations is the semicolon.
>
> From this, I concede that data property declarations in a class should not
> try to look like property assignments (key: value) in an object literal.
>
> But I'm stil not happy about assignment-expression appearances. It's simply
> the lesser evil at this point, in my view.
>
> The name; form, *sans* initialiser, is just wrong, so I agree we can
> mandate an explicit initialiser, even if undefined.
>

I agree with all of this, 100%. :)

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 3:13 PM, Allen Wirfs-Brock wrote:

>> The plain name; also looks like a useless expression-statement.
> 
> When we talked some people pretty strongly felt that it was very desirable to 
> be able to explicitly declare the intended per instance properties.  In 
> addition to document purposes such declaration might, for example, be used 
> for things like linting for this.mispellings in the body of the function.  
> Such explicit  declarations are probably essential if they are private 
> properties.  But I don't see any problem with requiring inclusion of an 
> initial value, even it it is going to be |undefined.|

It's fine to have privates declared, and I agree outside of the constructor is 
better than inside. But the syntax should not look like a useless identifier 
expression.


>> Whether they can be declared outside the constructor is a separate issue. 
>> Perhaps if they have constant or constructor-invariant initializers, they 
>> can be initialized where declared too.
> 
> This seemed to be a big issue in the past that caused a lot of thrashing 
> about how to put such declarations inside the constructor.  Backing off from 
> that requirement would be helpful.

I don't think there was a requirement to put private instance property 
declarations inside the constructor. Rather, there were two bodies to choose 
from, and the class body was for prototype properties, absent some sectioning 
scheme such as Bob just proposed.

Now that Bob has proposed it (and we did discuss C++-style labeled sections, 
briefly, in the run-up to the May TC39 meeting, IIRC, but we skipped over that 
approach for some reason I don't recall), we can indeed avoid putting special 
syntax for public and private instance property declaration into the 
constructor body syntax.

This wins too because it lets constructor be a method like any other, 
syntactically.


>> But declarations should look different from expressions. The alternative we 
>> keep returning to is the property assignment sub-grammar of object literals, 
>> which would want
>> 
>>   new:
>> numAttacks: 0;
>> 
>> with a semicolon not a comma.
> 
> some thoughts -- why does the punctuation following the new (or class or 
> prototype or whatever).  For example, what about
> 
>--new--
>  numAttacks: 0;
> 
> that looks more distinctly like a section break and different from a property 
> name (and otherwise how would one define a property name new or class or 
> prototype or private?)

Good point, I should have seen that one coming. The private and class names 
being reserved words may have caused false hope that they could not be used as 
property names, but ES5 allows them -- same with new.

At this point, I'm going to withdraw the 

  new:
 numAttacks: 0;

idea, in favor of the assignment expression-statement form Bob sketched.


> Also, why ; instead of , like in object literals

We've been over this before: because methods have braced bodies that should not 
require either ; or , to be separate from adjacent methods. A class body is not 
an ObjectLiteral grammatically. We do not want to require

  class C {
m1() {...},
m2() {...},
m3() {...}
  }

when top level functions do not need any such comma separation.


>  (alternatively could we allow use of ; as a separator in object literals).

No one is looking for that extension.


>  It seems desirable to have consistency of property definitions between 
> object literals and class declarations.

I don't agree. A class body is not an object literal, even if the method syntax 
is very close to the proposed ES.next method-in-object-literal syntax. Trying 
to make a class body be an object literal imposes ugly, undesirable, and 
likely-to-be-forgotten extra separator or even terminator punctuation (; or,  
-- doesn't matter).

Method bodies are braced and, like function declarations in ES1-5, do not 
require gratuitous ; or , termination or separation from following source 
elements.

This means data property declarations in a class *do* need some kind of 
termination, and the obvious candidate for parallelism with function 
declarations is the semicolon.

From this, I concede that data property declarations in a class should not try 
to look like property assignments (key: value) in an object literal.

But I'm stil not happy about assignment-expression appearances. It's simply the 
lesser evil at this point, in my view.

The name; form, sans initialiser, is just wrong, so I agree we can mandate an 
explicit initialiser, even if undefined.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2011, at 11:23 AM, Brendan Eich wrote:

> On Jul 19, 2011, at 11:07 AM, Bob Nystrom wrote:
> 
>> // "new" lets you declare members on new instances. these would presumably be
> 
>> // invoked on the new object before the constructor body is run.
>> new:
>>   numAttacks = 0;
>>   // declaring an instance property here mainly so you can document it. 
>> could be
>>   // useful later for guards or other annotations.
>>   name;
> 
> The plain name; also looks like a useless expression-statement.

When we talked some people pretty strongly felt that it was very desirable to 
be able to explicitly declare the intended per instance properties.  In 
addition to document purposes such declaration might, for example, be used for 
things like linting for this.mispellings in the body of the function.  Such 
explicit  declarations are probably essential if they are private properties.  
But I don't see any problem with requiring inclusion of an initial value, even 
it it is going to be |undefined.|

> 
> Beyond this, I'm concerned that per-instance properties need initializers 
> that use constructor parameters. So they ought to be initialized in the 
> constructor.
> 
> Whether they can be declared outside the constructor is a separate issue. 
> Perhaps if they have constant or constructor-invariant initializers, they can 
> be initialized where declared too.

This seemed to be a big issue in the past that caused a lot of thrashing about 
how to put such declarations inside the constructor.  Backing off from that 
requirement would be helpful.

> 
> But declarations should look different from expressions. The alternative we 
> keep returning to is the property assignment sub-grammar of object literals, 
> which would want
> 
>   new:
> numAttacks: 0;
> 
> with a semicolon not a comma.

some thoughts -- why does the punctuation following the new (or class or 
prototype or whatever).  For example, what about

   --new--
 numAttacks: 0;

that looks more distinctly like a section break and different from a property 
name (and otherwise how would one define a property name new or class or 
prototype or private?)

Also, why ; instead of , like in object literals  (alternatively could we allow 
use of ; as a separator in object literals).  It seems desirable to have 
consistency of property definitions between object literals and class 
declarations.


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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 2:44 PM, Allen Wirfs-Brock wrote:

> These were largely topics of another thread which I want to get back to with 
> some new thoughts.  But these issue may have impact of details of the direct 
> of the design discussion in this thread.  I don't think it works to try to 
> add private property access issues into the design after everything else is 
> settled.

(Missing "until" before "after"?)

Good point, private should not be "syntax solved" first. We need to finish the 
design, including semantics. Basing class-private instance and even prototype 
properties on private name objects still makes more sense to me than any new, 
unobservably different way of specifying private-in-class. Indeed 
private-on-class-prototype may leak some observable difference (but not the 
private name object) via Proxies, I'm still not sure.

Another reason to separate private from classes, as dherman's "minimal classes" 
post suggested.

/be

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2011, at 11:16 AM, Brendan Eich wrote:

> On Jul 19, 2011, at 11:07 AM, Bob Nystrom wrote:
>> 
> 
> 
> 
>> // "private" before a section lets you declare private members on that 
>> object.
>> private new:
>>   health;
> 
> Not sure we need 'new' there given lack of private prototype properties in 
> the proposal. It's a bit verbose. Probably even if we add private prototype 
> properties we can let private: (in this idea you've pitched) default to 
> private instance.
> 


Any useful for class design is going to want to be able to have non-public 
methods.  And there are good use cases for private data that is shared among 
instances (for example example large lookup tables).

Also, ust a reminder that if "privateness" is based upon Private Names then 
there are point of use issues with undecorated property name identifiers.  EG:

foo.health //foo might or might not be an instance of this class

which is why we might need to distinguish

foo[health]
from
   foo[@health]
or possibly
   foo@health

Also, if
private new;
  health

introduces a new Private Name valued lexical binding for "health" or (even 
@health) then we need to deal with the scoping of that binding.

These were largely topics of another thread which I want to get back to with 
some new thoughts.  But these issue may have impact of details of the direct of 
the design discussion in this thread.  I don't think it works to try to add 
private property access issues into the design after everything else is settled.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 1:28 PM, Luke Hoban wrote:

> Agreed - my note was just a "most value to the most users the soonest" 
> argument.  Syntax is clearly important, and many of the proposals can only 
> reasonably be offered as syntax.  Some of the proposals that can be partly 
> delivered as libraries still benefit significantly from syntax as well.

Great to hear.


>  But the adoption timelines for the new library pieces and the new syntax 
> pieces will be quite different, not just because of downrev browsers, but 
> also because of breaking change burden, authoring convenience, maintenance of 
> old script, etc.

Not to quibble, but the problem you are identifying is the polyfill vs. 
compiler one: polyfills for libraries are easier (even if fake or weak, 
semantically), polyfills for syntax are transpilers or full-strength compilers. 
Right?

I'm hoping your point is not that some implementors will prototype library code 
faster than new syntax. Library extensions may be easier (proxies are a 
possible counter-example) but implementors should be prototyping both new 
syntax+semantics and new library code or built-in modules (which will require 
the module system).

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


RE: An "extend" operator is a natural companion to <|

2011-07-19 Thread Luke Hoban
  >> From discussions with some Microsoft dev teams, that could be a 3+ year 
difference in adoption timeline. 
  > If this is a give me the goods now argument, and the goods can be expressed 
via functions, I'm with you.
  > If this is "new syntax takes too long to be usable due to downrev browsers, 
mainly IE", then that's no reason to stall progress on usable and new syntax 
for novel semantics (i.e., shallow continuations). Harmony requires not putting 
the language into a no-new-syntax straightjacket. That was ES3.1 -> ES5, and we 
are past it.

Agreed - my note was just a "most value to the most users the soonest" 
argument.  Syntax is clearly important, and many of the proposals can only 
reasonably be offered as syntax.  Some of the proposals that can be partly 
delivered as libraries still benefit significantly from syntax as well.  But 
the adoption timelines for the new library pieces and the new syntax pieces 
will be quite different, not just because of downrev browsers, but also because 
of breaking change burden, authoring convenience, maintenance of old script, 
etc.

Luke


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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 12:17 PM, Allen Wirfs-Brock wrote:

> On Jul 19, 2011, at 11:56 AM, Luke Hoban wrote:
> 
 Object.extend(src, dest)
>> 
>>> This is certainly closest to paving the cowpath. Either via a built-in 
>>> module exporting 'extend', or as you suggest, directly on Object. The 
>>> Object.extend route is a bit harder to analyze, but not fatally so for any 
>>> capable static analysis framework.
>>> Either way (built-in module or Object.extend), old script (Hi Luke! ;-) 
>>> could use it too.
>> 
>> Agreed - this was my initial reaction to <| as well, and I still see a 
>> number of reasons to prefer a library solution over a syntax solution for 
>> both 'Obect.extend' and 'Object.make'.
>> 
>> The arguments for <| as an operator seemed to boil down to:
>> 1) It's more 'declarative'
>> 2) It can be optimized by engines
> 
> One issue is that <| conceptually modifies the [[Prototype]] of its RHS.  As 
> an operator (whether special character or keyword based) we can restrict the 
> RHS to be a literal and define the behavior such that no actual mutation of 
> [[Prototype]] is necessary.

Good point, and I should have noted that in my reply (which was supportive of 
Object.extend, where the problem does not arise).


> However, at the value level we have no way to distinguish an object that was 
> created via a literal and which has no references other than the current 
> argument value.  So, when we specify Object.make we have to accept an 
> arbitrary object as the second argument  and specify either [[Prototype]] 
> mutation or some sort of shallow copy, either of which can be problematic. 

We are *not* gonna standardize mutable [[Prototype]].

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 12:05 PM, Allen Wirfs-Brock wrote:

>> Good point, though it does open the should-constructor-objects-inherit can 
>> of worms.
> 
> Yes, but it is a can that needs to be emptied.

I agree. Other than "Java didn't have class-side inheritance and I did not miss 
it", I haven't heard a good reason to exclude it.


>> I'm not sure how effective it is to try to inherit constructor-like 
>> functions. If you're using inheritance, that implies to me that the derived 
>> object adds its own state that needs proper initialization. Given that, I 
>> worry that it would be more trouble than it's worth to define methods in 
>> base objects that can somehow anticipate that.
> 
> This is a primary use case for class-side inheritance in Smalltalk. The 
> collection class hierarchy is one place you can see their usage. Some design 
> thought is usually required for inheritance to be effective as an an 
> extension mechanism.  This applies whether you are on the class side or 
> instance side.  The reason and patterns for using 'this' as opposed to a 
> fixed value are the same on both sides.

And we've heard from Rubyists such as Yehuda Katz on this point.

https://mail.mozilla.org/pipermail/es-discuss/2011-June/014987.html


>> The main point is that to do the right think here it is important to not 
>> think of it as being just like C++/C#/Java
>> 
>> Absolutely right. I don't want to turn JS into Java (ugh), and I don't think 
>> anyone else does either. I do think JS isn't as far from other OOP languages 
>> as it might like to believe, and we can occasionally use that to our 
>> advantage.
> 
> I actually think JS is very far from class-as-static-nominal-type OOP 
> languages.  It is quite close to other dynamic OOPP languages.  The exemplars 
> we need to be look at are  Smalltalk, Ruby, and Python.

Don't forget Self :-P.

The functional programming (Scheme in spirit if not flesh) inspiration i took 
for JS also influences API design, avoiding silly single-method objects where 
functions will do.

/be

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2011, at 12:10 PM, Brendan Eich wrote:

> On Jul 19, 2011, at 11:39 AM, Allen Wirfs-Brock wrote:
>> 
> 
> 
>> The third column uses Object.specialize and Object.extend calls instead of 
>> <| and <&.
>> 
>> Note that Object.create can't be used instead of Object.specialize because I 
>> want the second argument to be a regular object literal rather than a 
>> property descriptor.
> 
> "specialize" is ambiguous with respect to copying vs. delegating. How about 
> Object.delegate(to, from)? Or Object.clone, a Self homage?
> 
> It's hard to love the keyword forms, and many clearly choke on the punctuator 
> stew. That plus the "usable from downrev scripts" lends weight to 
> Object.{clone,extend}.

I didn't expect any of the chosen words to stick, I think the visual shape of 
the code for the four alternatives is more interesting.  From that perspective 
I find that my eyes are more able to distinguish <| and <& as unique indicators 
that something important is happening near them.

WRT, the various words.  Their English meanings are simply hints (and for 
non-native speakers probably poor hints) at the actual specified meaning of 
each operator/function.  In my case, the concept that things down an 
inheritance hierarchy are more specialized and that things up the hierarchy are 
more generalized is deeply ingrained that "specialize" works as a very strong 
hint for me.  But that is a pretty geeky OO perspective and it might not work 
so well for others. Self use of clone has never seemed intuitive to me.  Clone 
to me is much more suggestive of a shallow copy.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2011, at 11:56 AM, Luke Hoban wrote:

>>> Object.extend(src, dest)
> 
>> This is certainly closest to paving the cowpath. Either via a built-in 
>> module exporting 'extend', or as you suggest, directly on Object. The 
>> Object.extend route is a bit harder to analyze, but not fatally so for any 
>> capable static analysis framework.
>> Either way (built-in module or Object.extend), old script (Hi Luke! ;-) 
>> could use it too.
> 
> Agreed - this was my initial reaction to <| as well, and I still see a number 
> of reasons to prefer a library solution over a syntax solution for both 
> 'Obect.extend' and 'Object.make'.
> 
> The arguments for <| as an operator seemed to boil down to:
> 1) It's more 'declarative'
> 2) It can be optimized by engines

One issue is that <| conceptually modifies the [[Prototype]] of its RHS.  As an 
operator (whether special character or keyword based) we can restrict the RHS 
to be a literal and define the behavior such that no actual mutation of 
[[Prototype]] is necessary.

However, at the value level we have no way to distinguish an object that was 
created via a literal and which has no references other than the current 
argument value.  So, when we specify Object.make we have to accept an arbitrary 
object as the second argument  and specify either [[Prototype]] mutation or 
some sort of shallow copy, either of which can be problematic. 

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 11:56 AM, Luke Hoban wrote:

> The arguments in favor of a library alternative are:
> 1) Immediately useful to all JS developers
> 2) Simple, understandable syntax consistent with existing practice

I agree with all this, but demur here:


> From discussions with some Microsoft dev teams, that could be a 3+ year 
> difference in adoption timeline. 

If this is a give me the goods now argument, and the goods can be expressed via 
functions, I'm with you.

If this is "new syntax takes too long to be usable due to downrev browsers, 
mainly IE", then that's no reason to stall progress on usable and new syntax 
for novel semantics (i.e., shallow continuations). Harmony requires not putting 
the language into a no-new-syntax straightjacket. That was ES3.1 -> ES5, and we 
are past it.

But I quite agree that we should consider functions as alternatives to special 
forms where they are plausible (so, not for yield, to pick up the shallow 
continuations example).

/be

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 11:39 AM, Allen Wirfs-Brock wrote:

> Ok,  I did a side-by-side comparisons of some alternatives.  
> Seehttp://wiki.ecmascript.org/lib/exe/fetch.php?id=harmony%3Aspecification_drafts&cache=cache&media=harmony:protooperator_alternatives.pdf
>  
> 
> The first column is by prototypal inheritance example using<| and <& from the 
> first message in this thread.
> 
> The second column is the same example with <| and <& replaced by keyword 
> operators "prototypes" and "extendBy".

Nit-pick here, but: No! Never camelCaps in keywords. Consider instanceof.

Please try another word, perhaps "copies".

> The third column uses Object.specialize and Object.extend calls instead of <| 
> and <&.
> 
> Note that Object.create can't be used instead of Object.specialize because I 
> want the second argument to be a regular object literal rather than a 
> property descriptor.

"specialize" is ambiguous with respect to copying vs. delegating. How about 
Object.delegate(to, from)? Or Object.clone, a Self homage?

It's hard to love the keyword forms, and many clearly choke on the punctuator 
stew. That plus the "usable from downrev scripts" lends weight to 
Object.{clone,extend}.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 11:37 AM, Bob Nystrom wrote:

> Yeah, I don't like things that look like bare assignment either. I know Mark 
> isn't a fan, but I'd consider:
> 
> new:
>   var numAttacks = 0;
>   var name;
> 
> Or maybe let. I like leading with some keyword.

Those mislead, although var less so in ES1-5 if you think of global var binding 
a property of the global object. Again, declarative binding forms should (and 
do in ES.next) create lexical definitions, not properties in objects.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Allen Wirfs-Brock

On Jul 19, 2011, at 10:50 AM, Bob Nystrom wrote:

> On Mon, Jul 18, 2011 at 6:50 PM, Allen Wirfs-Brock  
> wrote:
> But if you were coming from a language where constructors (classes) were real 
> objects with real methods that could reference this and which were inherited 
> by subclass object you might look at the issue quite differently
>>   class Point {
>> static zero() { return new Point(0, 0); }
>>   }
> 
> Good point, though it does open the should-constructor-objects-inherit can of 
> worms.

Yes, but it is a can that needs to be emptied.

>  
> in fact you might look at the above zero method and say, Oh, that's buggy.  
> He didn't think about what will happen when somebody creates Point3D as a 
> subclass and then codes:  Point3D.zero();
> 
> It's possible that he did think about it, and thinks the solution should be 
> to define an appropriate zero() method in Point3D.

Yes, but if that is the case there probably should have been a note that says 
that this property needs to be over-ridden when creating a subclass of Point.  
Even better, in that case would be do define AbstractPoint with zero and one 
methods that throw with a 'Subclass Responsibility' exception. (assume that the 
language has no built-in support for tagging properties as abstract.

>  
> A better definition would be:
> 
> class Point {
> static zero() { return new this(0, 0); }
>   }
> or, probably even better this:
> 
> class Point {
> static zero() { return new this( ); }
>   }
> 
> and you probably would want to make sure that the constructor always return 
> the origin for the default no argument case.
> 
> That works fine for zero() but what about unit() or other factory functions? 
> I can imagine convoluted solutions to that, but not anything that's simpler 
> and cleaner than just defining appropriate factory methods in the derived 
> class instead of trying to inherit them.
> 
> I'm not sure how effective it is to try to inherit constructor-like 
> functions. If you're using inheritance, that implies to me that the derived 
> object adds its own state that needs proper initialization. Given that, I 
> worry that it would be more trouble than it's worth to define methods in base 
> objects that can somehow anticipate that.

This is a primary use case for class-side inheritance in Smalltalk. The 
collection class hierarchy is one place you can see their usage. Some design 
thought is usually required for inheritance to be effective as an an extension 
mechanism.  This applies whether you are on the class side or instance side.  
The reason and patterns for using 'this' as opposed to a fixed value are the 
same on both sides.

>  
> The main point is that to do the right think here it is important to not 
> think of it as being just like C++/C#/Java
> 
> Absolutely right. I don't want to turn JS into Java (ugh), and I don't think 
> anyone else does either. I do think JS isn't as far from other OOP languages 
> as it might like to believe, and we can occasionally use that to our 
> advantage.

I actually think JS is very far from class-as-static-nominal-type OOP 
languages.  It is quite close to other dynamic OOPP languages.  The exemplars 
we need to be look at are  Smalltalk, Ruby, and Python.


>  
>> That's probably true (yay browser lock-in) but I don't know that's what I'd 
>> call a great attitude for usability. I'm imagining that as a bumper sticker. 
>> JavaScript: you're going to use it regardless.
> 
> I wasn't trying to make a statement about usability.  I actually think 
> usability (and readability) of language features is very important.  But I'm 
> more concerned about the long term usability of the language by people who 
> know the language well then I am about short term ease of adoption by 
> somebody today who is knowledgeable about some in a legacy language.
> 
> I may be overly optimistic, but I think you can have both: a syntax that 
> isn't totally foreign to people coming from other languages but is also 
> expressive and JS-centric enough to be pleasant to use by experts. I don't 
> know if the current class proposal is that, but I think it's important to try 
> for both before we settle and choose to exclude one set of users.

Can't argue with that, other than to say which "other languages".


>  
> JavaScript is here and and going to remain here for a very long time.  I want 
> it to hold together on its own terms and to be most usable for people for 
> whom it is their first and primary programming language.
> 
> Agreed, but I think it's important to keep in mind where it's coming from 
> too. For better or worse, its legacy is that it marries some relatively 
> uncommon semantics with a syntax largely inspired by Java (and C, C++, C#, 
> et. al). To me that means curly blocks, semicolons, keywords for structure 
> and flow control, and usually only operators for arithmetic and logical 
> operations.

exceptions that prove the rule:  ? :   ,->
Not to mention the impact of o

RE: An "extend" operator is a natural companion to <|

2011-07-19 Thread Luke Hoban
>> Object.extend(src, dest)

>This is certainly closest to paving the cowpath. Either via a built-in module 
>exporting 'extend', or as you suggest, directly on Object. The Object.extend 
>route is a bit harder to analyze, but not fatally so for any capable static 
>analysis framework.
> Either way (built-in module or Object.extend), old script (Hi Luke! ;-) could 
> use it too.

Agreed - this was my initial reaction to <| as well, and I still see a number 
of reasons to prefer a library solution over a syntax solution for both 
'Obect.extend' and 'Object.make'.

The arguments for <| as an operator seemed to boil down to:
1) It's more 'declarative'
2) It can be optimized by engines

For developer-facing benefit, I think the declarative claim is maybe not really 
very significant.  From feedback I've heard when showing <| to JS developers, I 
don't see there being a preference for <| over Object.make(proto, members).  
And as mentioned, for engine optimization, the library approach is harder, but 
should not be impossible to optimize for modern engines.  There is a chicken 
and egg game for optimization that engines likely won't invest in this till 
users use it, and vice versa - but from discussions with Chakra developers, I 
expect we'd prefer to spend our energy investing in this class of optimization 
instead of implementing bespoke syntax and hoping that developers use it.

The arguments in favor of a library alternative are:
1) Immediately useful to all JS developers
2) Simple, understandable syntax consistent with existing practice

Developers would not need to opt in to breaking changes to use the new library, 
and would not need to wait for all engine implementers to implement and all 
users to upgrade.  From discussions with some Microsoft dev teams, that could 
be a 3+ year difference in adoption timeline.  The most common usages of these 
libraries could be offered (with worse performance) by a shim library, which 
also helps.  I also generally feel like avoiding new operators when possible is 
a "good thing" for learnability and readability of the language.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Bob Nystrom
On Tue, Jul 19, 2011 at 11:23 AM, Brendan Eich  wrote:

> On Jul 19, 2011, at 11:07 AM, Bob Nystrom wrote:
>
> // "new" lets you declare members on new instances. these would presumably
> be
>
> // invoked on the new object before the constructor body is run.
> new:
>   numAttacks = 0;
>   // declaring an instance property here mainly so you can document it.
> could be
>   // useful later for guards or other annotations.
>   name;
>
>
> The plain name; also looks like a useless expression-statement.
>

Yeah. :( Granted, it isn't even necessary so this corner case may not matter
much. I mentioned it because our earlier proposals have included a
declarative syntax for instance properties, even though it's mostly for
documentation.


> Beyond this, I'm concerned that per-instance properties need initializers
> that use constructor parameters. So they ought to be initialized in the
> constructor.
>

Agreed. The ctor is where the real magic happens. Declaring instance
properties at the class level is just bonus. It would be useful for things
like having a place to hang a Closure-style type annotation comment, but
wouldn't be critical at runtime.

Whether they can be declared outside the constructor is a separate issue.
> Perhaps if they have constant or constructor-invariant initializers, they
> can be initialized where declared too.
>

Exactly. I do like the ability to declare and initialize per-instance
properties outside the constructor for properties that *don't* depend on
constructor arguments since it highlights that fact, but it isn't a key
requirement.


> But declarations should look different from expressions. The alternative we
> keep returning to is the property assignment sub-grammar of object literals,
> which would want
>
>   new:
> numAttacks: 0;
>

I'd worry that that's too close to the prototype: and class: section syntax
we're talking about adding. We use ":" so much already that I hesitate to
invoke it again.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Allen Wirfs-Brock
Ok,  I did a side-by-side comparisons of some alternatives.  
Seehttp://wiki.ecmascript.org/lib/exe/fetch.php?id=harmony%3Aspecification_drafts&cache=cache&media=harmony:protooperator_alternatives.pdf
 

The first column is by prototypal inheritance example using<| and <& from the 
first message in this thread.

The second column is the same example with <| and <& replaced by keyword 
operators "prototypes" and "extendBy".

The third column uses Object.specialize and Object.extend calls instead of <| 
and <&.

Note that Object.create can't be used instead of Object.specialize because I 
want the second argument to be a regular object literal rather than a property 
descriptor.

By their nature these are short examples and impressions may not scale to 
larger samples. 

If anybody wants to do their own experiments, the MS Word copy of the file is 
http://wiki.ecmascript.org/lib/exe/fetch.php?id=harmony%3Aspecification_drafts&cache=cache&media=harmony:protooperator_alternatives.doc
 

Allen


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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Bob Nystrom
On Tue, Jul 19, 2011 at 11:16 AM, Brendan Eich  wrote:

> On Jul 19, 2011, at 11:07 AM, Bob Nystrom wrote:
>
> (It may be that we should use constructor: or static: instead of class:.)
>
>
> Those hurt more. I like class, it is shortest and closest to the keyword
> that introduces the binding (in the named form, not for class expressions --
> but those want a connection back to the keyword too).
>

I like class too.


>   numAttacks = 0;
>   // declaring an instance property here mainly so you can document it.
> could be
>   // useful later for guards or other annotations.
>   name;
>
>
> Neat idea, although the assignment expression-statement appearance still
> rankles. It looks like statements are allowed there, rather than declaration
> forms of some sort. OTOH we are talking about properties, and declarations
> are in ES.next lexical binding forms if you exclude object literal property
> assignments from "declarations".
>

Yeah, I don't like things that look like bare assignment either. I know Mark
isn't a fan, but I'd consider:

new:
  var numAttacks = 0;
  var name;


Or maybe let. I like leading with some keyword.


> Not sure we need 'new' there given lack of private prototype properties in
> the proposal. It's a bit verbose. Probably even if we add private prototype
> properties we can let private: (in this idea you've pitched) default to
> private instance.
>

That works for me.


> No, don't , . I think what you've suggested here is strictly
> better than (a) over-indenting one or another group of elements; (b) putting
> "instance variable" declarations in magic syntax in the constructor body;
> (c) festooning one's class declaration with repeated "static" prefix
> keywords.
>

Yay!

I think this wins, so far. This does suggest we rushed classes in
> prematurely.
>

Well if we hadn't started covering the design space, we might not have
gotten here ever, so I'd consider it time well spent.


>  I'm not saying anything more than that we should take our time and avoid
> marrying the syntax in the proposal. We already have agreed that
> private(this), private(foo), etc. is straw to burn up.
>

Yeah, we'll have to let this marinate a bit and see if we like it. If I can
find some time, I'll try converting a non-trivial chunk of JS to use this
syntax and see how it looks in practice.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 11:07 AM, Bob Nystrom wrote:

> // "new" lets you declare members on new instances. these would presumably be

> // invoked on the new object before the constructor body is run.
> new:
>   numAttacks = 0;
>   // declaring an instance property here mainly so you can document it. could 
> be
>   // useful later for guards or other annotations.
>   name;

The plain name; also looks like a useless expression-statement.

Beyond this, I'm concerned that per-instance properties need initializers that 
use constructor parameters. So they ought to be initialized in the constructor.

Whether they can be declared outside the constructor is a separate issue. 
Perhaps if they have constant or constructor-invariant initializers, they can 
be initialized where declared too.

But declarations should look different from expressions. The alternative we 
keep returning to is the property assignment sub-grammar of object literals, 
which would want

  new:
numAttacks: 0;

with a semicolon not a comma.

Anyway, this is a detail, and we could even defer it and still have a better 
class proposal using your C++-inspired label idea. I'm quite taken with that!

/be

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 11:07 AM, Bob Nystrom wrote:

> This is probably a terrible idea, but in the interest of considering all 
> options,

Not terrible at all, and thanks for considering more options. I claim that is 
what es-discuss is for, so long as you've thought out the pitch and checked to 
avoid rehashing.


> we could do something like:
>  
> class Point {
>   constructor(x, y) {
> this.x = x;
> this.y = y;
>   }
> 
> class:
>   zero() {
> return new Point(0, 0);
>   }
> 
>   unit() {
> return new Point(1, 1);
>   }
> 
> prototype:
>   manhattanDistance() {
> return Math.abs(this.x) + Math.abs(this.y);
>   }
> }

I'm used to C++, so I buy it. Also, and more important, it avoids the 
gratuitous over-indentation tax on either class or prototype elements.


> So, class: and prototype: indicate that members declared after them go into 
> those objects, much like public: and private: in a class in C++. By default, 
> it assumes prototype: since that's where most members go. In this example 
> here, I'm switching back and forth just to show the idea, but idiomatic code 
> would likely be:
> 
> class Point {
>   constructor(x, y) {
> this.x = x;
> this.y = y;
>   }
> 
>   manhattanDistance() {
> return Math.abs(this.x) + Math.abs(this.y);
>   }

Right, default is prototype: to match the predominance of prototype "instance" 
methods over class methods.


> class:
>   zero() {
> return new Point(0, 0);
>   }
> 
>   unit() {
> return new Point(1, 1);
>   }
> }
> 
> (It may be that we should use constructor: or static: instead of class:.)

Those hurt more. I like class, it is shortest and closest to the keyword that 
introduces the binding (in the named form, not for class expressions -- but 
those want a connection back to the keyword too).


> That solves the double indentation problem.

Right!


> We could possibly extend this to handle declaratively specifying instance 
> members and/or public/private too:
> 
> class Monster {
>   constructor(name, health) {
> this.name = name;
> this.health = health;
>   }
>  
>   attack(target) {
> log('The monster attacks ' + target);
>   }
>  
>   // The contextual keyword "get" followed by an identifier and
>   // a curly body defines a getter in the same way that "get"
>   // defines one in an object literal.
>   get isAlive() {
> return this.health > 0;
>   }
>  
>   // Likewise, "set" can be used to define setters.
>   set health(value) {
> if (value < 0) {
>   throw new Error('Health must be non-negative.')
> }
> this.health = value
>   }
> 
> // "new" lets you declare members on new instances. these would presumably be
> // invoked on the new object before the constructor body is run.
> new:
>   numAttacks = 0;
>   // declaring an instance property here mainly so you can document it. could 
> be
>   // useful later for guards or other annotations.
>   name;

Neat idea, although the assignment expression-statement appearance still 
rankles. It looks like statements are allowed there, rather than declaration 
forms of some sort. OTOH we are talking about properties, and declarations are 
in ES.next lexical binding forms if you exclude object literal property 
assignments from "declarations".


> // "private" before a section lets you declare private members on that object.
> private new:
>   health;

Not sure we need 'new' there given lack of private prototype properties in the 
proposal. It's a bit verbose. Probably even if we add private prototype 
properties we can let private: (in this idea you've pitched) default to private 
instance.


> class:
>   create(name) {
> let health = Math.random(5, 20);
> return new Monster(name, health);
>   }
>  
>   const attackMessage = 'The monster hits you!';
> }
> 
> Strangely, I don't find myself hating this as much as I expected. 

No, don't , . I think what you've suggested here is strictly 
better than (a) over-indenting one or another group of elements; (b) putting 
"instance variable" declarations in magic syntax in the constructor body; (c) 
festooning one's class declaration with repeated "static" prefix keywords.

I think this wins, so far. This does suggest we rushed classes in prematurely. 
I'm not saying anything more than that we should take our time and avoid 
marrying the syntax in the proposal. We already have agreed that private(this), 
private(foo), etc. is straw to burn up.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 10:20 AM, Brendan Eich wrote:

> On Jul 19, 2011, at 10:06 AM, Dmitry A. Soshnikov wrote:
> 
>> Object.extend(src, dest)

Oops, except you have the arguments tranposed (thanks to shaver for pointing 
this out to me).

  Object.extend(dst, src)

or

  import extend from "@obj";
  extend(dst, src);

Any mutating function should take uncurried "this" as first parameter. Separate 
argument: strcpy/memcpy/memmove from Unix libc all imitate assignment by 
copying right to left. Anything else is a sanity challenge (I've had to deal 
with gdb vs. Intel x86, which disagree on this [gdb is wrong] for way too long).

/be

> 
> This is certainly closest to paving the cowpath. Either via a built-in module 
> exporting 'extend', or as you suggest, directly on Object. The Object.extend 
> route is a bit harder to analyze, but not fatally so for any capable static 
> analysis framework.
> 
> Either way (built-in module or Object.extend), old script (Hi Luke! ;-) could 
> use it too.
> 
> /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: An "extend" operator is a natural companion to <|

2011-07-19 Thread Bob Nystrom
On Mon, Jul 18, 2011 at 9:09 PM, Brendan Eich  wrote:

> On Jul 18, 2011, at 9:02 PM, Rick Waldron wrote:
>
> Hey Bob, FWIW...
>
>
>> class Point {
>>   constructor(x, y) {
>> this.x = x;
>> this.y = y;
>>   }
>>
>>   zero() {
>> return new Point(0, 0);
>>   }
>>
>>   unit() {
>> return new Point(1, 1);
>>   }
>>
>>   prototype {
>> manhattanDistance() {
>>   return Math.abs(this.x) + Math.abs(this.y);
>> }
>>   }
>> }
>>
>
> ...That's actually the nicest, most intuitively designed "class" structure
> I've seen so far.
>
>
> This is actually close to a less magical syntax that flips around the
> "ClassElements" (immediate children of the class {...} container) to specify
> class methods. Here's a less sugared version:
>
> class Point {
>>   zero() {
>> return new Point(0, 0);
>>   }
>>
>>   unit() {
>> return new Point(1, 1);
>>   }
>>
>>   prototype: {
>> constructor(x, y) {
>>   this.x = x;
>>   this.y = y;
>> }
>>
>> manhattanDistance() {
>>   return Math.abs(this.x) + Math.abs(this.y);
>> }
>>   }
>> }
>>
>
>>
> Notice how constructor is in the prototype object, as in JS with
> constructors and prototypes. Also, prototype: {...} not prototype {...}.
>
> As Bob noted, though, even in JS and moreso (from Allen's stats) in
> Smalltalk, class methods are uncommon compared to prototype methods. Do you
> really want an extra level of indentation for the latter?
>
> This example is skewed away from norms by having two class methods to one
> prototype method. I think constructor was mislocated, and when I fixed it
> just above, the instance- vs. class-method counts matched. Still
> unrealistic, though.
>
> If we want *more* magic from the class syntax, not less, we could use 'new'
> at the outer class-element indentation level to declare the constructor, and
> automagically impute 'constructor' in the prototype from it. But we'd still
> be over-indenting the prototype methods, which are many, compared to the
> class methods (few).
>

This is probably a terrible idea, but in the interest of considering all
options, we could do something like:

class Point {
  constructor(x, y) {
this.x = x;
this.y = y;
  }

class:
  zero() {
return new Point(0, 0);
  }

  unit() {
return new Point(1, 1);
  }

prototype:
  manhattanDistance() {
return Math.abs(this.x) + Math.abs(this.y);
  }
}

So, class: and prototype: indicate that members declared after them go into
those objects, much like public: and private: in a class in C++. By default,
it assumes prototype: since that's where most members go. In this example
here, I'm switching back and forth just to show the idea, but idiomatic code
would likely be:

class Point {
  constructor(x, y) {
this.x = x;
this.y = y;
  }

  manhattanDistance() {
return Math.abs(this.x) + Math.abs(this.y);
  }

class:
  zero() {
return new Point(0, 0);
  }

  unit() {
return new Point(1, 1);
  }
}

(It may be that we should use constructor: or static: instead of class:.)

That solves the double indentation problem. We could possibly extend this to
handle declaratively specifying instance members and/or public/private too:

class Monster {
  constructor(name, health) {
this.name = name;
this.health = health;
  }

  attack(target) {
log('The monster attacks ' + target);
  }

  // The contextual keyword "get" followed by an identifier and
  // a curly body defines a getter in the same way that "get"
  // defines one in an object literal.
  get isAlive() {
return this.health > 0;
  }

  // Likewise, "set" can be used to define setters.
  set health(value) {
if (value < 0) {
  throw new Error('Health must be non-negative.')
}
this.health = value
  }

// "new" lets you declare members on new instances. these would presumably
be
// invoked on the new object before the constructor body is run.
new:
  numAttacks = 0;
  // declaring an instance property here mainly so you can document it.
could be
  // useful later for guards or other annotations.
  name;

// "private" before a section lets you declare private members on that
object.
private new:
  health;

class:
  create(name) {
let health = Math.random(5, 20);
return new Monster(name, health);
  }

  const attackMessage = 'The monster hits you!';
}

Strangely, I don't find myself hating this as much as I expected. 

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Bob Nystrom
On Mon, Jul 18, 2011 at 6:50 PM, Allen Wirfs-Brock wrote:

> But if you were coming from a language where constructors (classes) were
> real objects with real methods that could reference this and which were
> inherited by subclass object you might look at the issue quite differently
>
>   class Point {
> static zero() { return new Point(0, 0); }
>   }
>
> Good point, though it does open the should-constructor-objects-inherit can
of worms.


> in fact you might look at the above zero method and say, Oh, that's buggy.
>  He didn't think about what will happen when somebody creates Point3D as a
> subclass and then codes:  Point3D.zero();
>

It's possible that he did think about it, and thinks the solution should be
to define an appropriate zero() method in Point3D.


> A better definition would be:
>
> class Point {
> static zero() { return new this(0, 0); }
>   }
>
> or, probably even better this:
>
> class Point {
> static zero() { return new this( ); }
>   }
>
>
> and you probably would want to make sure that the constructor always return
> the origin for the default no argument case.
>

That works fine for zero() but what about unit() or other factory functions?
I can imagine convoluted solutions to that, but not anything that's simpler
and cleaner than just defining appropriate factory methods in the derived
class instead of trying to inherit them.

I'm not sure how effective it is to try to inherit constructor-like
functions. If you're using inheritance, that implies to me that the derived
object adds its own state that needs proper initialization. Given that, I
worry that it would be more trouble than it's worth to define methods in
base objects that can somehow anticipate that.


> The main point is that to do the right think here it is important to not
> think of it as being just like C++/C#/Java
>

Absolutely right. I don't want to turn JS into Java (ugh), and I don't think
anyone else does either. I do think JS isn't as far from other OOP languages
as it might like to believe, and we can occasionally use that to our
advantage.


> That's probably true (yay browser lock-in) but I don't know that's what I'd
> call a great attitude for usability. I'm imagining that as a bumper sticker.
> JavaScript: you're going to use it regardless.
>
>
> I wasn't trying to make a statement about usability.  I actually think
> usability (and readability) of language features is very important.  But I'm
> more concerned about the long term usability of the language by people who
> know the language well then I am about short term ease of adoption by
> somebody today who is knowledgeable about some in a legacy language.
>

I may be overly optimistic, but I think you can have both: a syntax that
isn't totally foreign to people coming from other languages but is also
expressive and JS-centric enough to be pleasant to use by experts. I don't
know if the current class proposal is that, but I think it's important to
try for both before we settle and choose to exclude one set of users.


> JavaScript is here and and going to remain here for a very long time.  I
> want it to hold together on its own terms and to be most usable for people
> for whom it is their first and primary programming language.
>

Agreed, but I think it's important to keep in mind where it's coming from
too. For better or worse, its legacy is that it marries some relatively
uncommon semantics with a syntax largely inspired by Java (and C, C++, C#,
et. al). To me that means curly blocks, semicolons, keywords for structure
and flow control, and usually only operators for arithmetic and logical
operations.

While I'm personally not a huge fan of that style, JS is pretty consistent
with it. I'm 100% on board with bringing JS's unique features to the surface
in a clearer way but I'd be sad if we did that at the expense of syntactic
consistency. I think Objective-C is a cool language, but it's clearly and
unpleasantly two languages jammed into one (with "[]" as the duct tape
holding them together). I think we can do better than that.

JavaScript is its own unique combination of concepts and features. I think
> that some of the more significant warts in JavaScript (including the new
> operator, instanceof, and some aspects of constructor functions) are a
> direct result of such mimicry.
>

I think a lot of us would love to have a time machine to go back and fix
that (and block scope!). Until we can do that, I think the best we can hope
to do now is to move the language forward while getting the most use out of
its legacy "features" that we can.

Rather than continuing to just graft on features from other language we need
> to be evolving JavaScript on its own terms.  This needs to be informed by
> knowledge of the successes and failures of other language designs and many
> other things.   But I see little value in mimicry for its own sake.
>

I agree we shouldn't blindly ape other languages (especially ones we,
honestly, probably aren't too fond of

Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 10:06 AM, Dmitry A. Soshnikov wrote:

> Object.extend(src, dest)

This is certainly closest to paving the cowpath. Either via a built-in module 
exporting 'extend', or as you suggest, directly on Object. The Object.extend 
route is a bit harder to analyze, but not fatally so for any capable static 
analysis framework.

Either way (built-in module or Object.extend), old script (Hi Luke! ;-) could 
use it too.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Allen Wirfs-Brock

On Jul 18, 2011, at 7:24 PM, Axel Rauschmayer wrote:

>> From: Allen Wirfs-Brock 
>> Date: July 18, 2011 19:32:24 GMT+02:00
>> To: es-discuss 
>> Subject: An "extend" operator is a natural companion to <| 
> 
> 
> Definitely a nice dual to <|
> 
>> proto <| obj
> 
> 
> What happens if obj is not a literal? Then it would make sense to do a 
> shallow copy of obj whose prototype is proto. That would be useful for 
> combining objects into a chain.

That was my original thought, but for the proposal I limited to literal values 
on the RHS.  I did this to keep focus on the primary use cases and to not 
derail the feature with concerns about issues that don't occur in those primary 
use cases.   In particular there are some problematic issues relating to the 
concept of "shallow copy" of an arbitrary object.   What does that mean for 
host or Proxy based objects?  Is shallow copy a meaningful concept if the 
object uses closure capture to represent per object state? etc.

My think was that the feature could always be extended in the future to allow a 
non-literal RHS if we wanted to deal with those issues.


> 
> From your examples, it looks as if the lhs would be modified, a bit similar 
> to the += operator. Then the "arrow" should probably point in the opposite 
> direction, e.g.:
> 
>> objToBeModified +> increment

I don't follow your logic for the pointer direction. 


> 
> Quoting from your examples:
> 
>> function Point(x,y) {
>>return tthis <& {
>>   __x: x,
>>   __y: y
>>  };
>> };
>> Point.prototype <& {
>>__validate(x,y) { return typeof x == 'number' && typeof y = 'number'}
>> };
> 
> 
> I love how the prototype is incremented here. What does "tthis" do? Wouldn't 
> point simply return an object literal (no "this <&")?

No, because the [[Construct]] internal method set this to a new object whose 
[[Prototype]] is correctly initialized to Point.prototype.  You could return:
   Point.prototype <| { ...

As shown, in the immediately following constructor-based Point3D example, if 
you are going to build inheritance hierarchies using constructors like this you 
need to call the "super class" constructor.  If you think it is a good idea (it 
probably is) to always follow a common pattern for constructors then Point 
probably should have been written as:

function Point(x,y) {
   return Object.call(this) <& {
  __x: x,
  __y: y
 };
};


> 
> Another example from your message:
> 
>> const Point = {
>>  //private members
>>  __x: 0,
>>  __y: 0, 
>>  __validate(x,y) { return typeof x == 'number' && typeof y = 'number'},
>>  //public members
>>  new(x,y) {
>>   if (!this.__validate(x,y)) throw "invalid";
>>   return this <| {
>>   __x: x,
>>   __y: y
>>  }
>>   };
>> }
> 
> If things are ever done this way, I would prefer to have an initialize() 
> method (that only initializes an instance that has been created for it) and 
> not a method that instantiates and initializes at the same time. initialize() 
> works together very well with super-references, because in subclasses, you 
> simply call the super-initialize method.

Lots of possible patterns for these things.  I was just trying to illustrate 
key use cases and not suggest a recommend pattern.

Allen

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Dmitry A. Soshnikov

On 19.07.2011 20:59, Brendan Eich wrote:

On Jul 19, 2011, at 7:39 AM, Sean Eagan wrote:


On Mon, Jul 18, 2011 at 4:01 PM, Brendan Eich  wrote:

// replace<| with<>
let B = A<>  {...}; // looks like a (prototype) chain link

How so?

I'm talking about visual similarity with an actual physical chain link.

Very visual -- but my mind's eye sees something more like (=) in the right font 
to line up the round bracket tips with the equals bars...

Reasoning about ASCII art, especially with too few chars, is perilous.



That link is unidirectional. I don't buy it,

I'm thinking of it as "the pre-existing (prototype) properties go
before the new (own) properties", in other words the spatial and
temporal order of the properties matches.

Definitely want the prototype object on the left of<|. Not sure what else to 
say.



However, I agree with your comment in another post that contextual
keywords are worth considering even though they introduce restricted
productions.  If we were to go that route, I would propose:

// replace<| with "prototypes"
let B = A prototypes {
  ...
};

That does seem like the keyword to use. It's long, though.



// replace<&  with "owns"
let b = B owns {
  ...
};

"owns" is ambiguous -- could still delegate. Can't use "extends", the direction is wrong 
(and "extendedBy" is right out!). How about

   let b = B copies {...};

?

There must be a better contextual keyword...



mixin

or even

Object.extend(src, dest)

Dmitry.


/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: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 7:44 AM, Sean Eagan wrote:

> On Tue, Jul 19, 2011 at 9:39 AM, Sean Eagan  wrote:
>> // replace <& with "owns"
>> let b = B owns {
> 
> Sorry, that should have just been...
> 
> B owns {
>  ...
> }

B conquers {...}

Half-kidding. The mutating aspect still bothers me. Indeed it seems to have 
tripped you up too, since you wrote:

  let b = B owns {...}

as if owns were a pure operator.

If we are paving the "extend" cowpath, a function is the better paving material:

  import extend from "@obj"; // or @core or whatever

  extend(B, {...});

is completely unambiguous and no harder to analyze for a static program 
analysis tool that can parse ES.next than <&.

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Brendan Eich
On Jul 19, 2011, at 7:39 AM, Sean Eagan wrote:

> On Mon, Jul 18, 2011 at 4:01 PM, Brendan Eich  wrote:
>>> // replace <| with <>
>>> let B = A <> {...}; // looks like a (prototype) chain link
>> 
>> How so?
> 
> I'm talking about visual similarity with an actual physical chain link.

Very visual -- but my mind's eye sees something more like (=) in the right font 
to line up the round bracket tips with the equals bars...

Reasoning about ASCII art, especially with too few chars, is perilous.


>> That link is unidirectional. I don't buy it,
> 
> I'm thinking of it as "the pre-existing (prototype) properties go
> before the new (own) properties", in other words the spatial and
> temporal order of the properties matches.

Definitely want the prototype object on the left of <|. Not sure what else to 
say.


> However, I agree with your comment in another post that contextual
> keywords are worth considering even though they introduce restricted
> productions.  If we were to go that route, I would propose:
> 
> // replace <| with "prototypes"
> let B = A prototypes {
>  ...
> };

That does seem like the keyword to use. It's long, though.


> // replace <& with "owns"
> let b = B owns {
>  ...
> };

"owns" is ambiguous -- could still delegate. Can't use "extends", the direction 
is wrong (and "extendedBy" is right out!). How about

  let b = B copies {...};

?

There must be a better contextual keyword...

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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Sean Eagan
On Tue, Jul 19, 2011 at 9:39 AM, Sean Eagan  wrote:
> // replace <& with "owns"
> let b = B owns {

Sorry, that should have just been...

B owns {
  ...
}

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Sean Eagan
On Mon, Jul 18, 2011 at 4:01 PM, Brendan Eich  wrote:
>> // replace <| with <>
>> let B = A <> {...}; // looks like a (prototype) chain link
>
> How so?

I'm talking about visual similarity with an actual physical chain link.

> That link is unidirectional. I don't buy it,

I'm thinking of it as "the pre-existing (prototype) properties go
before the new (own) properties", in other words the spatial and
temporal order of the properties matches.

> and <> historically means not equal or unordered.

True, and it also looks like a diamond which some might associate with
multiple inheritance.  A better "prototype chain" analogy might be ><
since the operands themselves would then serve as the chain links
being linked together...

let B = A >< {
  ...
};

However, I agree with your comment in another post that contextual
keywords are worth considering even though they introduce restricted
productions.  If we were to go that route, I would propose:

// replace <| with "prototypes"
let B = A prototypes {
  ...
};
// replace <& with "owns"
let b = B owns {
  ...
};


Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Axel Rauschmayer
> From: Brendan Eich 
> Date: July 19, 2011 6:09:17 GMT+02:00
> To: Rick Waldron 
> Cc: es-discuss 
> Subject: Re: An "extend" operator is a natural companion to <|
> 
> This is actually close to a less magical syntax that flips around the 
> "ClassElements" (immediate children of the class {...} container) to specify 
> class methods. Here's a less sugared version:
> 
> class Point {
>   zero() {
> return new Point(0, 0);
>   }
> 
>   unit() {
> return new Point(1, 1);
>   }
> 
>   prototype: {
> constructor(x, y) {
>   this.x = x;
>   this.y = y;
> }
> 
> manhattanDistance() {
>   return Math.abs(this.x) + Math.abs(this.y);
> }
>   }
> }
> 


I like the above, but it probably makes sense to stay closer to the proposal:

class Point {
  constructor(x, y) {
this.x = x;
this.y = y;
  }

  manhattanDistance() {
return Math.abs(this.x) + Math.abs(this.y);
  }
  
  static {
zero() {
  return new Point(0, 0);
}
  
unit() {
  return new Point(1, 1);
}
  }
}

I wouldn’t mind a "static" before each class property, either, as those will 
become rarer with modules. The above also stays close to the status quo, 
because it is basically the prototype. I find it easy to understand and 
explain. The above is not much different from Allen’s syntax, and replacing the 
<& operator with "static". But it allows one to hide the gory details with 
syntactic sugar (i.e., one does not expose that those properties are actually 
added to the constructor). To me the class literal proposal looks like 
prototypes-as-classes, with desugaring to constructor-functions-as-classes.


-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: An "extend" operator is a natural companion to <|

2011-07-19 Thread Axel Rauschmayer
> From: Brendan Eich 
> Date: July 19, 2011 5:59:16 GMT+02:00
> To: Allen Wirfs-Brock 
> Cc: es-discuss 
> Subject: Re: An "extend" operator is a natural companion to <|
> 
> 
> On Jul 18, 2011, at 6:50 PM, Allen Wirfs-Brock wrote:
> 
>>> Even in Harmony, many of the new methods being adding are "static": 
>>> Proxy.create(), Proxy.createFunction(), Proxy.isTrapping(), 
>>> Object.getPropertyDescriptor(), Object.getPropertyNames(), Object.is(), 
>>> Number.isFinite(), Number.isNan()... If anything non-instance methods are 
>>> becoming more important in JS as time goes on (though modules might change 
>>> that).
>> 
>> Brendan and I recently had a discussion about some of these and it isn't 
>> clear that they are all in the correct places.  Of the ones you mentioned, 
>> I'm not so sure I would call Proxy a constructor.  (you never say, new 
>> Proxy() right?) it is really a factory object which means the methods you 
>> name are instance side.
> 
> No, rather Proxy is a module name. We could even spec it for ES.next as 
> something users must import from a standard library MRL:
> 
>   module Proxy from "@proxy";
> 
> and avoid polluting the global scope with 'Proxy' -- users get to name the 
> module. With ES.next modules, one can even selectively import:
> 
>   import createFunction from "@proxy";


This is awesome! A lot of “static” methods will go away now that we finally can 
have real modules.

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Brendan Eich
On Jul 18, 2011, at 9:02 PM, Rick Waldron wrote:

> Hey Bob, FWIW...
> 
> 
> class Point {
>   constructor(x, y) {
> this.x = x;
> this.y = y;
>   }
> 
>   zero() {
> return new Point(0, 0);
>   }
> 
>   unit() {
> return new Point(1, 1);
>   }
> 
>   prototype {
> manhattanDistance() {
>   return Math.abs(this.x) + Math.abs(this.y);
> }
>   }
> }
> 
> ...That's actually the nicest, most intuitively designed "class" structure 
> I've seen so far.

This is actually close to a less magical syntax that flips around the 
"ClassElements" (immediate children of the class {...} container) to specify 
class methods. Here's a less sugared version:

class Point {
  zero() {
return new Point(0, 0);
  }

  unit() {
return new Point(1, 1);
  }

  prototype: {
constructor(x, y) {
  this.x = x;
  this.y = y;
}

manhattanDistance() {
  return Math.abs(this.x) + Math.abs(this.y);
}
  }
}


Notice how constructor is in the prototype object, as in JS with constructors 
and prototypes. Also, prototype: {...} not prototype {...}.

As Bob noted, though, even in JS and moreso (from Allen's stats) in Smalltalk, 
class methods are uncommon compared to prototype methods. Do you really want an 
extra level of indentation for the latter?

This example is skewed away from norms by having two class methods to one 
prototype method. I think constructor was mislocated, and when I fixed it just 
above, the instance- vs. class-method counts matched. Still unrealistic, though.

If we want *more* magic from the class syntax, not less, we could use 'new' at 
the outer class-element indentation level to declare the constructor, and 
automagically impute 'constructor' in the prototype from it. But we'd still be 
over-indenting the prototype methods, which are many, compared to the class 
methods (few). What was that Spock said about the needs of the many?

/be

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Rick Waldron
Hey Bob, FWIW...


> class Point {
>   constructor(x, y) {
> this.x = x;
> this.y = y;
>   }
>
>   zero() {
> return new Point(0, 0);
>   }
>
>   unit() {
> return new Point(1, 1);
>   }
>
>   prototype {
> manhattanDistance() {
>   return Math.abs(this.x) + Math.abs(this.y);
> }
>   }
> }
>

...That's actually the nicest, most intuitively designed "class" structure
I've seen so far.

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Brendan Eich
On Jul 18, 2011, at 7:00 PM, Allen Wirfs-Brock wrote:

> On Jul 18, 2011, at 4:59 PM, Brendan Eich wrote:
> 
>> 
>> Word on the street, from folks ranging the skill gamut, is that <|, <& and 
>> so on are Perl-ish line noise. We should consider alternatives, even if it 
>> means restricted productions.
> 
> As I've said in the past, I'm generally more in the COBOL/readability camp 
> than I am in the APL/terseness  camp (in reality, I more of a PL/I guy.  (and 
> what's this new fangled Perl thing that everybody keeps talking about??))
> 
> That said, in writing sample code I've come to find <| to be rather pleasant 
> to both write and read. 

I can believe that. We should in any case not rush to judgment. "consider 
alternatives" means writing some side-by-side examples, playing with 
alternatives in practical code.


> Beyond that, we need to really decide what we want to surface syntax of JS to 
> be like as it evolve.  Do we want a keyword rich language or a concise 
> language that uses lots of special characters.  How to we find the balance 
> between the extreme.  For now I don't think we really have anything to guide 
> us so we keep oscillate  from on to the other based upon the latest feedback 
> on a proposal that goes one way or the other.

The main feedback is "don't grow the surface syntax too much". ES4 did 
overreach here, based on original-JS2/ES4 precedent and AS3. We should in any 
case not add "too much" (to be defined).

/be

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Brendan Eich
On Jul 18, 2011, at 6:50 PM, Allen Wirfs-Brock wrote:

>> Even in Harmony, many of the new methods being adding are "static": 
>> Proxy.create(), Proxy.createFunction(), Proxy.isTrapping(), 
>> Object.getPropertyDescriptor(), Object.getPropertyNames(), Object.is(), 
>> Number.isFinite(), Number.isNan()... If anything non-instance methods are 
>> becoming more important in JS as time goes on (though modules might change 
>> that).
> 
> Brendan and I recently had a discussion about some of these and it isn't 
> clear that they are all in the correct places.  Of the ones you mentioned, 
> I'm not so sure I would call Proxy a constructor.  (you never say, new 
> Proxy() right?) it is really a factory object which means the methods you 
> name are instance side.

No, rather Proxy is a module name. We could even spec it for ES.next as 
something users must import from a standard library MRL:

  module Proxy from "@proxy";

and avoid polluting the global scope with 'Proxy' -- users get to name the 
module. With ES.next modules, one can even selectively import:

  import createFunction from "@proxy";


> The Object refection methods were put on object because it was a convenient  
> "namespace" object. But that's not a style I would want to encourage for 
> complex user applications.

It depends on whether we have set a precedent, and also on the domain type (see 
below).


> isFinite and isNaN probably should go on the instance side.

No, that requires an extra test, as we discussed re: isGenerator. These are 
intentional any -> boolean non-coercing functions, not methods. They must be 
callable on any type of argument without testing that the argument is a number 
and then using it to call a method.

/be

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Axel Rauschmayer
> From: Bob Nystrom 
> Date: July 19, 2011 2:31:48 GMT+02:00
> To: Brendan Eich 
> Cc: es-discuss 
> Subject: Re: An "extend" operator is a natural companion to <|

To me, the important thing with class literals is to use naming consistently. 
If the class is named Point and you want to add properties to it, it seems odd 
to use an operator to add those properties to (what looks like) a method called 
"constructor". Under the hood, it makes sense. Superficially (with a sugared 
eye), it’s confusing.

> You could flip it around to:
> 
> class Point {
>   constructor(x, y) {
> this.x = x;
> this.y = y;
>   }
> 
>   zero() {
> return new Point(0, 0);
>   }
> 
>   unit() {
> return new Point(1, 1);
>   }
> 
>   prototype {
> manhattanDistance() {
>   return Math.abs(this.x) + Math.abs(this.y);
> }
>   }
> }


I kind of like the idea of parameterized object literals. But then I have no 
idea where class properties would go:

class Point(x,y) {
x: x,
y: y,
prototype {
manhattanDistance() {
return Math.abs(this.x) + Math.abs(this.y);
}
}
}

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Allen Wirfs-Brock

On Jul 18, 2011, at 4:59 PM, Brendan Eich wrote:

> 
> Word on the street, from folks ranging the skill gamut, is that <|, <& and so 
> on are Perl-ish line noise. We should consider alternatives, even if it means 
> restricted productions.

As I've said in the past, I'm generally more in the COBOL/readability camp than 
I am in the APL/terseness  camp (in reality, I more of a PL/I guy.  (and what's 
this new fangled Perl thing that everybody keeps talking about??))

That said, in writing sample code I've come to find <| to be rather pleasant to 
both write and read. 

Beyond that, we need to really decide what we want to surface syntax of JS to 
be like as it evolve.  Do we want a keyword rich language or a concise language 
that uses lots of special characters.  How to we find the balance between the 
extreme.  For now I don't think we really have anything to guide us so we keep 
oscillate  from on to the other based upon the latest feedback on a proposal 
that goes one way or the other.

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Allen Wirfs-Brock

On Jul 18, 2011, at 4:50 PM, Bob Nystrom wrote:

> 
> 
> On Mon, Jul 18, 2011 at 3:40 PM, Allen Wirfs-Brock  
> wrote:
> 
> On Jul 18, 2011, at 1:05 PM, Bob Nystrom wrote:
>> 2. Familiar from other languages and it works about the same here as it does 
>> in those
> Arguably it doesn't.  Java/C# static methods are not 
> inherited/over-ridable...of course that leads to the issue of 
> constructor-side inheritance.
> 
> I did say "about the same" and not exactly the same. Naturally there are some 
> differences, but there are plenty of similarities too. I don't think a 
> programmer from C++/C#/Java would find this astonishing at all, and would 
> probably have little trouble inferring what it means:

But if you were coming from a language where constructors (classes) were real 
objects with real methods that could reference this and which were inherited by 
subclass object you might look at the issue quite differently

> 
>   class Point {
> static zero() { return new Point(0, 0); }
>   }

in fact you might look at the above zero method and say, Oh, that's buggy.  He 
didn't think about what will happen when somebody creates Point3D as a subclass 
and then codes:  Point3D.zero();

A better definition would be:

class Point {
static zero() { return new this(0, 0); }
  }
or, probably even better this:

class Point {
static zero() { return new this( ); }
  }

and you probably would want to make sure that the constructor always return the 
origin for the default no argument case.

The main point is that to do the right think here it is important to not think 
of it as being just like C++/C#/Java


>   
>   var p = Point.zero();
> 
>> 1. We want to re-use keywords from other languages to make JS familiar and 
>> to use what's already in the programmer's head. If some JS construct looks 
>> and acts similar to a construct in other popular languages, using the same 
>> word for it is like instant knowledge.
> 
> I don't think we have listed this as a design guideline anywhere.
> 
> Does it need to be written down as a guideline to be a good idea?

The real issue is what is both looks and acts similarly enough to make this a 
good rule to apply.  There is clearly some disagreement about this particular 
case and a hazard of this general rule.
>  
> If a word/constructor looks the same or even similar but has different 
> semantics we have instance confusion rather than instant knowledge.
> 
> We don't have to look familiar to get people to use JavaScript.  They are 
> going to use it regardless.
> 
> That's probably true (yay browser lock-in) but I don't know that's what I'd 
> call a great attitude for usability. I'm imagining that as a bumper sticker. 
> JavaScript: you're going to use it regardless.

I wasn't trying to make a statement about usability.  I actually think 
usability (and readability) of language features is very important.  But I'm 
more concerned about the long term usability of the language by people who know 
the language well then I am about short term ease of adoption by somebody today 
who is knowledgeable about some in a legacy language. JavaScript is here and 
and going to remain here for a very long time.  I want it to hold together on 
its own terms and to be most usable for people for whom it is their first and 
primary programming language.

> 
>  We may be past the point where these is much value in mimicking other 
> languages.
> 
> What makes you say that?

JavaScript is its own unique combination of concepts and features. I think that 
some of the more significant warts in JavaScript (including the new operator, 
instanceof, and some aspects of constructor functions) are a direct result of 
such mimicry.  Rather than continuing to just graft on features from other 
language we need to be evolving JavaScript on its own terms.  This needs to be 
informed by knowledge of the successes and failures of other language designs 
and many other things.   But I see little value in mimicry for its own sake.


>  
> I was speaking primarily from Smalltalk experience.  Even though it had  very 
> good tool support for class-side methods, there use is relatively rare.
> 
> I'm not a Smalltalker but my impression is that Smalltalk culture was more 
> open to defining things as instance methods where a Javascripter would likely 
> make a static method on some constructor. Especially in recent years where 
> monkey-patching existing protos is considered bad form, that leads to fewer 
> instance methods and more static ones. Likewise, for-in loops discourage 
> adding methods on prototypes.

This may well be the case, but is it something we want to encourage for the 
next 50 years? Most behavior belongs on instances because it is the instance 
that model the computation system of the program.  Instances are what OO design 
and programming is all about.  If we make it easy to define instance behavior 
and harder to define "static" behavior that is probably a good think in the 
long run.

Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Brendan Eich
On Jul 18, 2011, at 5:31 PM, Bob Nystrom wrote:

> class Point {
>   constructor(x, y) {
> this.x = x;
> this.y = y;
>   }
> 
>   zero() {
> return new Point(0, 0);
>   }
> 
>   unit() {
> return new Point(1, 1);
>   }
> 
>   prototype {
> manhattanDistance() {
>   return Math.abs(this.x) + Math.abs(this.y);
> }
>   }
> }
> 
> Pros:
> 1. Makes it abundantly clear that prototype members are just that.

But that's not a good in itself, and your argument about many other languages 
putting "instance methods" at the level that this approach uses for class 
methods goes against.


> 2. Makes it clearer (I think?) that members on the constructor ("class") are 
> that. Basically, the name of the surrounding curly ("prototype" or "class") 
> tells you where the member goes.

This is a fair point but I think it is outweighed by the Cons (mine plus yours).


> Cons:
> 1. Prototype members, the most common case, are the most verbose and suffer 
> two levels of indentation.

That's a problem too (in addition to the strangeness compared to other 
languages with 'class' syntax).


> 2. constructor() is in weird limbo. Should it be under prototype or class?

It binds a prototype property (MyDate.prototype.constructor), absent more magic 
to make that alias. It does not bind a class property (e.g., 
MyDate.constructor).


> 3. Lots'o'curlies.

This is a pain, but so are lots o' statics -- but generally class methods are 
few, so it could be a wash.


> There may be a good solution hiding in here somewhere, but I'm not sure.


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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Bob Nystrom
On Mon, Jul 18, 2011 at 4:59 PM, Brendan Eich  wrote:

>  The primary purpose of a class is to define the behavior (methods) of
>> instances. It is describing an abstraction over all the possible instances.
>> The behavior of the singleton class object is typically secondary to the
>> primary abstraction.
>>
>
> True, but secondary still matters.
>
> Here you were arguing about class vs. prototype method indentation or body
> nesting level?
>

I think Allen was explaining why it makes sense for "static" methods to be
in a second curly block following the main class definition.

I could see us making a subordinate body for class methods, instead of using
> 'static'.


Interesting idea! Something like this?

class Point {
  constructor(x, y) {
this.x = x;
this.y = y;
  }

  manhattanDistance() {
return Math.abs(this.x) + Math.abs(this.y);
  }

  ??? {
zero() {
  return new Point(0, 0);
}

unit() {
  return new Point(1, 1);
}
  }
}

It looks a little strange to me to lump the class members together like that
and leave the prototype ones directly under class given that the prototype
members don't end up on the class. You could flip it around to:

class Point {
  constructor(x, y) {
this.x = x;
this.y = y;
  }

  zero() {
return new Point(0, 0);
  }

  unit() {
return new Point(1, 1);
  }

  prototype {
manhattanDistance() {
  return Math.abs(this.x) + Math.abs(this.y);
}
  }
}

Pros:
1. Makes it abundantly clear that prototype members are just that.
2. Makes it clearer (I think?) that members on the constructor ("class") are
that. Basically, the name of the surrounding curly ("prototype" or "class")
tells you where the member goes.

Cons:
1. Prototype members, the most common case, are the most verbose and suffer
two levels of indentation.
2. constructor() is in weird limbo. Should it be under prototype or class?
3. Lots'o'curlies.

There may be a good solution hiding in here somewhere, but I'm not sure.

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Brendan Eich
On Jul 18, 2011, at 4:50 PM, Bob Nystrom wrote:

> On Mon, Jul 18, 2011 at 3:40 PM, Allen Wirfs-Brock  
> wrote:
> 
> On Jul 18, 2011, at 1:05 PM, Bob Nystrom wrote:
>> 2. Familiar from other languages and it works about the same here as it does 
>> in those
> Arguably it doesn't.  Java/C# static methods are not 
> inherited/over-ridable...of course that leads to the issue of 
> constructor-side inheritance.
> 
> I did say "about the same" and not exactly the same. Naturally there are some 
> differences, but there are plenty of similarities too. I don't think a 
> programmer from C++/C#/Java would find this astonishing at all, and would 
> probably have little trouble inferring what it means:
> 
>   class Point {
> static zero() { return new Point(0, 0); }
>   }
>   
>   var p = Point.zero();

Indeed, isn't that legal C# 4.0? :-P


> 
>> 1. We want to re-use keywords from other languages to make JS familiar and 
>> to use what's already in the programmer's head. If some JS construct looks 
>> and acts similar to a construct in other popular languages, using the same 
>> word for it is like instant knowledge.
> 
> I don't think we have listed this as a design guideline anywhere.
> 
> Does it need to be written down as a guideline to be a good idea?

Zing!

I've been on this side since ES4 days. I'm a bit older and wiser, so I'll just 
add that it takes nice judgment and experience to know when to imitate and when 
to diverge.

It's clear classes are not quite complete or coherent for ES.next, even though 
the proposal has been accepted (too many open issues, some not recorded). 
Imitating another language won't settle the open issues. We need to focus on 
specifics and simplify if possible, cut if necessary.


>  
> If a word/constructor looks the same or even similar but has different 
> semantics we have instance confusion rather than instant knowledge.
> 
> We don't have to look familiar to get people to use JavaScript.  They are 
> going to use it regardless.
> 
> That's probably true (yay browser lock-in) but I don't know that's what I'd 
> call a great attitude for usability. I'm imagining that as a bumper sticker. 
> JavaScript: you're going to use it regardless.

I'm with Bob here.

Word on the street, from folks ranging the skill gamut, is that <|, <& and so 
on are Perl-ish line noise. We should consider alternatives, even if it means 
restricted productions.


> The primary purpose of a class is to define the behavior (methods) of 
> instances. It is describing an abstraction over all the possible instances. 
> The behavior of the singleton class object is typically secondary to the 
> primary abstraction.
> 
> True, but secondary still matters.

Here you were arguing about class vs. prototype method indentation or body 
nesting level? I could see us making a subordinate body for class methods, 
instead of using 'static'.

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Bob Nystrom
On Mon, Jul 18, 2011 at 3:40 PM, Allen Wirfs-Brock wrote:

>
> On Jul 18, 2011, at 1:05 PM, Bob Nystrom wrote:
>
> 2. Familiar from other languages and it works about the same here as it
> does in those
>
> Arguably it doesn't.  Java/C# static methods are not
> inherited/over-ridable...of course that leads to the issue of
> constructor-side inheritance.
>

I did say "*about* the same" and not *exactly* the same. Naturally there are
some differences, but there are plenty of similarities too. I don't think a
programmer from C++/C#/Java would find this astonishing at all, and would
probably have little trouble inferring what it means:

  class Point {
static zero() { return new Point(0, 0); }
  }

  var p = Point.zero();

1. We want to re-use keywords from other languages to make JS familiar and
> to use what's already in the programmer's head. If some JS construct looks
> and acts similar to a construct in other popular languages, using the same
> word for it is like instant knowledge.
>
> I don't think we have listed this as a design guideline anywhere.
>

Does it need to be written down as a guideline to be a good idea?


> If a word/constructor looks the same or even similar but has different
> semantics we have instance confusion rather than instant knowledge.
>
> We don't have to look familiar to get people to use JavaScript.  They are
> going to use it regardless.
>

That's probably true (yay browser lock-in) but I don't know that's what I'd
call a great attitude for usability. I'm imagining that as a bumper sticker.
JavaScript: you're going to use it regardless.

 We may be past the point where these is much value in mimicking other
> languages.
>

What makes you say that?


> I was speaking primarily from Smalltalk experience.  Even though it had
>  very good tool support for class-side methods, there use is relatively
> rare.
>

I'm not a Smalltalker but my impression is that Smalltalk culture was more
open to defining things as instance methods where a Javascripter would
likely make a static method on some constructor. Especially in recent years
where monkey-patching existing protos is considered bad form, that leads to
fewer instance methods and more static ones. Likewise, for-in loops
discourage adding methods on prototypes.

Even in Harmony, many of the new methods being adding are "static":
Proxy.create(), Proxy.createFunction(), Proxy.isTrapping(),
Object.getPropertyDescriptor(), Object.getPropertyNames(), Object.is(),
Number.isFinite(), Number.isNan()... If anything non-instance methods are
becoming more important in JS as time goes on (though modules might change
that).

Certainly less than 5% of all methods particularly if you discount the
> class-side methods that implement and support the new method which is
> basically the Smalltalk equivalent of the normal constructor.
>

My rough calculation was around 10% looking at Closure JS code.


> They certainly shouldn't be particularly inconvenient to define. But they
> aren't a central feature of OO design and probably don't deserve quite as
> much language design attention as instance methods.
>

Agreed.


> The primary purpose of a class is to define the behavior (methods) of
> instances. It is describing an abstraction over all the possible instances.
> The behavior of the singleton class object is typically secondary to the
> primary abstraction.
>

True, but secondary still matters.

> 3. Unless I've had it explained to me, there's no way I could figure out
> what that code means even if I'm an expert in other programming languages.
>
> Yes,but how long will it take you to learn it.  Isn't it better when
> learning something new to know that you don't understand it rather than to
> being mislead into thinking it is something familiar when it really isn't.
>

I don't like being led astray, certainly. Personally, I do like learning
"this is kinda like a foo" and then later having that refined to "but it
doesn't bar and it bazzes". I'd rather that than having to learn a new
concept from a blank page only to reach the end and realize "hey, this is
75% like a foo."

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Allen Wirfs-Brock

On Jul 18, 2011, at 1:37 PM, Brendan Eich wrote:

> On Jul 18, 2011, at 12:16 PM, Allen Wirfs-Brock wrote:
> 
>> On Jul 18, 2011, at 11:32 AM, Brendan Eich wrote:
>> 
>>> Hawt.
>>> 
>>> A bit rough in that LHS <& RHS mutates LHS, whereas LHS <| RHS is pure and 
>>> produces a new object (which could be optimized to mutate RHS, note well!). 
>>> Both <| and <& are operators, to support chaining. Would it be better for 
>>> <& to be pure as <| is, and make an assignment operator form, LHS <&= RHS, 
>>> that expands to LHS = LHS <& RHS?
>> 
>> One way to think about <& is as a more declarative and more concise 
>> alternative to Object.defineProperties. I think there are plenty of use 
>> causes for the mutating extends.  For example, adding properties to the 
>> prototype object of a function.  Another issue is that the object you need 
>> to extend may already have been captured somewhere.  For example, a 
>> super.constructor call might have registered the object in a WeakMap and if 
>> <& created a new instance you would loose the identify relationship.
> 
> Sure, I'm not saying word one against the mutating form -- just noting the 
> symmetry break w.r.t. <| and suggesting a fix that builds on the assignment 
> operator.

You're right it can be viewed that way.  Even though I know that = or += and 
friends are just operators I think I tend to think of them more like a 
statement form.  Also all the other assignment operators are operations upon 
values and they modify a variable rather than mutate an object.  I see where 
you're coming from on this but personally that lack of symmetry with the other 
assignment operators feels more disconcerting then the lack of symmetry with <|.


> 
> 
>> In practice, I think most of the more declarative uses such as adding own 
>> properties can be implemented (and perhaps even specified) such that no 
>> extra objects need to be created.
> 
> Agreed.
> 
> 
>> One thing that I think is still open is whether the RHS needs to be an 
>> ObjectLiteral or whether any object producing expression should be allowed.  
>> All the use cases  I have explored use an ObjectLiteral but I don't see any 
>> hazard (like would be the case if <| mutated the LHS [[Prototype]]) with 
>> allowing a non-literal value of the RHS.
> 
> Probably right; another symmetry break.

Yes, if the symmetry argument would be my primary reason for restricting the 
RHS.  But then <& could be use for things like:

Object.prototype.extend = function (obj) {this <& obj};


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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Allen Wirfs-Brock

On Jul 18, 2011, at 1:05 PM, Bob Nystrom wrote:

> On Mon, Jul 18, 2011 at 10:32 AM, Allen Wirfs-Brock  
> wrote:
> > This is a nice declarative way to describe the per instance state but it 
> > turns out it doesn't generalize very well to multiple levels of inheritance.
> 
> This is an important point. I think the reason most OOP languages make a 
> distinction between object construction and initialization is because in the 
> presence of inheritance, you need 1 construction, but N initializations where 
> N is the depth of your inheritance chain. If you try to construct and 
> initialize in one step, it's hard to do that (as your proposal addresses).
> 
> > A similar issue exists for the proposed class declarations.  That proposal 
> > includes the concept of "static" (a lot of us don't like that the term 
> > "static" in this context)  property declaration:
> 
> Yeah, I don't think anyone is crazy about that keyword, but it's:
> 
> 1. Reserved already.

But we are using it in a context where that isn't an issue.

> 2. Familiar from other languages and it works about the same here as it does 
> in those

Arguably it doesn't.  Java/C# static methods are not 
inherited/over-ridable...of course that leads to the issue of constructor-side 
inheritance.

> 
> I liked "class" instead, but the worry about nested classes was enough to 
> talk me out of it.
> 
> We have a challenge with JS keywords:
> 
> 1. We want to re-use keywords from other languages to make JS familiar and to 
> use what's already in the programmer's head. If some JS construct looks and 
> acts similar to a construct in other popular languages, using the same word 
> for it is like instant knowledge.

I don't think we have listed this as a design guideline anywhere.   If a 
word/constructor looks the same or even similar but has different semantics we 
have instance confusion rather than instant knowledge.

We don't have to look familiar to get people to use JavaScript.  They are going 
to use it regardless.  We may be past the point where these is much value in 
mimicking other languages.

> 
> 2. We want to emphasize JS's unique features. JS is not Java (or C++, or C#, 
> or Smalltalk, or Ruby) and we run the risk of leading users down a false path 
> if we make JS look superficially too much like them. There's also a strong 
> cultural bias where JS = light, terse, expressive, fun and Java = verbose, 
> rigid, work. Borrowing keywords from Java makes people worry that there's 
> going to be a JavaScript khaki dress code. Personally, I think that's much 
> ado about nothing, but I can understand why people would worry that the suits 
> are going to show up and crash the party.
> 
> > Static properties are really just own properties of the constructor object. 
> >  While sometimes useful, they occur relatively infrequently yet they 
> > require a additional declaration form within class bodies.
> 
> I just did some quick hunting through a few classes in the Closure library. 
> Instance methods are definitely the most common kind of member there, but 
> static methods were used in every type I looked at. For example, 
> goog.ui.Component has a static mutable field, three "constants" which are 
> properties on the constructor, and a couple of static methods. 
> goog.ui.Tooltip has five members that would use "static" in the class 
> proposal.

I was speaking primarily from Smalltalk experience.  Even though it had  very 
good tool support for class-side methods, there use is relatively rare. 
Certainly less than 5% of all methods particularly if you discount the 
class-side methods that implement and support the new method which is basically 
the Smalltalk equivalent of the normal constructor.

They certainly shouldn't be particularly inconvenient to define. But they 
aren't a central feature of OO design and probably don't deserve quite as much 
language design attention as instance methods. 

BTW, you may find some of the metric at 
http://www.emunix.emich.edu/~ahmad/metrdes.htm interesting.

> 
> > This complicates the conceptual model of a class declaration by allowing 
> > intermingling of constructor and prototype property declaration.
> 
> There can also be confusion between what goes on the prototype and what goes 
> on the new instance.

Exactly.  I'm arguing that placing instance properties in an extension object 
literal within the constructor is a way to reduce this confusion without adding 
new property declarations that can only occur in the function bodies of 
constructor functions.


> 
> > This also increase the potential for confusion about the meaning of "this"  
> > (and "super") within such static property declarations.
> 
> Good point. From a conceptual simplicity argument, I like the idea of having 
> different curly blocks for "stuff on the ctor" and "stuff on the proto". 
> Pragmatically, though, C++, Java, and C# all mix instance and non-instance 
> members together and people seem to get by without too much troub

Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Allen Wirfs-Brock

On Jul 18, 2011, at 11:26 AM, Dmitry A. Soshnikov wrote:

> On 18.07.2011 21:32, Allen Wirfs-Brock wrote:
>> 
>> I've recently been experimenting with coding both prototypal and class based 
>> object definitions using the various syntactic forms that are currently on 
>> the table.  Something has emerged from that which has surprised me.  I have 
>> never been a big fan of the "extend" method that is provided by a number of 
>> JavaScript frameworks. However, based upon my experiments I'm now think that 
>> something like extend solves several issues with the declarative object and 
>> class declarations that we have recently been discussing.
>> 
>> Just in case there is anyone on this list who isn't familiar with extend, 
>> here is a quick explanation. In most frameworks that support it, "extend" is 
>> invoked something like this: 
>>obj.extend(extensionObj)
>> It copies the own properties of  extensionObj and makes corresponding own 
>> properties for obj.
> 
> JFTR: object.extend(...) first appeared in Prototype.js and was borrowed 
> there from Ruby. In Ruby though, this method method is delegation-based (that 
> is, a hidden class is created which is inserted as a direct ancestor of the 
> object and the superclass of the hidden class is set to extending module). 
> That is, if something changes in the mixed module, the changes are reflected 
> on the object which extended it.
> 

...

> Perhaps ES wants also this approach. OTOH, "extend" practice is already 
> strongly used in JS and from this viewpoint it makes sense to make extending 
> with copying and not using delegation.

That would require at mutable [[Prototype]] which is something we have been 
trying to stay away from in TC39.

> 
> 
...
> Am I alone here who want to put a space after the methods in this proposal? 
> ;) It's like operators, really:

feel free to use one.  a space isn't syntactically significant in that 
position. 

...
> 
> 
>>   if (!this.__validate(x,y)) throw "invalid";
>>   return this <| {
>>   __x: x,
>>   __y: y
>>  }
>>   };
>> }
>> 
> 
> What's the reason we want back to desugared factories (with all this explicit 
> stuff, manual `return`, setting manually proto, etc) instead of improving 
> constructors syntax by forming them to classes? Is the syntax already 
> accepted for classes by the way? I remind again this syntactic form which 
> seems (for me?) more elegant 
> http://dmitrysoshnikov.com/scheme-on-coffee/class.html.

One of the design issues in the class proposals has been how to distinguish 
between prototype properties and per instance properties added by a 
constructor.  The current class proposal uses public/private declarations in 
the constructor for that purpose. This proposal of mine is suggesting that 
instead of adding special syntax just for constructors in class declarations we 
should consider adding a new operator (<&) with multiple uses that can also 
address the constructor use case.



...

> I'm really sorry, perhaps it's only for me, but all these examples seem to me 
> too cryptic in respect of syntax (even like Perl). All these `} <& {` seem 
> for me as a syntactic noise. I even better would like to see some longer but 
> humanized "extends" keyword. Maybe it's about the habit and perhaps later it 
> will become for me not so cryptic (after all I can accept -> #, {||}, etc. as 
> an alternative for `function`).
> 

I'm sympathetic  to the crypticness argument but I get just as many arguments 
on the other side of the issue when proposing keyword based extensions.
Also, it is generally harder (but not necessarily impossible) to add keyword 
operators then it is special character based operators.  Automatic semi-colon 
insertion gets in the way.
Consider:

var function extend() {};
var bar = foo
   extend ({y:20});

> E.g.
> 
> let foo = {x: 10}
> 
> // delegation-based extending
> let bar = foo extend {
>   y: 20;
> };
> 
> // copy-based extending
> bar.mixin({
>   z: 30
> });
> 
> Pity btw, that < is already borrowed and is a normal operator, we could use 
> it instead of <| which is not the best on different fonts.  value="Mayber a back arrow? <- " />

 foo <-bar  //   foo < (-bar)

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Brendan Eich
On Jul 18, 2011, at 1:39 PM, Sean Eagan wrote:

> On Mon, Jul 18, 2011 at 1:44 PM, Allen Wirfs-Brock
>  wrote:
>>> Also, how about |> as opposed to <&, since it is a dual to <| adding
>>> own rather than inherited properties?
>> 
>> I'd be a bit concerned about  some people getting confused about which 
>> direction of the "arrow" corresponds to each operation.
> 
> I think the arrow-to-operator correspondence would be fairly easy to
> remember... "extension arrows point back in space to prototypes which
> exist back in time , and forward in space to own properties which will
> exist forward in time".

Whatever happens, we mix metaphors:

1. <| is pointing in the reference direction of __proto__ aka [[Prototype]].

2. <& is pointing to the copy destination.

However, making the arrow point to the right mixes yet another metaphor:

3. +> or whatever points to the copy sources.

I do not think 3 helps as much as it hurts.

Separate point: left to right assignment or copy operation is confusing in many 
languages, and right to left is the norm. This goes back to assembly variants 
(gdb x86 vs. Intel ASM). JS uses right to left assignment direction. I think 
this must matter.


>> I like the nemonic value of having + or & as part of the operator symbol for 
>> "extend" but  unfortunately <+ can't be used.
> 
> One thing to note is that <& would disallow using & as a unary
> operator in the future.

Yup. No plans there.


> Here's another option to consider:
> 
> // replace <| with <>
> let B = A <> {...}; // looks like a (prototype) chain link

How so? That link is unidirectional. I don't buy it, and <> historically means 
not equal or unordered.


> // then +> could make sense
> let b = B +> {}; // "adding" pointed to properties.

See above.

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Sean Eagan
On Mon, Jul 18, 2011 at 1:44 PM, Allen Wirfs-Brock
 wrote:
>> Also, how about |> as opposed to <&, since it is a dual to <| adding
>> own rather than inherited properties?
>
> I'd be a bit concerned about  some people getting confused about which 
> direction of the "arrow" corresponds to each operation.

I think the arrow-to-operator correspondence would be fairly easy to
remember... "extension arrows point back in space to prototypes which
exist back in time , and forward in space to own properties which will
exist forward in time".

>
> I like the nemonic value of having + or & as part of the operator symbol for 
> "extend" but  unfortunately <+ can't be used.

One thing to note is that <& would disallow using & as a unary
operator in the future.

Here's another option to consider:

// replace <| with <>
let B = A <> {...}; // looks like a (prototype) chain link
// then +> could make sense
let b = B +> {}; // "adding" pointed to properties.


Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Brendan Eich
On Jul 18, 2011, at 12:16 PM, Allen Wirfs-Brock wrote:

> On Jul 18, 2011, at 11:32 AM, Brendan Eich wrote:
> 
>> Hawt.
>> 
>> A bit rough in that LHS <& RHS mutates LHS, whereas LHS <| RHS is pure and 
>> produces a new object (which could be optimized to mutate RHS, note well!). 
>> Both <| and <& are operators, to support chaining. Would it be better for <& 
>> to be pure as <| is, and make an assignment operator form, LHS <&= RHS, that 
>> expands to LHS = LHS <& RHS?
> 
> One way to think about <& is as a more declarative and more concise 
> alternative to Object.defineProperties. I think there are plenty of use 
> causes for the mutating extends.  For example, adding properties to the 
> prototype object of a function.  Another issue is that the object you need to 
> extend may already have been captured somewhere.  For example, a 
> super.constructor call might have registered the object in a WeakMap and if 
> <& created a new instance you would loose the identify relationship.

Sure, I'm not saying word one against the mutating form -- just noting the 
symmetry break w.r.t. <| and suggesting a fix that builds on the assignment 
operator.


> In practice, I think most of the more declarative uses such as adding own 
> properties can be implemented (and perhaps even specified) such that no extra 
> objects need to be created.

Agreed.


> One thing that I think is still open is whether the RHS needs to be an 
> ObjectLiteral or whether any object producing expression should be allowed.  
> All the use cases  I have explored use an ObjectLiteral but I don't see any 
> hazard (like would be the case if <| mutated the LHS [[Prototype]]) with 
> allowing a non-literal value of the RHS.

Probably right; another symmetry break.

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Bob Nystrom
On Mon, Jul 18, 2011 at 10:32 AM, Allen Wirfs-Brock 
wrote:
> This is a nice declarative way to describe the per instance state but it
turns out it doesn't generalize very well to multiple levels of inheritance.

This is an important point. I think the reason most OOP languages make a
distinction between object construction and initialization is because in the
presence of inheritance, you need 1 construction, but N initializations
where N is the depth of your inheritance chain. If you try to construct and
initialize in one step, it's hard to do that (as your proposal addresses).

> A similar issue exists for the proposed class declarations.  That proposal
includes the concept of "static" (a lot of us don't like that the term
"static" in this context)  property declaration:

Yeah, I don't think anyone is crazy about that keyword, but it's:

1. Reserved already.
2. Familiar from other languages and it works about the same here as it does
in those.

I liked "class" instead, but the worry about nested classes was enough to
talk me out of it.

We have a challenge with JS keywords:

1. We want to re-use keywords from other languages to make JS familiar and
to use what's already in the programmer's head. If some JS construct looks
and acts similar to a construct in other popular languages, using the same
word for it is like instant knowledge.

2. We want to emphasize JS's unique features. JS is not Java (or C++, or C#,
or Smalltalk, or Ruby) and we run the risk of leading users down a false
path if we make JS look superficially too much like them. There's also a
strong cultural bias where JS = light, terse, expressive, fun and Java =
verbose, rigid, work. Borrowing keywords from Java makes people worry that
there's going to be a JavaScript khaki dress code. Personally, I think
that's much ado about nothing, but I can understand why people would worry
that the suits are going to show up and crash the party.

> Static properties are really just own properties of the constructor
object.  While sometimes useful, they occur relatively infrequently yet they
require a additional declaration form within class bodies.

I just did some quick hunting through a few classes in the Closure library.
Instance methods are definitely the most common kind of member there, but
static methods were used in every type I looked at. For example,
goog.ui.Component has a static mutable field, three "constants" which are
properties on the constructor, and a couple of static methods.
goog.ui.Tooltip has five members that would use "static" in the class
proposal.

> This complicates the conceptual model of a class declaration by allowing
intermingling of constructor and prototype property declaration.

There can also be confusion between what goes on the prototype and what goes
on the new instance.

> This also increase the potential for confusion about the meaning of "this"
 (and "super") within such static property declarations.

Good point. From a conceptual simplicity argument, I like the idea of having
different curly blocks for "stuff on the ctor" and "stuff on the proto".
Pragmatically, though, C++, Java, and C# all mix instance and non-instance
members together and people seem to get by without too much trouble.

Looking at your example:

  class Point  {
private __validate(x,y) { return typeof x == 'number' && typeof y =
'number'};
constructor(x,y) {
  if (!this.__validate(x,y)) throw "invalid";
  return this <& {
  private __x: x,
  private __y: y
  };
   }
  } <& {
 get origin() { new this(0,0); }
  };

A few things stand out for me:

1. Personal preference, but it's pretty punctuation heavy.
2. It seems strange that the instance methods are in the class block, and
the methods on the class itself aren't. That feels backwards.
3. Unless I've had it explained to me, there's no way I could figure out
what that code means even if I'm an expert in other programming languages.

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Allen Wirfs-Brock

On Jul 18, 2011, at 11:32 AM, Brendan Eich wrote:

> Hawt.
> 
> A bit rough in that LHS <& RHS mutates LHS, whereas LHS <| RHS is pure and 
> produces a new object (which could be optimized to mutate RHS, note well!). 
> Both <| and <& are operators, to support chaining. Would it be better for <& 
> to be pure as <| is, and make an assignment operator form, LHS <&= RHS, that 
> expands to LHS = LHS <& RHS?

One way to think about <& is as a more declarative and more concise alternative 
to Object.defineProperties. I think there are plenty of use causes for the 
mutating extends.  For example, adding properties to the prototype object of a 
function.  Another issue is that the object you need to extend may already have 
been captured somewhere.  For example, a super.constructor call might have 
registered the object in a WeakMap and if <& created a new instance you would 
loose the identify relationship.

In practice, I think most of the more declarative uses such as adding own 
properties can be implemented (and perhaps even specified) such that no extra 
objects need to be created.

One thing that I think is still open is whether the RHS needs to be an 
ObjectLiteral or whether any object producing expression should be allowed.  
All the use cases  I have explored use an ObjectLiteral but I don't see any 
hazard (like would be the case if <| mutated the LHS [[Prototype]]) with 
allowing a non-literal value of the RHS.

> 
> Anyway, if I have <& right, then:
> 
> class SkinnedMesh extends THREE.Mesh {
>  constructor(geometry, materials) {
>super(geometry, materials);
> 
>public identityMatrix = new THREE.Matrix4();
>public bones = [];
>public boneMatrices = [];
>...
>  }
> 
>  update(camera) {
>...
>super.update();
>  }
> }
> 
> from http://wiki.ecmascript.org/doku.php?id=harmony:classes would desugar to:
> 
> function SkinnedMesh(geometry, materials) {
>  return super(geometry, materials) <& {
>identityMatrix: new THREE.Matrix4(),
>bones: [],
>boneMatrices: [],
>...
>  };
> }
> 
> SkinnedMesh.prototype = THREE.Mesh.prototype <| {
>  update(camera) {
>...
>super.update();
>  }
> };

yes, plus you need a
   constructor: SkinnedMesh
in the object literal used to defined SkinnedMesh.prototype

> 
> Class-side inheritance could be done via
> 
> let SkinnedMesh = THREE.Mesh <| (function (geom, mats) { ... } <& { 
> classMethod() {...} });
> 
> This loses the hoisting of SkinnedMesh that the function declaration 
> desugaring gained "for free" -- another rough spot to smooth out.
> 
> There's still a usability argument for class syntax, certainly.

Perhaps, but a simpler class syntax is arguably a better class syntax and as I 
mentioned "static" properties are relatively rare.  If the class declaration is 
taking care of building both the class and instance side prototype chains then

class SkinnedMesh extends THREE.Mesh {
...
} <& {
classMethod() {...}
};

would take care of them without complicating the class declaration body.

> 
> Class syntax is also, for some folks, an attractive nuisance because of 
> single-inheritance OOP being oversold and very often the wrong paradigm. But 
> <& helps there too -- one can more conveniently make mixins (I must mean <&= 
> here, of course).
> 
> The last conflicting name wins, or so it seems from what you've written. The 
> compositional answer there is to seal properties you don't want anyone to 
> redefine by a conflicting extend operation. I'm assuming the internal method 
> used to update the LHS or populate the new copy of it is 
> [[DefineOwnProperty]], as with ES5 object literals, and not [[Put]].

   Exactly. Like I mentioned above, <& is I proposed it (your <&=) is 
essentially a syntactic shorthand for Object.defineProperties. 

Allen



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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread David Bruant
Le 18/07/2011 19:32, Allen Wirfs-Brock a écrit :
> I've recently been experimenting with coding both prototypal and class
> based object definitions using the various syntactic forms that are
> currently on the table.  Something has emerged from that which has
> surprised me.  I have never been a big fan of the "extend" method that
> is provided by a number of JavaScript frameworks. However, based upon
> my experiments I'm now think that something like extend solves several
> issues with the declarative object and class declarations that we have
> recently been discussing.
>
> Just in case there is anyone on this list who isn't familiar with
> extend, here is a quick explanation. In most frameworks that support
> it, "extend" is invoked something like this: 
>obj.extend(extensionObj)
> It copies the own properties of  extensionObj and makes corresponding
> own properties for obj.
Very recently, I have read jQuery source code of jQuery.extend and I
have been surprised to discover that actually not only own properties
are copied. See definition at [1] and the main for-in loop between lines
334 and 360. Do anyone has an idea of why it is like this?


> (...)
>
> So, why use an operator like <& instead of a method named "extend":
> 1)  A big reason is that frameworks already use the extend name and
> the exact semantics we would define for it are only to match the
> current semantics of these frameworks.  By not using that name we
> avoid compatibility issues.
> 2) A operator form such as <& avoids issue of method redefinition and
> can more easily added to existing syntactic forms such as function
> declarations.
> 3) It is conceptually natural a natural companion to <|.  It makes
> sense to learn about the two operators together (particularly with
> regard to object literals on the RHS).
4) It makes static analysis easier. I'm currently working on some
JavaScript analysis, trying to extract out the API of a JS library.
Plenty of cases are easy. However, jQuery, defines its API in literal
objects which "extend" jQuery (see [2], for instance) or
jQuery.prototype (jQuery.fn). Doing a static analysis which will be able
to figure this one out will be extremely hard at the very best and most
likely impossible at all (because it will require my static analysis to
understand jQuery.extend semantics, which sounds impossible to me for now)
Having some syntax for that will make the analysis I want to do not only
possible, but easy.

Having a standardized "extend" method would make the static analysis
possible with the extra burden of making sure it has not been overridden
which is impossible in some cases (think obj[var1 + var2] = 1;).

On a related note, as I said, I'm working on extracting a "JavaScript
API" out of a JS file. For that very purpose, I cannot think of
something more useful than a class syntax.
Overall, I am highly in favor of language constructs that make
Javascript more suitable for reliable and easy machine understandability
as it will allow to extract more useful information just based on the
source code.

> I think <& is a natural companion to <| and is in line with our goals
> to both enhancing object literals and providing a class declarations
> as alternative to stand-alone constructor functions.  It increases the
> expressiveness of object literals for declaratively defining
> prototypal object models and permits simplifications of the proposed
> class declaration form.
Indeed. I really like this proposal.

David

[1] https://github.com/jquery/jquery/blob/master/src/core.js#L304
[2] https://github.com/jquery/jquery/blob/master/src/core.js#L368
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Allen Wirfs-Brock

On Jul 18, 2011, at 11:29 AM, Sean Eagan wrote:

> It would also allow declarative non-integer own properties for arrays,
> and arbitrary own properties to regular expressions, numbers,
> booleans, and strings, though I can't think of any specific use cases
> for those off of the top of my head.

Yes, I should have mentioned at least the array case.

> 
> Also, how about |> as opposed to <&, since it is a dual to <| adding
> own rather than inherited properties?

I'd be a bit concerned about  some people getting confused about which 
direction of the "arrow" corresponds to each operation.  Might be particularly 
hard for people with dyslexia.  I have played around with some other 
possibilities, for example, +<| .

I like the nemonic value of having + or & as part of the operator symbol for 
"extend" but  unfortunately <+ can't be used.

Allen






> 
> On Mon, Jul 18, 2011 at 12:32 PM, Allen Wirfs-Brock
>  wrote:
>> I've recently been experimenting with coding both prototypal and class based
>> object definitions using the various syntactic forms that are currently on
>> the table.  Something has emerged from that which has surprised me.  I have
>> never been a big fan of the "extend" method that is provided by a number of
>> JavaScript frameworks. However, based upon my experiments I'm now think that
>> something like extend solves several issues with the declarative object and
>> class declarations that we have recently been discussing.
>> Just in case there is anyone on this list who isn't familiar with extend,
>> here is a quick explanation. In most frameworks that support it, "extend" is
>> invoked something like this:
>>obj.extend(extensionObj)
>> It copies the own properties of  extensionObj and makes corresponding own
>> properties for obj.  Exact details about which properties are copied,
>> various error conditions and even the name of the method varies among
>> frameworks.  It is generally has been used as an imperative supplement to
>> ECMASript's built-in prototype inheritance, for example to provide effects
>> similar to multiple inheritance.
>> The use cases that interests me are some what different then this current
>> common use.
>> But first, I'll cut to the chase. Here is a quick summary of what I'm going
>> to propose:
>> In addition to  <| we need another operator <& that is similar to the
>> "extend" method in various frameworks.  It replicates the own properties of
>> its RHS operation on its LHS operand.  It provides an easy declarative way
>> to describe the properties that need to be added to an already created
>> object. For example:
>> 
>> obj <& {
>>__constDataProp: x,
>>method(a) {return a+this._constDataProp},
>>get konst() {return this.__costDataProp}
>> };
>> 
>> adds three properties to obj.
>> 
>> So, on to the use cases that motivates this. In
>> https://mail.mozilla.org/pipermail/es-discuss/2011-July/015792.html  I used
>> an prototypal inheritance pattern in an example.  A slightly simplified
>> version of the example is:
>> 
>> const Point = {
>>  //private members
>>  __x: 0,
>>  __y: 0,
>>  __validate(x,y) { return typeof x == 'number' && typeof y = 'number'},
>>  //public members
>>  new(x,y) {
>>   if (!this.__validate(x,y)) throw "invalid";
>>   return this <| {
>>   __x: x,
>>   __y: y
>>  }
>>   };
>> }
>> 
>> In this pattern, the "new" method on a prototype object is used to create
>> instance of the corresponding object abstraction.  It does this by using the
>> <| operator to create the instance as an object whose [[Protoype]] is set to
>> the prototypal instance.  The object literal on the right of the <| lists
>> the per instance state of the new object.  In this case the properties named
>> "__x" and "__y".   This is a nice declarative way to describe the per
>> instance state but it turns out it doesn't generalize very well to multiple
>> levels of inheritance.  If you tried to use this pattern to create a three
>> dimensional point,  it would probably look something like:
>> 
>> const Point3D = Point <| {
>>  //private members
>>  __z: 0,
>>  //public members
>>  new(x,y,z) {
>>   if (!this.__validate(x,y) || typeof z != 'number') throw
>> "invalid";
>>   return this <| {
>>   __x: x,
>>   __y: y,
>>  __z: z
>>  }
>>   };
>> }
>> 
>> Note that the "new" method in Point3D had to essentially copy everything
>> that was in the "new" method of Point.  This isn't very good use of
>> inheritance. It also may not work if true private properties are used
>> instead of just a naming convention. What you would really like to do is to
>> let the implementation of "new" in Point do all the work that relates to x
>> and y and only have to include in Point3D code that relates to z. You might
>> be tempted to write it as:
>> 
>> const Point3D = Point <| {
>>   

Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Brendan Eich
Hawt.

A bit rough in that LHS <& RHS mutates LHS, whereas LHS <| RHS is pure and 
produces a new object (which could be optimized to mutate RHS, note well!). 
Both <| and <& are operators, to support chaining. Would it be better for <& to 
be pure as <| is, and make an assignment operator form, LHS <&= RHS, that 
expands to LHS = LHS <& RHS?

Anyway, if I have <& right, then:

class SkinnedMesh extends THREE.Mesh {
  constructor(geometry, materials) {
super(geometry, materials);
 
public identityMatrix = new THREE.Matrix4();
public bones = [];
public boneMatrices = [];
...
  }
 
  update(camera) {
...
super.update();
  }
}

from http://wiki.ecmascript.org/doku.php?id=harmony:classes would desugar to:

function SkinnedMesh(geometry, materials) {
  return super(geometry, materials) <& {
identityMatrix: new THREE.Matrix4(),
bones: [],
boneMatrices: [],
...
  };
}

SkinnedMesh.prototype = THREE.Mesh.prototype <| {
  update(camera) {
...
super.update();
  }
};

Class-side inheritance could be done via

let SkinnedMesh = THREE.Mesh <| (function (geom, mats) { ... } <& { 
classMethod() {...} });

This loses the hoisting of SkinnedMesh that the function declaration desugaring 
gained "for free" -- another rough spot to smooth out.

There's still a usability argument for class syntax, certainly.

Class syntax is also, for some folks, an attractive nuisance because of 
single-inheritance OOP being oversold and very often the wrong paradigm. But <& 
helps there too -- one can more conveniently make mixins (I must mean <&= here, 
of course).

The last conflicting name wins, or so it seems from what you've written. The 
compositional answer there is to seal properties you don't want anyone to 
redefine by a conflicting extend operation. I'm assuming the internal method 
used to update the LHS or populate the new copy of it is [[DefineOwnProperty]], 
as with ES5 object literals, and not [[Put]].

/be

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


Re: An "extend" operator is a natural companion to <|

2011-07-18 Thread Sean Eagan
It would also allow declarative non-integer own properties for arrays,
and arbitrary own properties to regular expressions, numbers,
booleans, and strings, though I can't think of any specific use cases
for those off of the top of my head.

Also, how about |> as opposed to <&, since it is a dual to <| adding
own rather than inherited properties?

On Mon, Jul 18, 2011 at 12:32 PM, Allen Wirfs-Brock
 wrote:
> I've recently been experimenting with coding both prototypal and class based
> object definitions using the various syntactic forms that are currently on
> the table.  Something has emerged from that which has surprised me.  I have
> never been a big fan of the "extend" method that is provided by a number of
> JavaScript frameworks. However, based upon my experiments I'm now think that
> something like extend solves several issues with the declarative object and
> class declarations that we have recently been discussing.
> Just in case there is anyone on this list who isn't familiar with extend,
> here is a quick explanation. In most frameworks that support it, "extend" is
> invoked something like this:
>    obj.extend(extensionObj)
> It copies the own properties of  extensionObj and makes corresponding own
> properties for obj.  Exact details about which properties are copied,
> various error conditions and even the name of the method varies among
> frameworks.  It is generally has been used as an imperative supplement to
> ECMASript's built-in prototype inheritance, for example to provide effects
> similar to multiple inheritance.
> The use cases that interests me are some what different then this current
> common use.
> But first, I'll cut to the chase. Here is a quick summary of what I'm going
> to propose:
> In addition to  <| we need another operator <& that is similar to the
> "extend" method in various frameworks.  It replicates the own properties of
> its RHS operation on its LHS operand.  It provides an easy declarative way
> to describe the properties that need to be added to an already created
> object. For example:
>
> obj <& {
>    __constDataProp: x,
>    method(a) {return a+this._constDataProp},
>    get konst() {return this.__costDataProp}
> };
>
> adds three properties to obj.
>
> So, on to the use cases that motivates this. In
> https://mail.mozilla.org/pipermail/es-discuss/2011-July/015792.html  I used
> an prototypal inheritance pattern in an example.  A slightly simplified
> version of the example is:
>
> const Point = {
>      //private members
>      __x: 0,
>      __y: 0,
>      __validate(x,y) { return typeof x == 'number' && typeof y = 'number'},
>      //public members
>      new(x,y) {
>           if (!this.__validate(x,y)) throw "invalid";
>           return this <| {
>                   __x: x,
>                   __y: y
>                  }
>       };
> }
>
> In this pattern, the "new" method on a prototype object is used to create
> instance of the corresponding object abstraction.  It does this by using the
> <| operator to create the instance as an object whose [[Protoype]] is set to
> the prototypal instance.  The object literal on the right of the <| lists
> the per instance state of the new object.  In this case the properties named
> "__x" and "__y".   This is a nice declarative way to describe the per
> instance state but it turns out it doesn't generalize very well to multiple
> levels of inheritance.  If you tried to use this pattern to create a three
> dimensional point,  it would probably look something like:
>
> const Point3D = Point <| {
>      //private members
>      __z: 0,
>      //public members
>      new(x,y,z) {
>           if (!this.__validate(x,y) || typeof z != 'number') throw
> "invalid";
>           return this <| {
>                   __x: x,
>                   __y: y,
>                  __z: z
>                  }
>       };
> }
>
> Note that the "new" method in Point3D had to essentially copy everything
> that was in the "new" method of Point.  This isn't very good use of
> inheritance. It also may not work if true private properties are used
> instead of just a naming convention. What you would really like to do is to
> let the implementation of "new" in Point do all the work that relates to x
> and y and only have to include in Point3D code that relates to z. You might
> be tempted to write it as:
>
> const Point3D = Point <| {
>      //private members
>      __z: 0,
>      //public members
>      new(x,y,z) {
>           if (typeof z != 'number') throw "invalid";
>           return super.new(x,y) <| {
>                  __z: z
>                  }
>       };
> }
>
> However, that wouldn't create what was probably intended. Instead of
> creating a single instance object that inherits from Point3D it creates two
> objects, the first one has Point3D as its [[Prototype]] and has own
> properties "__x" and "__y".  The second object has the first object as its
> [[Prototype]] and as "__z" as an own property.  If a Point4D was created
> followin