[Grace-core] Inheritance and object initialisation

Andrew P. Black black at cs.pdx.edu
Thu Jul 26 11:38:14 PDT 2012


On 25 Jul 2012, at 17:39 , James Noble wrote:

>> 
> It is a bit ironic that Michael's withdrawn a paper from PLOP on object creation in Grace though. 
> (But we can send it to EuroPlop next year, which is better to go to anyway)


Why did he do that?

>> By "constructor" I asume that Kim means "Grace object literal",
> 
> Yeah. We need to standardize on these names. Grace object, block & string literals aren't... literal.

This is true — they can all capture their environment.  Perhaps block constructor, object constructor and string constructor are better names. 

> 
>> Well, I think that this desire is unreasonable: inGrace, the object literal in B.new runs before B.new exists, and certainly should do the same thing regardless of the context in which B.new is invoked.   
> 
> Right. And herein is the difficulty. 
> Do you always want to inherit from a object that's already fully-formed?

No always, but often doing so avoids the problem of initializing the super-object.  That was the motivation for the present arrangement.

It's certainly possible to inherit from an uninitialized super-object and leave it to the sub-object to do the initialization — that was what my "Smalltalkesque" example was trying to show.  It's up to the designer to decide.

> 
>> Self in that object literal has to mean the object being constructed. 
> 
> It's odd to use self to refer to an object "before [that object] B.new exists"
> There is another interpretation here that makes some of these problems go away...

That's the magic of fixedpoints.  I don't suppose that you are advocating that we write fix( lambda self . { ...self ... }) !

> 
>>> Any good examples of inheritance using mutable objects (ideally where the state has changed since it was created)?
>> 
>> We didn't think that this was a common use case, which is why the current spec outlaws it.   
> 
> I'm not sure it does. It says you have to be able to find the object statically, not that the object has not been mutated since construction. A no mutation rule would be very hard indeed to enforce, especially with side effects from initializers and construction code. 

I meant "has not been mutated since the constructor finished running".  The current spec (which I have always argued was overly restrictive) says:

> The right hand side of an inherits clause is restricted to be a class name, followed by a correct request for that class’s method.


I suppose that the constructor could create a process that mutated the object while the inheritance was happening ... I hadn't thought of that!  It's a good thing that we don't have processes!

> ... my answer to Kim's question about "How do subclasses initialize defs" [is that]
> they have to have an explicit constructor parameter.  There is another answer: they override them, and let the compiler sort out the dead definition. 

This means that the meaning of a requesting an object constructor depends on the context in which the constructor is embedded.  I don't see any hope of writing a compositional semantics for that.


> But - in fact - this shows Kim's problem:  If the subobject overrides the border, that will work fine, but if they jus override the borderColour it won't have any effect. 

That depends on what use the super-object makes of borderColor.  This is always the case with inheritance, which is why it is both powerful and dangerous.  You can't inherit from a class, or an object, without a good understanding of how that class or object uses self messages to define it's behavior.  Perhaps the borderColor is used on each refresh cycle.  Perhaps on each "update" message from an observed object.  
> 
> 
>> but part of the advantage of inheritance is to *avoid* having to parameterize by everything that might change; instead, we override it.  So, how can we make error windows have red borders without changing the declaration of window?  Like this:
>> 
>>    def errorWindow = object  {
>>        inherits window
>>        ...
>>        method borderColor is override { Color.red }    
>>        border.setColor( borderColor )
>>    }
>> 
>> This seems quite natural to me.  The request border.setColor might be in practice be in an "open" method that also sets other appearance parameters, such as background color, size, etc.
> 
> The catch is that border.setColour has to be repeated in *every* subclass all the way down that wants to change the Colour.

It has to be "repeated" in every subclass that wants a _different_ color.  Otherwise, they will get the inherited color red.   Maybe that's what you meant.
 
>  It seems the open method heads back to having one big method with every single parameter that gets passed along. (Generalising requests might help a bit: passing through a map -Ruby style- might help a bit more)

No, the open method might have no parameters at all — the window object already knows it's attributes, such as size, position, border color, etc.   The point is that these attributes aren't interrogated until they are needed — when the window is opened.
> 
>> I think that the common cases of inheritance — where one inherits from an abstract superclass — will work just fine using Grace "delegation-style" inheritance.  This is because the abstract superclass is (in Smalltalk) just a singleton object with no state, which was our use-case when we defined Grace inheritance to clone such an object and then extend it to become the new object.
> 
> Perhaps. But if you want to do "Template Method" like things when you're setting up the object; or if you want to register it in some external service, then you can't. 

Yes you can — you just do them in an initialization method that executes after the object is constructed.  This is just like in Java and in Smalltalk.  The advantage of the Grace design is that one doesn't need such a method for the common case of passing values to fields — only for these more exotic cases, which are not what one teaches in the first few sessions of a course.

	Andrew




More information about the Grace-core mailing list