9fans archive / 2004 / 05 / 373 / prev next
From: rog@vit...
Subject: [9fans] limbo polymorphism
Date: Thu, 20 May 2004 20:51:36 +0100
>| you could express it quite nicely with the new limbo
>| polymorphism stuff:
>
>Is there a good reference to look at for that?
ahem.
i don't believe there is, until someone gets around to updating the
reference manual.
the syntax does seem reasonably stable now, so that should probably
happen...
it's really quite straightforward though:
a function or adt can be parameterised with one or more type names (in
square brackets). these types can be used in the body of the function
or adt as any other type.
e.g.
reverse[T](x: list of T): list of T;
Table: adt[T] {
items: array of list of (int, T);
new: fn(nslots: int): ref Table[T];
add: fn(t: self ref Table, id: int, x: T): int;
del: fn(t: self ref Table, id: int): int;
find: fn(t: self ref Table, id: int): T;
};
a "for" clause can define operations on the types (by default
there are none save assignment (and possibly equality, although
i think that will be deprecated).
e.g.
sort[T](a: array of T) for {
T =>
cmp: fn (t0, t1: T): int;
};
Env: adt[V]
for {
V =>
discard: fn(v: self V);
}
{
items: array of list of (string, V);
new: fn(nslots: int): ref Env[V];
set: fn(t: self ref Env, id: string, x: V);
get: fn(t: self ref Env, id: string): V;
clear: fn(t: self ref Env);
};
[the last syntax is going to change, i think, so that
the for clause comes *after* the adt declaration, rather
than in the middle as currently.]
when calling a type-parameterised function, the compiler infers the
type parameter from the given arguments (currently it's not possible
to explicitly name the type, although that'll come, once john susses
the grammar).
with a function or adt declared polymorphically, you can use any
"pointer type" (i.e. ref adts, chans, arrays, lists and strings).
for polymorphic types that require member functions, the type has to
be an adt containing at least the required member functions.
so, given the above declaration, you could do:
x := reverse("one" :: "two" :: "three" :: nil);
to get a list containing "three"::"two"::"one"::nil (assuming
reverse() reverses a list!).