subtyping proposal
David Glen JEFFERY
dgj at cs.mu.OZ.AU
Tue Feb 10 15:30:25 AEDT 1998
On 10-Feb-1998, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> Here's a suggestion for a language extension,
> namely a new `:- subtype' declaration.
Not a bad idea, but I have a few comments.
> We already have one mechanism for subtypes/inheritence,
> namely type classes; do we need another one?
This is certainly true. Perhaps it would be better to hold off on this for a
while until we have come to terms with programming with type classes a little
more.
In particular, I think that the following example would be better solved using
a type class approach:
(Warning, I'm just making this up off the top of my head... this probably needs
a little more thought... particularly the names).
> This change would allow us to use subtypes to define the
> io__stream types
>
> io__stream
> io__text_stream
> io__input_stream
> io__output_stream
> io__bidirectional_stream
> io__binary_stream
> io__binary_input_stream
> io__binary_output_stream
> io__binary_bidirectional_stream
>
> with an appropriate subtype relation.
> The subtype relation here involves multiple inheritence:
>
> io__stream
> / \
> / \
> io__text_stream io__binary_stream
> / \ / \
> io__input_stream io__output_stream ... ...
> \ / \ /
> io__bidirectional_stream .......
>
:- typeclass stream(S) where [
...
].
:- typeclass text_stream(S) <= stream(S) where [
...
].
:- typeclass input_stream(S) <= text_stream(S) where [
pred read_word(S, io__result(list(char)), io__state, io__state),
mode read_word(in, out, di, uo) is det,
...
].
:- typeclass output_stream(S) <= text_stream(S) where [
pred print(S, T, io__state, io__state),
mode print(in, in, di, uo) is det,
...
].
:- type input_stream ---> input_stream(c_pointer).
:- instance stream(input_stream) where [...].
:- instance input_stream(input_stream) where [
pred(read_word/4) is the_implementation_of_read_word
].
% Ditto for output_stream
We can now handle bidirectional_stream like this:
:- type bidirectional_stream
---> bidirectional_stream(
input_stream,
output_stream
).
:- instance input_stream(bidirectional_stream) where [
pred(read_word/4) is bidirectional_stream_read_word,
...
].
:- pred bidirectional_stream_read_word(bidirectional_stream::in,
io__result(list(char))::out, io__state::di, io__state::uo) is det.
bidirectional_stream_read_word(bidirectional_stream(IS, _), Res) -->
read_word(IS, Res).
% Ditto for the bidirectional_stream instance of output_stream
We could also have a typeclass like this:
:- typeclass bidirectional_stream(S) <= (input_stream(S), output_stream(S))
where [
...
].
if we wanted, but that might be overkill. It is useful if we want to extend
the subtype relation though.
> Drawbacks:
>
> One problem with this proposal as it stands is that using the
> mode system for subtypes doesn't work well with polymorphic
> predicates or containers.
The type class approach has a problem with building heterogenous containers.
For example the type:
:- type io__stream_names == map(io__stream, string).
would cause a few problems.
We need existential types to solve this. (But more about this later... :) ).
(It can also be solved in this case by having a type:
:- type io__stream ---> input_stream(input_stream)
; output_stream(output_stream)
...
Anyhow, that's just a rough proposal. Ideas?
love and cuddles,
dgj
--
David Jeffery (dgj at cs.mu.oz.au) | Marge: Did you just call everyone "chicken"?
MEngSc student, | Homer: Noooo. I swear on this Bible!
Department of Computer Science | Marge: That's not a Bible; that's a book of
University of Melbourne | carpet samples!
Australia | Homer: Ooooh... Fuzzy.
More information about the developers
mailing list