7 Polimorphism
This is probably the neatest thing in Gont. Structures, as well as
functions can be parameterized over types. Thus it is possible to
write generic types and functions, like list of anything, or
stack of anything.
For example to define list of anything you write:
opt_struct <'a>list {
'a data;
<'a>list next;
}
'a
is alpha. It is type variable, it stands for any type
(similarly 'b
is beta, but I really don't know what 'foo
is... :-) <'a>list
is read as ``list of alphas'' -- list of
data of any type. <int>list
is ``list of integers''.
Then you use it as:
<int>list l; // list of ints
<<int>list>list ll; // list of lists of ints
<string>list s; // list of strings
Now, when we have our polimorphic list, we note, that for example
length()
function doesn't need to know type of elements stored
in the list:
int length(<'a>list l)
{
int n;
for (n = 0; l != null; l = l.next)
n++;
return n;
}
Gont standard library includes modules with ready-to-use generic
datatypes.
7.1 Polimorphism vs templates
At the abstract level polimorphism is similar to templates in
C++. However, in Gont, code for given polimorphic function is generated
just once. Additionally polimorphism becomes really funny in conjunction
with functional values. We'll discuss it later.
You might have seen generic datatypes implementations in C. They most
often use void*
pointers as placeholders for user data. Gont does
essentially the same. However it ensures, this void*
is always
assigned and read from variables of the same type.
If you are familiar with C++ you know, that following C++ template
instance is not valid:
List<List<int>> l;
whereas in Gont, following is valid:
<<int>list>list l;
`<<' and `>>' are lexed as bitwise shift operators in both Gont and C++.
In C++ one have to write `< <', but in Gont parser handles this case
specially, just for convenience.