RE: super, methods, constructors Co.

2012-06-04 Thread Luke Hoban
  In fact, without |, are there any cases where super behaves correctly in 
 an object literal, other than making super calls to Object.prototype 
 functions?

 We haven't eliminated the ability to define object literals that inherit from 
 objects other than Object.prototype.  We have just changed the syntax for 
 specifying them from:
   proto | {}
 to
{__proto__: proto}

Good point.  Object literals with inline __proto__ declarations do provide 
method contexts where super will behave correctly. But I think it's fair to 
assume that most object literals will not include inline __proto__ 
declarations.  

 In general, if you have multiple level instance based inheritance 
 hierarchies, super has the same general utility that it has in an a 
 class/instance based inheritance hierarchy. 

But only if that multi-level instance hierarchy is created in a very specific 
(and arguably uncommon) way.  That's my concern.  We happen to be discussing 
adding a new syntactic construct for classes, and can make sure that 'super' 
always works inside classes.  But we can't make 'super' always work inside 
object literals.  

 
 Take Backbone/Underscore as an example.  A developer writes some code like:
 
 var Note = Backbone.Model.extend({
set: function(attributes, options) {
super.set(attributes, options);
}
 });

 Of course, the above is a case where I suggest a mustache should probably be 
 used.  

Although it isn't obvious from the code I shared, this is actually creating a 
new object which has Backbone.Model in its prototype chain, and putting a set 
method in the new instance.  So mustache doesn't easily integrate into the 
syntax here.  One would need to change the API model non-trivially, and the 
consumption syntax somewhat significantly, to use mustache here.

 If extend did not explicitly deal with rebinding super referencing methods 
 (which it can't, if we eliminate defineMethod) then the set method would 
 throw when it tried to invoke the super.set.  So, the code fails with an 
 exception rather than silently working incorrectly.

That is at least better - but late errors trying to use a 1st class piece of 
syntax in a seemingly meaningful location feels concerning.

 Also, a very similar issue will apply to if the argument to extend had any 
 private name properties.  So this isn't a problem that is specific to super. 
 I can actually envision how it may be easier for a built-in extend function 
 to handle super rebinding than it would be for it to handle private names.  I 
 don't currently see how a non-built-in Es=5 semantics based extend could 
 handle it.

That's a good point, and does lead me to be concerned about the behaviour of 
ES3-style extend on private names as well.  For similar reasons, I expect devs 
will just assume this sort of thing works.

 The issue of passing new semantic constructors into legacy frameworks is 
 certainly worth thinking about.  Although, i tend to think that actively 
 maintain frameworks will get ahead of the ES6 adoption curve.  And that 
 legacy using a out of date framework is much less likely to start using new 
 ES6 constructs.

This seems optimistic, but possible.  More importantly though, do we know how 
these libraries would address this sort of thing?  And what the transition 
would look like (can they do it in a library-only way such that they can 
feature detect to work correctly with new ES6 constructs, but still work in 
pre-ES6 environments)?

  Of course, the above doesn't even work for ES5 since it it ignores 
 non-enumerable properties, doesn't copy accessor properties correctly, and 
 probably unintentionally includes inherited properties. We should be cherry 
 picking super as the only feature that is problematic for such code.
 One might speculate if these deficiencies aren't causing problems today, then 
 perhaps the issue of passing new language constructs into to legacy 
 frameworks that don't correctly deal with them is not a significant problem.

Good point.  Though one might also speculate that none of the ES5 features 
mentioned have seen enough adoption on the web yet to understand the full 
impact of these problems.

But I think a difference that makes me more concerned about super is that this 
is something these APIs are trying to do already today.  The backbone.js docs 
[1] that I took this example from explicitly call out __Brief aside on super: 
JavaScript does not provide a simple way to call super — the function of the 
same name defined higher on the prototype chain. If you override a core 
function like set, or save, and you want to invoke the parent object's 
implementation, you'll have to explicitly call it...__.  It gets a bit more 
subtle to say JavaScript has a way to call super, but it won't work here.   

 Here is another way to think about this class of issues. super is a language 
 feature that is design to work at the level of the built-in behavior 
 composition mechanism of ES (a fixed single 

Re: super, methods, constructors Co.

2012-06-04 Thread Herby Vojčík



Luke Hoban wrote:

In fact, without|, are there any cases where super behaves
correctly in an object literal, other than making super calls to
Object.prototype functions?



We haven't eliminated the ability to define object literals that
inherit from objects other than Object.prototype.  We have just
changed the syntax for specifying them from: proto| {} to
{__proto__: proto}


Good point.  Object literals with inline __proto__ declarations do
provide method contexts where super will behave correctly. But I
think it's fair to assume that most object literals will not include
inline __proto__ declarations.


In general, if you have multiple level instance based inheritance
hierarchies, super has the same general utility that it has in an a
class/instance based inheritance hierarchy.


But only if that multi-level instance hierarchy is created in a very
specific (and arguably uncommon) way.  That's my concern.  We happen
to be discussing adding a new syntactic construct for classes, and
can make sure that 'super' always works inside classes.  But we can't
make 'super' always work inside object literals.


Take Backbone/Underscore as an example.  A developer writes some
code like:

var Note = Backbone.Model.extend({
set: function(attributes, options) {
super.set(attributes, options);
}
});



Of course, the above is a case where I suggest a mustache should
probably be used.


Although it isn't obvious from the code I shared, this is actually
creating a new object which has Backbone.Model in its prototype
chain, and putting a set method in the new instance.  So mustache
doesn't easily integrate into the syntax here.  One would need to
change the API model non-trivially, and the consumption syntax
somewhat significantly, to use mustache here.


In that case, it is the place for {__proto__: Backbone.Model, set: ...} 
or similar construct, where super is highly usable.



The issue of passing new semantic constructors into legacy
frameworks is certainly worth thinking about.  Although, i tend to
think that actively maintain frameworks will get ahead of the ES6
adoption curve.  And that legacy using a out of date framework is
much less likely to start using new ES6 constructs.


This seems optimistic, but possible.  More importantly though, do we
know how these libraries would address this sort of thing?  And what
the transition would look like (can they do it in a library-only way
such that they can feature detect to work correctly with new ES6
constructs, but still work in pre-ES6 environments)?


Of course, the above doesn't even work for ES5 since it it ignores
non-enumerable properties, doesn't copy accessor properties
correctly, and probably unintentionally includes inherited
properties. We should be cherry picking super as the only feature
that is problematic for such code. One might speculate if these
deficiencies aren't causing problems today, then perhaps the issue
of passing new language constructs into to legacy frameworks that
don't correctly deal with them is not a significant problem.


Good point.  Though one might also speculate that none of the ES5
features mentioned have seen enough adoption on the web yet to
understand the full impact of these problems.

But I think a difference that makes me more concerned about super is
that this is something these APIs are trying to do already today.
The backbone.js docs [1] that I took this example from explicitly
call out __Brief aside on super: JavaScript does not provide a
simple way to call super — the function of the same name defined
higher on the prototype chain. If you override a core function like
set, or save, and you want to invoke the parent object's
implementation, you'll have to explicitly call it...__.  It gets a
bit more subtle to say JavaScript has a way to call super, but it
won't work here.


And what is your concern here? super now allows to do it right (if you 
don't define a method bad way - in fact Object.defineMethod is needed 
for programmatic definition of a method from a variable). Libraries can 
begin to use it.



Here is another way to think about this class of issues. super is a
language feature that is design to work at the level of the
built-in behavior composition mechanism of ES (a fixed single
inheritance [[Prototype]] chain).  _extend and other abstraction
impose a different behavioral composition model.  super may not
work as expected with those other models unless their
implementation takes it input account in their implementation.


That's a fair summary.  In practice though, a lot of object models in
JavaScript are built using these higher-level abstractions built on
top of the core JS prototype chain.  Mostly, features at the core
language level continue to be usable via these higher level
abstractions.  It's concerning to add core language features that
can't (or can't sufficiently easily) be used by the common
abstractions.


The question may be also, if those abstractions (which were filling 

Re: super, methods, constructors Co.

2012-06-01 Thread Allen Wirfs-Brock

On May 31, 2012, at 10:57 PM, Luke Hoban wrote:

 On May 31, 2012, at 1:54 PM, Allen Wirfs-Brock wrote:
 
 On May 31, 2012, at 1:53 AM, Herby Vojčík wrote:
 
 Hello,
 
 reacting to super only in classes, I'd like to propose widening it just a 
 little bit:
 
 1. Allow super in every concise methods (in classes, as well as out of 
 them).
 
 Basically this means in object literals (or object extension literals if we 
 have them)
 
 It still seems to me that the majority of the time, super used in an object 
 literal will not actually behave correctly.  My pushback on a general notion 
 of super outside of classes is based on the assumption that it will be a 
 misleading feature, suggesting support for super calls in many places there 
 actually is not.  
 
 In fact, without |, are there any cases where super behaves correctly in an 
 object literal, other than making super calls to Object.prototype functions?

We haven't eliminated the ability to define object literals that inherit from 
objects other than Object.prototype.  We have just changed the syntax for 
specifying them from:
   proto | {}
to
   {__proto__: proto}

In general, if you have multiple level instance based inheritance hierarchies, 
super has the same general utility that it has in an a class/instance based 
inheritance hierarchy. 

 
 Take Backbone/Underscore as an example.  A developer writes some code like:
 
 var Note = Backbone.Model.extend({
set: function(attributes, options) {
super.set(attributes, options);
}
 });

Of course, the above is a case where I suggest a mustache should probably be 
used.  If extend did not explicitly deal with rebinding super referencing 
methods (which it can't, if we eliminate defineMethod) then the set method 
would throw when it tried to invoke the super.set.  So, the code fails with an 
exception rather than silently working incorrectly.

Also, a very similar issue will apply to if the argument to extend had any 
private name properties.  So this isn't a problem that is specific to super. I 
can actually envision how it may be easier for a built-in extend function to 
handle super rebinding than it would be for it to handle private names.  I 
don't currently see how a non-built-in Es=5 semantics based extend could 
handle it.

The issue of passing new semantic constructors into legacy frameworks is 
certainly worth thinking about.  Although, i tend to think that actively 
maintain frameworks will get ahead of the ES6 adoption curve.  And that legacy 
using a out of date framework is much less likely to start using new ES6 
constructs.

 
 They rightly think they can use a super call inside an object literal.   But 
 it doesn't behave correctly, because extend is ultimately (somewhere in code 
 that the end-developer shouldn't really need to be aware of) implemented in 
 just the simple ES3-compatible way:
 
  _.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
  for (var prop in source) {
obj[prop] = source[prop];
  }
});
return obj;
  };
 

Of course, the above doesn't even work for ES5 since it it ignores 
non-enumerable properties, doesn't copy accessor properties correctly, and 
probably unintentionally includes inherited properties. We should be cherry 
picking super as the only feature that is problematic for such code.

One might speculate if these deficiencies aren't causing problems today, then 
perhaps the issue of passing new language constructs into to legacy frameworks 
that don't correctly deal with them is not a significant problem.

 As I understand it, super will not work correctly in cases like these unless 
 the authors of every object model library opt in to taking an ES6 dependency 
 on Object.defineMethod, or fork their implementations to detect and behave 
 differently on ES6.  I believe the necessary change to these APIs is intended 
 to be something like this - but I'm pretty sure this also wouldn't be 
 correct, because it rebinds the super bindings of functions which may have 
 been correctly bound previously to other points in the prototype hierarchy. 
 
  _.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
  for (var prop in source) {
if(typeof prop === 'function') {
  Object.defineMethod(obj, prop, source[prop]);
} else {
  obj[prop] = source[prop];
}
  }
});
return obj;
  };\
Basically, except I would only want to rebind the function if the current 
function is bound to the object it is being extracted from.
 
 Basically - I just don't see that this feature can be made to feel like it 
 just works, in a practical sense, outside of classes.

But also note that class instance or class prototype objects can be used in all 
the same situations where you have used object literals.  Nothing here is 
unique about their occurrence in object literals.  

Here is another way to think about this class of issues. super is a 

RE: super, methods, constructors Co.

2012-06-01 Thread Domenic Denicola
 -Original Message-
 From: es-discuss-boun...@mozilla.org [mailto:es-discuss-
 boun...@mozilla.org] On Behalf Of Allen Wirfs-Brock
 Sent: Friday, June 01, 2012 04:05


 We haven't eliminated the ability to define object literals that inherit
 from objects other than Object.prototype.  We have just changed the
 syntax for specifying them from:
proto | {}
 to
{__proto__: proto}

For anyone who (like me) was confused by this in light of all the talk that 
colons in object literals always do a [[DefineOwnProperty]], there is an 
exemption made for __proto__ in section B.3.1.3 of the latest spec.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: super, methods, constructors Co.

2012-06-01 Thread Oliver Hunt

On Jun 1, 2012, at 8:30 AM, Domenic Denicola wrote:

 -Original Message-
 From: es-discuss-boun...@mozilla.org [mailto:es-discuss-
 boun...@mozilla.org] On Behalf Of Allen Wirfs-Brock
 Sent: Friday, June 01, 2012 04:05
 
 
 We haven't eliminated the ability to define object literals that inherit
 from objects other than Object.prototype.  We have just changed the
 syntax for specifying them from:
  proto | {}
 to
  {__proto__: proto}
 
 For anyone who (like me) was confused by this in light of all the talk that 
 colons in object literals always do a [[DefineOwnProperty]], there is an 
 exemption made for __proto__ in section B.3.1.3 of the latest spec.

That exception is required as the spec placed __proto__ on the Object 
prototype, and existing content requires {__proto__: ...} to set the prototype. 
 JSC didn't have this problem in the past as __proto__ was a magical property 
that all objects had and shared with all the world.  This made Mark sad :-(

For the record, I agree with Luke that super, etc shouldn't be allowed outside 
of actual class definitions.  The semantics become confusing, and the 
implementation complexity of super goes up even for super used in a class.

Also, I won't be around on email for the next week or so as I'm helping out on 
the ALC (if you feel like sponsoring here's a url: 
http://www.tofighthiv.org/site/TR/AIDSLIFECYCLE11/AIDSLifeCycleCenter?px=2583919pg=personalfr_id=1440)

--Oliver

 ___
 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: super, methods, constructors Co.

2012-06-01 Thread David Herman
On Jun 1, 2012, at 10:10 AM, Oliver Hunt wrote:

 Also, I won't be around on email for the next week or so as I'm helping out 
 on the ALC (if you feel like sponsoring here's a url: 
 http://www.tofighthiv.org/site/TR/AIDSLIFECYCLE11/AIDSLifeCycleCenter?px=2583919pg=personalfr_id=1440)

Go Ollie! I encourage everyone who feels they can to contribute to Ollie's 
ride. It's a great cause and a pretty amazing show of dedication (a week-long 
bicycle ride from SF to LA).

Now back to your regularly scheduled JS conversation...

Dave

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


Re: super, methods, constructors Co.

2012-05-31 Thread Allen Wirfs-Brock
(private reply)

On May 31, 2012, at 1:53 AM, Herby Vojčík wrote:
 
 P.S.: It was told that there are some problems with super -- what are they?

I think the problem is that  some committee members just don't understand the 
normal OO semantics of super and how it is used in OO inheritance. In some 
cases, they are dubious of inheritance in general.  This makes them 
uncomfortable with having it at all.

It is those road blocks that we need to navigate.

Allen

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


Re: super, methods, constructors Co.

2012-05-31 Thread Allen Wirfs-Brock
well this is embarrassing...

I stand by my perception, but it isn't something I would normally share in a 
public list.

I apologize if anybody is offended.

Allen




On May 31, 2012, at 11:07 AM, Allen Wirfs-Brock wrote:

 (private reply)
 
 On May 31, 2012, at 1:53 AM, Herby Vojčík wrote:
 
 P.S.: It was told that there are some problems with super -- what are they?
 
 I think the problem is that  some committee members just don't understand the 
 normal OO semantics of super and how it is used in OO inheritance. In some 
 cases, they are dubious of inheritance in general.  This makes them 
 uncomfortable with having it at all.
 
 It is those road blocks that we need to navigate.
 
 Allen
 
 ___
 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: super, methods, constructors Co.

2012-05-31 Thread Luke Hoban
On May 31, 2012, at 1:54 PM, Allen Wirfs-Brock wrote:

 On May 31, 2012, at 1:53 AM, Herby Vojčík wrote:

 Hello,
 
 reacting to super only in classes, I'd like to propose widening it just a 
 little bit:
 
 1. Allow super in every concise methods (in classes, as well as out of them).

 Basically this means in object literals (or object extension literals if we 
 have them)

It still seems to me that the majority of the time, super used in an object 
literal will not actually behave correctly.  My pushback on a general notion of 
super outside of classes is based on the assumption that it will be a 
misleading feature, suggesting support for super calls in many places there 
actually is not.  

In fact, without |, are there any cases where super behaves correctly in an 
object literal, other than making super calls to Object.prototype functions?

Take Backbone/Underscore as an example.  A developer writes some code like:

var Note = Backbone.Model.extend({
set: function(attributes, options) {
super.set(attributes, options);
}
});

They rightly think they can use a super call inside an object literal.   But it 
doesn't behave correctly, because extend is ultimately (somewhere in code that 
the end-developer shouldn't really need to be aware of) implemented in just the 
simple ES3-compatible way:

  _.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
  for (var prop in source) {
obj[prop] = source[prop];
  }
});
return obj;
  };

As I understand it, super will not work correctly in cases like these unless 
the authors of every object model library opt in to taking an ES6 dependency on 
Object.defineMethod, or fork their implementations to detect and behave 
differently on ES6.  I believe the necessary change to these APIs is intended 
to be something like this - but I'm pretty sure this also wouldn't be correct, 
because it rebinds the super bindings of functions which may have been 
correctly bound previously to other points in the prototype hierarchy. 

  _.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
  for (var prop in source) {
if(typeof prop === 'function') {
  Object.defineMethod(obj, prop, source[prop]);
} else {
  obj[prop] = source[prop];
}
  }
});
return obj;
  };

Basically - I just don't see that this feature can be made to feel like it 
just works, in a practical sense, outside of classes.

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