[Grace-core] Minutes of Teleconference 2012.01.10-11

Kim Bruce kim at cs.pomona.edu
Fri Jan 13 15:40:58 PST 2012


I've been trying not to get involved in this thread because it opens old wounds that continue to fester.

The big issue is that the encoding of classes as objects we adopted is not correct for a static type system.  The way we have been talking about it violates all the usual rules for static scope and information hiding in these languages.  If the type of a (class) variable (or constant) is {new(...) -> NewType} then you don't get to peek into the code for the implementation of the new method if you are trying to extend a class.  The whole point of the type is to present what you want to be public and hide what you want to be hidden.  I understand that it doesn't work that way in the dynamically typed world, but that is the way it works in the statically typed world.

I agreed to pretend (because I don't believe it - it is not a correct encoding) that we could encode classes that way, with my own understanding being that there is an implicit conversion operation that converts an class to an object with a new method by forgetting a lot of information about implementation.  Our requirement of statically manifest definitions allowed me to maintain that illusion -- at least to myself, and provided me with a way of justifying (though rather weakly) to others knowledgable about static typing.  However, it is wrong and I greatly dislike it.  (See Abadi-Cardelli for the correct encoding.)

However, once we start writing class expressions (rather than declarations) that can be used in definitions and assignments then you start down the slippery slope where you (or at least I) can no longer pretend it is correct.  If you write
	def foo = class {...}
then it is quite reasonable to write down a type for Foo.  The object type with "new" method is not the correct type for the class, but is something the class could be implicitly converted into. 

"Obviously" if you can write that, then you can also write var foo := class {...} or pass such an expression into a method as a parameter.  But then, why can't you extend it to form a subclass?  Well we have this "statically manifest" rule that mysteriously distinguishes between "good" expressions and "bad" expressions just in the case of classes.  What an ugly wart!  Talk about inconsistency!!!  How do I explain that to novices!

If I were to start down this road of making classes into first class expressions then I would start by giving classes real types (as in my book) that does reflect the information needed in order to determine whether a proposed extension is legal without having to dig into source code and into scopes that are not currently visible (i.e., whole program analysis -- something most people agree is highly undesirable for type-checking).  

Based on my experience with the languages I designed (e.g., LOOM), I thought that was overkill and not needed for a language with the goals we have for Grace.  Hence I didn't push it.  However, if we are going to make class expressions (rather than declarations) then I will insist that we stop lying (at least in the static world) and do this properly by using a correct encoding of classes (a la Abadi-Cardelli) if you still want to do encodings.  I personally think the encodings are not worth the warts it puts in the language, and would be thrilled to drop them entirely.  It is the only feature of the language that I can't defend to language experts, and I often wish I had not agreed to it.

If we keep classes as declarations then I will continue pretending that something else is actually going on, but if we make them expressions then I find it no longer defensible.

Kim



On Jan 13, 2012, at 2:04 PM, Andrew P. Black wrote:

> 
> On 13 Jan 2012, at 1:10, James Noble wrote:
> 
>> what happens if you execute a class constructor multiple times. 
> 
> You get multiple classes, of course.   What else could it possibly mean?   (Consistency and orthogonality again.)
> 
> Of course, since our class construct is just a shorthand for an object that has no instance variables, those multiple classes would be egal.  The objects that they manufacture  would have the same type, because of structural typing.   So I don't see that this is harmful in any way.
> 
>> If we write "def Foo = class { }" we are making classes even closer to object constructors --- 
> 
> I would say that we are making class constructors parallel to object constructors, and also to blocks, which are "function constructors".   Similar syntax, similar semantics.
> 
> You convinced me that with types declaraions, there is a reason to use a different syntax — we want types to be manifest.   But I don't know of any such reason for classes.
> 
> 	Andrew
> 



More information about the Grace-core mailing list