getter and setter inheritance

Lars Hansen lhansen at adobe.com
Fri May 9 09:46:30 PDT 2008


(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: es3.x-discuss-bounces at mozilla.org
[mailto:es3.x-discuss-bounces at mozilla.org] On Behalf Of Lars Hansen
	Sent: 9. mai 2008 08:41
	To: Kris Zyp; es3.x-discuss at mozilla.org; 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: es4-discuss-bounces at mozilla.org
[mailto:es4-discuss-bounces at mozilla.org] On Behalf Of Kris Zyp
		Sent: 9. mai 2008 07:19
		To: es3.x-discuss at mozilla.org; 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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.mozilla.org/pipermail/es-discuss/attachments/20080509/f9ce8a49/attachment-0002.html 


More information about the Es4-discuss mailing list