[Grace-core] Inheritance and Template Objects

Andrew P. Black black at cs.pdx.edu
Fri Apr 5 18:02:15 PDT 2013


On 5 Apr 2013, at 12:00 , Marco Servetto wrote:

> I'm not too sure to understand well this template idea, so sorry if
> what I'm saying can be out of topic; however:
> Is there any need to declare template explicitly?
> That is, template objects are representing (in my understanding) the
> "datastructure" of the class,
> in the implementation they would even be "some representation for" the
> abstract syntax tree of an object literal.

Yes

> What if every object literal is simply jointed with his template
> object statically created at compile time?

Yes — it contains a pointer to the template object.   This is like a class pointer, but the template also contains the initialization code containing an unbound self parameter. 

> That is, when one write
> def o1=object{....}
> ...
> def o2=object{ use o1.template .... }
> o2 is created using the "soul" of o1.

Yes.

> "template objects" are objects the user can not (or may be can in some
> dialect?) directly create and  observe; still they can be there, and
> can be first class too (with some weird typing issues?)
> And, of course, trait operators are simply messages over template objects.

I think that Marco understands what I had in mind.  Explicit use templates would not be necessary, because you could always get a template out of a prototype object (using the "soul sucking" operation).  But if one wants to think about inheritance pedagogically, then its desirable.  The difference between a class (which is used to make new instances) and a template (which is used to make new templates, via inheritance), and to define factory methods in classes (using instantiation), become important.

Looked at like this, the difference between templates and objects is as important as the difference between types and classes.   We could drake the language appear smaller by obscuring the distinction, but that won't actually make it simpler.

I don't know what James is trying too accomplish via his encodings.  As I said at the beginning of my original email on templates, I'm trying to get a clean conceptual model that I can write about in a textbook and that I can teach.  Once we agree on that, we can find a nice syntax that we like, hopefully one that is not very different from what we have been writing so far.   But I think that it' important to agree on the concepts first.

On 5 Apr 2013, at 16:17 , James Noble wrote:

> But in the template model, the templates are instantiated whenever they're inherited.

No, they are not.  You can compose two templates using inheritance (or using trait composition) without instantiating them.

> Or ... when writing  "object Template"

Yes, object <template> is the way that we would instantiate a template, creating an object that has that template as its "soul".

>> It's an explicit goal of mine not to have unnecessary incantations.  
> 
> Sure.  But the question then is whether we need a third concept -
> a template - as well as objects and classes that we've already got

In this proposal, we don't need classes as a concept.  We can still have classes as a syntax, but they are just a shorthand for an object with a factory method, as they have been for a while.

I believe that we do need an additional concept to get conventional inheritance semantics.  The theory tells us that we do (the class generators as well as the classes that are their fix points), and Michaels' s "constructors parameterized by self" scheme tells us that we do.  My original "inheritance by copying" scheme was an attempt to avoid this, but didn't work exactly because the stuff that needs to be in an object is different from the stuff that needs to be executed in construction that object.

> What I'm trying to get to are the essential difference between the proposals ...

What I'm hoping for is a succinct explanation of the proposal that you have in your head that you are comparing templates to.   I think that it may be that it's the same as templates, except that the templateOf operation is implicit, and is applied whenever an object appears after the inherits keyword.  I don't think that's right, but then maybe I don't understand your proposal.

When I wrote 

		def aCartesianPoint = object {
			method x(a)y(b) { 
				template {
					def x is public = a
					def y is public = b 
					print "nothing will be executed until an object is made from this template"
				}
			} 
		}

the idea was that aCartesianPoint.x(x)y(y) answered a template object, not a point object.  My example was bad, because colorPoint.x()y()color() did make colorPoint objects.  It would be more uniform like this:

		def aColorPoint = object {
			method x(x)y(y)color(c) {
				template {
					inherits aCartesianPoint.x(x)y(y)
					def color = c
				}
			}
		}

So that aColorPoint.x(x)y(y)color(c) answers a template object too, not a point object.   Importantly, inheriting from aCartesianPoint.x(x)y(y) does not create aCartesianPoint; it's a template-level operation. 

We can then make instances directly from the templates, if we want:

		def p = object aCartesianPoint.x(3)y(4)
		def cp = object aColorPoint.x(3)y(4)color(aColor.blue)

or we can make classes out of them:

		def pointClass = object {
			def origin is public = object aCartesianPoint.x(0)y(0)
			method x(a)y(b) { object aCartesianPoint.x(a)y(b) }
		}


		def colorPointClass = object {
			def origin is public = x(0)y(0)color(aColor.black)
			method x(a)y(b) { x(a)y(b)(aColor.black) }
			method originColored(c) { x(0)y(0)color(c) }
			method x(a)y(b)color(c) { object aColorPoint.x(a)y(b)color(c) }
		}

Yes, there is a certain amount of repetitive code here.   That's why (to my mind) we introduced the class syntax in the first place; to simplify the syntax of such common operations.   I'm quite prepared to see us redesign the syntax a bit to eliminate some of the verbosity.  But I want to agree on the underlying semantics first.

In contrast, with this definition, 

> class aCartesianPoint.x(a)y(b) { 
> 					def x is public = a
> 					def y is public = b 
> 					print "this string will be printed each time the x()y() method is executed"
> 			}  


requesting the x()y() method on aCartesianPoint will make an actual point object, and also print out the string.

If we go in the direction that I'm proposing, I think that we do need to be careful to be uniform in our naming.  It's a Bad Idea (capital letters) to have operations like x()y() answering both templates and instances.   And its a Bad Idea (capital letters) to use aFoo for a template-generating object and aBar for an instance-generating object.  But now it's time for me to go and cook dinner.

	Andrew


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailhost.cecs.pdx.edu/pipermail/grace-core/attachments/20130405/2e09f18e/attachment-0001.html>


More information about the Grace-core mailing list