Saturday, August 11, 2007

I want structural and denotional typing

Originally Cahalang classes were rather simple records. You know, a bunch of named members wrapped up into a named type. Two types with the same members would have nothing in common unless descended from a common superclass. I also had the idea of having union and intersection types. For example you could define an ElfWizard type that was the intersection of Elf and Wizard. You could also do it without naming the resulting class, as in having an Elf&&Wizard variable.

Then something happened. You see, I was thinking about functions and had this idea that the arguments to a function defined a class and that the return values defined another class. That somehow the type of the function was more than just a tuple type. That maybe I could unify functions and constructors in an elegant way. Turned out that I couldn't make it work and keep with my design principles so I abandoned the idea. However it lead to something new.

First a bit of background. In Cahalan , is the tuple operator. So 5,6 is a value of type int,int. Nothing too special, many languages have tuples. However they don't interact well with templates. Consider the C++ list template class. What if I want a list of int,int? What then? I can't pass it int,int because then it is two parameters. I needed a way to box up tuples into single entities. Thus the boxing syntax was born. Thus [5,6] is a single value, not a tuple of values, and [int,int] is a single type, not a tuple of types.

Now here is where my constructor idea lead:

[int x, int y] a;
a.x=5;
a.y=6;

Boxing up variable declarations would create a class literal. Very cool, very structural.

What about denotional typing? I still want that! So now I am thinking that the following will hold true: (the << operator is the subset/subtype operator)

[int,int] << [int x, int y]
[int,int] << [int a, int b]
[int x, int y] << Point //typedef Point [int x, int y]
[int a, int b] << Complex //typedef Vector [int a, int b]
[int x, int y] << Vector //typedef Vector [int x, int y]

So now what about the intersection and union operators? I'm thinking that they will only work on named types. That way if you do an intersection type of two types that each have an x, you will be able to refer to them as A.x and B.x or whatever. Not that you should do that of course. However banning intersections of types that share member names just sounds cruel and is likely to lead to people naming their members A_x and B_x or something stupid. Note: intersection types are like using virtual inheritance in C++. Multiple inheritance got a bad name mainly to the default being non-virtual inheritance, oh and the fact that inheritance is overused in general.

Another development is that the unboxing operator would alleviate the hardship of not having a this pointer:

a'; //all of a's members are now locals; you don't need to write a.x or whatever.

No comments: