Monday, July 23, 2007

An extension to the type system

Why change Hyper's type system? The main reason is arrays, or more specifically the array index operator. When you have an array of 'int', the return type of the index operator needs to be a pointer to an 'int' in order for you to be able to change the numeric value in the array. (Currently this is not the case yet; the array index operator returns a plain 'int' for such an array. That will be fixed of course.) But what when you have an array of pointers to 'int'? What will be the index operator's return type then? Logically it has to be something like pointer to pointer to int, because of the extra level of indirection that is needed. After all, you should be able to change the int pointer. But at this time the language disallows multiple levels of pointers!

My first idea to solve this problem was to introduce "inout return types". It would provide an extra (hidden) reference to the actual type, as it is done for inout parameters. But I decided not to do that, as it would be a quirky solution. And then someone pointed out that the current pointer system is weird and makes source code unreadable because of the implicit (de)referencing done by the compiler. So I thought of changing the type system to be more like C++, with explicit referencing/dereferencing for most things. Unfortunately it seemed to me that the changes would lead me to something that was almost identical to C++ but a bit more complicated. I decided that this wasn't an option either.

I looked back to the actual problem and my first idea of 'inout return types'. What I have come up with is a bit similar to that solution, only less quirky. The main idea is introducing a second pointer level, thus allowing a pointer-to-pointer-to-class type to be declared in some places. This introduces an ambiguity, namely: to what pointer level does the pointer assignment etc. apply to? Well, the second (i.e. top-level) pointer is only used as a reference to the single pointer; you need to be able to change the single pointer as in the array-of-pointer-to-int example. That means all pointer operations would need to work on the single pointer, the one that points to the 'int' in the example. The double pointer would serve like a reference in C++, only initialized once and always dereferenced when used in an expression. The usage of such a double pointer is not universal; it would not be allowed for parameter types, because input parameters don't need a second level of indirection and because inout parameters already provide an implicit second pointer for a pointer parameter. A double pointer can be useful for return types, for variable types, and maybe for fields as well.

Some examples now:
var i : int = 22
var p: *int = i # points to i
var pp: **int = p # points to p
var b : bool
b = (p = 22) # yes, p equals 22
b = (pp = 22) # yes, pp equals 22
b = (pp $= p) # yes, pp equals p
p = 47 # change i to 47
pp = 84 # change i to 84
p $= new int(55) # p no longer points to i
pp $= new int(31) # p changed again, points to 31
As you see in the example pp can not be changed anymore; it is a reference to p and all pointer assignments done on pp will be therefore applied to p.

This new functionality allows us to write a class that serves as a pointer-to-int:
class IntPtrArray
var fP : [10] * int # array has a fixed size of 10 ints

const procedure size() : nat
return 10

operator[](index:nat) : **int
# return a reference to the int pointer
return fP[index]

const operator[](index:nat) : *int
# no double pointer return needed (array is const)
return fP[index]
I'm not sure when I will implement this feature, but unless I get some serious objections against this the feature will be added to the language.

Thursday, July 19, 2007

website moved

My website has moved recently. The new URL for Hyper is:

The project is somewhat stalled right now. I don't have much time these days, and the language's type system needs to be reworked a bit.