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