[Grace-core] Dialect Design Proposal

Kim Bruce kim at cs.pomona.edu
Wed Nov 28 08:56:49 PST 2012


> 
> So the current design has the "superclass" and "subclass" objects being the *same object* - the previous design did not - 
> however before the sub-object-constructor has executed, behaviour will be that of the super object. I think.
> For example, this code prints "TOP" then "BOT".  
> 
> class top.new {
>    method x {print "TOP"}
>    x
> }
> 
> class bot.new {
>    inherits top.new
>    method x {print "BOT"}
>    x
> }
> 
> bot.new 

This is NOT the semantics of current class-based object-oriented languages.  Here is the equivalent code in Java:

public class Top {
	public Top() { x(); }
	
	public void x() {System.out.println("top");}
}

public class Bottom extends Top{
	public void x() {System.out.println("Bottom");}
	
	public static void main(String[] args) {
		new Bottom();
	}
}

If you compile and run it, it will print out "Bottom"

Here is the equivalent Scala program:

package testSemantics

class Top {
	def x {println("Top")}
	x
}

class Bottom extends Top {
    override def x {println("Bottom")}
}

object Tester {
  def main(args:Array[String]){
	  new Bottom;
  }
}

If you compile and run it, it will also print out "Bottom"

If you know another class-based language that gives a different answer, please let me know.  I can think of NO justification for the other answer.  If you are overriding a method, surely you expect all calls on the object -- including those doing initialization, to use the new value.

I can imagine a language which decides not to allow self-calls until the object is fully constructed, but that really ties your hand behind your back.

> 
> 
>> As Andrew has pointed out, inheritance from objects has issues.  No doubt this explains why it generally doesn't show up in mainstream languages.
> 
> yep.
> 
>> James points out below that this is supported by Self and Javascript, but they are prototype based.
> 
> and, in practice, Self had issues too. I know less about JS, but I don't think we'd want to emulate it either.
> 
>> At this point, I'm confused enough that I'm not even sure any more what the intended semantics is for inheritance from objects.  Is it sharing (essentially some variant of delegation) or does it involve some sort of implicit clone (though I'm not sure what kind)?  Perhaps someone can point me to an e-mail that proposes exactly what it should be.
> 
> I don't think there as been such an email, although there have been emails about discussions.
> I think implicit (shallow) clones are bad.  Explicit clones result in something pretty close to the "fresh objects"
> design that we already have - expect that all "inheritable" objects would need to support a clone method,
> that method would have to be built in, and so we now have two primitive generative mechanisms
> (generative object constructors, and clone).  So far we've survived without clone, right?
> 
>> I'm getting frustrated enough to suggest maybe we should support both of these semantics by different syntax.  One instructor could choose working with classes and classical inheritance, while another could choose working with objects and some sort of delegation (perhaps using "sharing" instead of "inherits").  Both clearly have some uses, and neither seems easily definable from the other (and I fear what error messages would look like if we tried to define them that way).
> 
> that's one option - although it is the classical "design by committee" solution: put everything in. 
> 
>> I'm not happy with this solution, but I'd be even more unhappy to throw out the standard semantics of inheritance.  Andrew would be very unhappy if we threw out inheritance from objects.
> 
> I don't know if I'd be very unhappy, but I'd certainly be unhappy with two similar but subtly different inheritance-like mechanisms.
> If we must have two mechansism, make them as brutally different as possible! 
> 
>> Is there anything that might bridge the gap that doesn't make everything worse?
> 
> I don't know.  O'CAML style initializers? 
> Explicitly building objects with mirrors (sounds to close to macros to me)?
> Traits / FJigsaw style object construction?
> 
> How bad would it be if clonable objects either had to inherit from "Clonable" (or - potentially worse) had to have a Clonable annotation?
> 
> Then you could at least do something like this: 
> 
> def myTrait = object {
>  extends Clonable.clone /// have to clone or we corrupt the Clonable trait object! 
>  method foo {...}
>  method bar {...}
> }

Keep in mind we have single inheritance, so that means nothing clonable could ever extend anything that was not itself already clonable.
> 
> 
> class myClass.new {
>     extends myTrait.clone // again must clone to avoid prototype corruption problem
> }
> 
> extending this model to multiple inheritance is... trickier.  
> And there is very little difference with this: 
> 
> class myTrait.new = object {
>  method foo {...}
>  method bar {...}
> }
> 
> class myClass.new {
>     extends myTrait.new
> }
> 
> in fact I think the class version is better overall...
> 
> James



More information about the Grace-core mailing list