Types, Makers, and Inheritance

Mark S. Miller markm@erights.org
Tue, 03 Nov 1998 20:58:03 -0800


At 02:48 PM 10/20/98 , Bill Frantz wrote:
>I am getting confused.  As I see it, we don't have types now.  The only
>checking we have is that a particular invocation "makes sense".  That is,
>the designated object has a method with the correct name which accepts the
>correct number of parameters.  It seems somewhat Smalltalkish to me.

[+] It's Smalltalkish both statically and dynamically.
Both E and Smalltalk have no static type checking.  Both E and Smalltalk do
method dispatch only on name and number of parameters.  (Actually, in
Smalltalk the name determines the number of parameters, but it amounts to
the same thing.)  In Smalltalk, Java, and E, you can ask an instance for an
object that describes the protocol it responds to.

Neither Java nor E conflate this protocol description object with the
service (not an object in Java) for making such instances.  Smalltalk does
conflate these in the way that's been advocated, but as a result of not
separating these concerns, the resulting Smalltalk Class objects have a
*huge* protocol composed using a complex inheritance structure.


>What this means to me is that if I am passing an object to service, and
>that service's contract is that it will only call the "farble()" method,
>then I can pass any object which has a zero parameter farble method.  That
>is much less than full type compatibility.

[-] This is type compatibility.
In this case the type of the object is a subtype (ie, "<=") of the required
type.  The required type is characterized by the zero-argument "farble"
message.  Any object that responds to this message is a member of that
type.  Any protocol description that includes that method is a subtype of
that type.


>As to makers, it seems to me that having more than one maker for an object
>which obeys a particular contract could be useful.  Different
>implementations come immediatly to mind.

[+] Absolutely.
A classic example should make the Point:

	define CartesianPointMaker(x,y) {
	    define cartesianPoint {
	        to getX {x}
	        to getY {y}
	        to getLength {(x**2 + y**2) asDouble sqrt}
	        to getAngle { x asDouble atan2(y) }
	    }
	}

	define PolarPointMaker(length, angle) {
	    define polarPoint {
	        to getLength {length}
	        to getAngle {angle}
	        to getX {angle asDouble cos * length}
	        to getY {angle asDouble sin * length}
	    }
	}

These two makers produce objects with the same protocol.  If we ask two
such instances for their protocol, we must find they're compatible (ie,
each is a subtype of the other).

My trig is a bit rusty; please correct the trig above before this example
travels farther.  Thanks.