From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: To: 9fans@cse.psu.edu, inferno-list@vitanuova.com Date: Thu, 20 May 2004 20:51:36 +0100 From: rog@vitanuova.com In-Reply-To: <20040520192144.10183.qmail@g.galapagos.bx.psu.edu> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Cc: Subject: [9fans] limbo polymorphism Topicbox-Message-UUID: 81d18060-eacd-11e9-9e20-41e7f4b1d025 >| 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!).