Re: getter and setter inheritance

2008-05-12 Thread P T Withington
On 2008-05-09, at 12:46 EDT, Lars Hansen wrote:

 (One bike ride and one cup of coffee later.)

 Clearly there is a difference between class/interface inheritance on  
 the
 one hand and prototype inheritance on the other.

 In either case I think the introduction of a setter and/or a getter  
 in a
 context introduces definitions for both in that context, essentially a
 special property that holds a getter/setter pair.  A missing
 getter/setter is generated (that's what ES4 specifies now.)  That  
 means
 that in prototype contexts, if an object has a getter or a setter  
 for a
 field, the prototype will never be searched for the missing half.   
 In a
 class context, getters and setters can be overridden because the class
 instance only has the one special property with the getter/setter  
 pair,
 and the values in that property depend on the class that the  
 instance is
 an instance of.  So different classes have different pairs.

(I've only been to spin class, but I've had 1 coffee and 2 teas.)

When A missing getter/setter is generated, what is its  
functionality?  Does it just error?

Can I call a super getter/setter method (I hope)?  What is the syntax  
for that?

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


RE: getter and setter inheritance

2008-05-12 Thread Lars Hansen
The generated getter and setter ought to have roughly the same
behavior as the getting and setting behavior for a property on
the class.

The behavior for reading and writing properties is this, IIRC:

If the class is compiled in standard mode, then reads from nonexistent
properties return undefined.  Writes to nonexistent properties
on non-dynamic classes fail silently, whereas writes to nonexistent
properties on dynamic classes create those properties.

If the class is compiled in strict mode, then reads from nonexistent
properties on non-dynamic classes throw an exception (no such property);
reads from nonexistent properties on dynamic classes return undefined.
Writes to nonexistent properties on non-dynamic classes throw an
exception (no such property), whereas writes to nonexistent properties
on dynamic classes create those properties.

For generated getters and setters (in classes at least), it seems
that matching that behavior, except for property creation, is
roughly right.  I'd say that the write ought to be silently ignored
on non-strict classes and that an error should be thrown on strict
classes.

And yes, it ought to be possible to invoke the superclass getter,
the syntax is as for accessing a property on a superclass,
super.p for the immediate base class or super(C).p for classes
higher up the inheritance chain.

--lars

 -Original Message-
 From: P T Withington [mailto:[EMAIL PROTECTED] On Behalf Of 
 P T Withington
 Sent: 12. mai 2008 07:59
 To: Lars Hansen
 Cc: Kris Zyp; [EMAIL PROTECTED]; es4-discuss Discuss
 Subject: Re: getter and setter inheritance
 
 On 2008-05-09, at 12:46 EDT, Lars Hansen wrote:
 
  (One bike ride and one cup of coffee later.)
 
  Clearly there is a difference between class/interface 
 inheritance on 
  the one hand and prototype inheritance on the other.
 
  In either case I think the introduction of a setter and/or 
 a getter in 
  a context introduces definitions for both in that context, 
 essentially 
  a special property that holds a getter/setter pair.  A missing 
  getter/setter is generated (that's what ES4 specifies now.)  That 
  means that in prototype contexts, if an object has a getter or a 
  setter for a
  field, the prototype will never be searched for the missing half.   
  In a
  class context, getters and setters can be overridden 
 because the class 
  instance only has the one special property with the getter/setter 
  pair, and the values in that property depend on the class that the 
  instance is an instance of.  So different classes have different 
  pairs.
 
 (I've only been to spin class, but I've had 1 coffee and 2 teas.)
 
 When A missing getter/setter is generated, what is its 
 functionality?  Does it just error?
 
 Can I call a super getter/setter method (I hope)?  What is 
 the syntax for that?
 
 
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: getter and setter inheritance

2008-05-12 Thread Erik Arvidsson
How does super lookups and calls work for getters and setters in ES3.1
and ES4? It seems like the following scheme should work.

Given the following code in ES4:

class A {
  function get x() {
...
  }
  function set x(value) {
...
  }
}

class B extends A {
  private let _x = 0;
  function get x() {
return super.x;
  }
  function set x(value) {
_x = value;
super.x = value;
  }
}

In JS1.7 I think the following works

function A() {
  ...
}
A.prototype.__defineGetter__('x', ...);
A.prototype.__defineSetter__('x', ...);

function B() {
  A.call(this);
}
B.prototype = new A; // Or use helper to prevent calling A's
constructor while setting up the prototype object

B.prototype._x = 0;

B.prototype.__defineGetter__('x', function() {
  var aGetter = A.prototype.__lookupGetter__('x);
  return aGetter.call(this);
};

B.prototype.__defineSetter__('x', function(value) {
  this.x_ = value;
  var aSetter = A.prototype.__lookupSetter__('x);
  aSetter.call(this, value);
};

Would ES3.1 work by simply replacing __lookup(G|S)etter__ by Object.getProperty?

-- 
erik

On Mon, May 12, 2008 at 08:52, Lars Hansen [EMAIL PROTECTED] wrote:
 The generated getter and setter ought to have roughly the same
  behavior as the getting and setting behavior for a property on
  the class.

  The behavior for reading and writing properties is this, IIRC:

  If the class is compiled in standard mode, then reads from nonexistent
  properties return undefined.  Writes to nonexistent properties
  on non-dynamic classes fail silently, whereas writes to nonexistent
  properties on dynamic classes create those properties.

  If the class is compiled in strict mode, then reads from nonexistent
  properties on non-dynamic classes throw an exception (no such property);
  reads from nonexistent properties on dynamic classes return undefined.
  Writes to nonexistent properties on non-dynamic classes throw an
  exception (no such property), whereas writes to nonexistent properties
  on dynamic classes create those properties.

  For generated getters and setters (in classes at least), it seems
  that matching that behavior, except for property creation, is
  roughly right.  I'd say that the write ought to be silently ignored
  on non-strict classes and that an error should be thrown on strict
  classes.

  And yes, it ought to be possible to invoke the superclass getter,
  the syntax is as for accessing a property on a superclass,
  super.p for the immediate base class or super(C).p for classes
  higher up the inheritance chain.

  --lars


   -Original Message-
   From: P T Withington [mailto:[EMAIL PROTECTED] On Behalf Of
   P T Withington
   Sent: 12. mai 2008 07:59
   To: Lars Hansen
   Cc: Kris Zyp; [EMAIL PROTECTED]; es4-discuss Discuss
   Subject: Re: getter and setter inheritance
  


  On 2008-05-09, at 12:46 EDT, Lars Hansen wrote:
  
(One bike ride and one cup of coffee later.)
   
Clearly there is a difference between class/interface
   inheritance on
the one hand and prototype inheritance on the other.
   
In either case I think the introduction of a setter and/or
   a getter in
a context introduces definitions for both in that context,
   essentially
a special property that holds a getter/setter pair.  A missing
getter/setter is generated (that's what ES4 specifies now.)  That
means that in prototype contexts, if an object has a getter or a
setter for a
field, the prototype will never be searched for the missing half.
In a
class context, getters and setters can be overridden
   because the class
instance only has the one special property with the getter/setter
pair, and the values in that property depend on the class that the
instance is an instance of.  So different classes have different
pairs.
  
   (I've only been to spin class, but I've had 1 coffee and 2 teas.)
  
   When A missing getter/setter is generated, what is its
   functionality?  Does it just error?
  
   Can I call a super getter/setter method (I hope)?  What is
   the syntax for that?
  
  
  ___
  Es3.x-discuss mailing list
  [EMAIL PROTECTED]
  https://mail.mozilla.org/listinfo/es3.x-discuss
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: getter and setter inheritance

2008-05-12 Thread Mark S. Miller
On Mon, May 12, 2008 at 10:10 AM, Erik Arvidsson
[EMAIL PROTECTED] wrote:
 Would ES3.1 work by simply replacing __lookup(G|S)etter__ by 
 Object.getProperty?

Yes, I think so.

 B.prototype.__defineGetter__('x', function() {
  var aGetter = A.prototype.__lookupGetter__('x);
  ...

Object.defineProperties(B.prototype, {x: {
  getter: function() {
var aGetter = Object.getProperty(A.prototype, 'x').getter;
...

-- 
Cheers,
--MarkM
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: getter and setter inheritance

2008-05-11 Thread Kris Zyp
When an object A is defined that inherits from it's prototype object B that 
has a getter and setter defined for foo, and object A wants to inherit the 
behavior of B except for a slight modification to the getter behavior, it 
could be advantageous if the setter could still be inherited without having 
to redefine it on object A. If the developer wants to make property foo 
read-only, this can still easily be done by creating a setter that throws an 
exception (or does nothing).
That being said, I would still favor the approach of treating 
getters/setters as a full slot, where inheritance doesn't go past 
half-definitions because that is behavior that is currently used on the web 
today.

Also, the idea of making setters without getters illegal is interesting. 
However, while they may be rare, I think setters without getters has use 
cases. This seems like unnecessary arbitrary restriction to dissallow 
setters without getters. Furthermore, this is not the behavior of current 
browsers, there is no precedent in JavaScript implementations for preventing 
this combination. Is there other reasons for this restriction that I am not 
aware of?

Thanks,
Kris


- Original Message - 
From: Mark S. Miller [EMAIL PROTECTED]
To: Kris Zyp [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]; es4-discuss Discuss 
es4-discuss@mozilla.org
Sent: Sunday, May 11, 2008 10:23 AM
Subject: Re: getter and setter inheritance


 2008/5/9 Kris Zyp [EMAIL PROTECTED]:
 A question of how inheritance/delegation should work with getters and
 setters was raised in a recent discussion.


 Hi Kris,

 The way I've been thinking of getters and setters is as if there are
 two kinds of properties:

 * A data property is defined by its current value, and whether the
 value is writable. If the value is not writable, the property is
 considered read-only.

 * A procedural property is defined by a getter function and an
 optional setter function. If there is no setter function, the property
 is considered read-only.

 For both kinds of properties, a property is further defined by its
 property name, whether the property is enumerable, and whether the
 property's definition is redefinable. (Where redefinable implies
 deletable.) This would be reflected (so to speak) concretely in the
 results of Object.getProperties and Object.getProperty, and in the
 argument of Object.defineProperties.

  Object.getProperty(x, 'foo') = {value: 3, writable: false,
 enumerable: false, redefinable: false}
  Object.getProperty(x, 'bar') = {getter: function(){return 3;},
 enumerable: false, redefinable: false}

 in which case x.foo and x.bar are behaviorally identical for
 non-reflective clients.


 If there is an object A whose
 prototype is object B, and object A defines a getter for property foo, 
 and
 object B defines a setter for property foo, and we write a value to 
 A.foo,
 should the setter defined on object B be called?

 I think it should be illegal to define a setter without defining a
 getter. A procedural property should either have a getter or have a
 getter and a setter.

 Assuming B defines a getter and a setter for foo, and A defines a
 getter for foo, the answer should be no. A's own foo is a read-only
 procedural property that fully masks B's foo.


 If A didn't define any
 property on A, the setter would be inherited from B and would be called 
 when
 A.foo was modified.

 Yes.

 However, with the getter defined on A, should the
 inheritance stop at A, because there is a slot defined, or should it
 continue along the prototype chain because there was no setter defined 
 for
 that property (nor plain value)?

 Stop at A. s/slot/property


 The question also applies when the getter
 and setter are reversed. When a property is accessed and there is a 
 setter
 defined, but no getter,

 That case should be rejected as illegal.


 should we continue to down the prototype chain to
 find a getter or a plain value, or stop and return undefined? AFAICT, ES4
 doesn't explicitly define which is the correct behavior. Firefox follows 
 the
 former behavior:

 B={set foo(v){foo = v},
 get bar(){return bar value}}

 B.foo should be rejected as illegal.

 A={get foo(){return foo value},
 set bar(v){bar = v},
 __proto__:B}

 A.bar should be rejected as illegal.


 -- 
Cheers,
--MarkM

 

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


Re: getter and setter inheritance

2008-05-11 Thread Mark S. Miller
On Sun, May 11, 2008 at 4:40 PM, Kris Zyp [EMAIL PROTECTED] wrote:
 [...] That being said, I would still favor the approach of treating
 getters/setters as a full slot, where inheritance doesn't go past
 half-definitions because that is behavior that is currently used on the web
 today.

Great!

 Also, the idea of making setters without getters illegal is interesting.
 However, while they may be rare, I think setters without getters has use
 cases. This seems like unnecessary arbitrary restriction to dissallow
 setters without getters. Furthermore, this is not the behavior of current
 browsers, there is no precedent in JavaScript implementations for preventing
 this combination. Is there other reasons for this restriction that I am not
 aware of?

Not really. I can live with write-only procedural properties. I don't
think it changes any of the other points.

When reading a write-only property, i.e., a procedural property with a
setter and no getter, one reads undefined, even in strict mode. Right?
So an absent getter is always equivalent to a getter of
function(){return undefined;}?

-- 
Cheers,
--MarkM
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


getter and setter inheritance

2008-05-09 Thread Kris Zyp
A question of how inheritance/delegation should work with getters and setters 
was raised in a recent discussion. If there is an object A whose prototype is 
object B, and object A defines a getter for property foo, and object B defines 
a setter for property foo, and we write a value to A.foo, should the setter 
defined on object B be called? If A didn't define any property on A, the setter 
would be inherited from B and would be called when A.foo was modified. However, 
with the getter defined on A, should the inheritance stop at A, because there 
is a slot defined, or should it continue along the prototype chain because 
there was no setter defined for that property (nor plain value)? The question 
also applies when the getter and setter are reversed. When a property is 
accessed and there is a setter defined, but no getter, should we continue to 
down the prototype chain to find a getter or a plain value, or stop and return 
undefined? AFAICT, ES4 doesn't explicitly define which is the correct behavior. 
Firefox follows the former behavior:

B={set foo(v){foo = v},
get bar(){return bar value}}
A={get foo(){return foo value},
set bar(v){bar = v},
__proto__:B}

A.bar - undefined
A.foo = 'new value' - setter is not called, foo is not set

Thanks,
Kris___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


Re: getter and setter inheritance

2008-05-09 Thread liorean
2008/5/9 Lars Hansen [EMAIL PROTECTED]:
 My view is that getters and setters introduce properties and that whatever we 
 do should be appropriate to that model.

That is pretty much my view as well. Just a couple of questions that
might need addressing, if it hasn't been dealt with already:
- Can you have a property together with a getter and/or a setter?
- If so:
  * Is there any way to reach that property from inside the
getter/setter without ending up recurring into the getter/setter?
  * Can a setter modify the property if there is a property but no getter?
  * Can a getter read the property if there is a property but no setter?


 Others seem to think that getters and setters introduce a way of invoking
 normal methods by a different syntax and that they are truly just methods.
 In the world of classes and instances that may be appropriate, but not in
 the object-and-property world of ES3, I expect.

Or one could consider an ES3 property as a getter/setter pair, if one wished.

-- 
David liorean Andersson
___
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss


RE: getter and setter inheritance

2008-05-09 Thread Lars Hansen
(One bike ride and one cup of coffee later.)
 
Clearly there is a difference between class/interface inheritance on the
one hand and prototype inheritance on the other.
 
In either case I think the introduction of a setter and/or a getter in a
context introduces definitions for both in that context, essentially a
special property that holds a getter/setter pair.  A missing
getter/setter is generated (that's what ES4 specifies now.)  That means
that in prototype contexts, if an object has a getter or a setter for a
field, the prototype will never be searched for the missing half.  In a
class context, getters and setters can be overridden because the class
instance only has the one special property with the getter/setter pair,
and the values in that property depend on the class that the instance is
an instance of.  So different classes have different pairs.
 
There's no particular problem with interfaces holding getter and setter
declarations, they are just constraints on the contents of the
implementing class -- the class must have a matching getter or setter
definition (possibly inherited from base class).  That said, getters and
setters in interfaces feels pretty lame, because what they're doing is
basically requiring a particular *implementation* of a property.  A
good interface would require there to be a property x with a
particular type, but not worry about whether it was introduced by var,
let, const, or implemented as a getter/setter.  So, using var to
stand for all of those possibilities:
 
  interface ArrayLike.T {
var length: double;
meta function get(n):T;
meta function set(n,v:T);
  }
 
In practice most types implementing ArrayLike would use a getter/setter
pair for the length field, but why should the type worry about that?
 
--lars




From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Lars Hansen
Sent: 9. mai 2008 08:41
To: Kris Zyp; [EMAIL PROTECTED]; es4-discuss Discuss
Subject: RE: getter and setter inheritance


Very timely questions.  I've been worrying about similar things
this week (more in the context of the ES4 type system) and not yet
reached any conclusions.
 
My view is that getters and setters introduce properties and
that whatever we do should be appropriate to that model.
 
Others seem to think that getters and setters introduce a way of
invoking normal methods by a different syntax and that they are truly
just methods.  In the world of classes and instances that may be
appropriate, but not in the object-and-property world of ES3, I expect.
 
--lars




From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Kris Zyp
Sent: 9. mai 2008 07:19
To: [EMAIL PROTECTED]; es4-discuss Discuss
Subject: getter and setter inheritance


A question of how inheritance/delegation should work
with getters and setters was raised in a recent discussion. If there is
an object A whose prototype is object B, and object A defines a getter
for property foo, and object B defines a setter for property foo, and we
write a value to A.foo, should the setter defined on object B be called?
If A didn't define any property on A, the setter would be inherited from
B and would be called when A.foo was modified. However, with the getter
defined on A, should the inheritance stop at A, because there is a slot
defined, or should it continue along the prototype chain because there
was no setter defined for that property (nor plain value)? The question
also applies when the getter and setter are reversed. When a property is
accessed and there is a setter defined, but no getter, should we
continue to down the prototype chain to find a getter or a plain value,
or stop and return undefined? AFAICT, ES4 doesn't explicitly define
which is the correct behavior. Firefox follows the former behavior:
 
B={set foo(v){foo = v},
get bar(){return bar value}}
A={get foo(){return foo value},
set bar(v){bar = v},
__proto__:B}
 
A.bar - undefined
A.foo = 'new value' - setter is not called, foo is not
set
 
Thanks,
Kris

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