[m-dev.] Suggestion: default func-type/mode correspondence.

Fergus Henderson fjh at cs.mu.OZ.AU
Tue Jul 24 05:40:08 AEST 2001


On 23-Jul-2001, Ralph Becket <rbeck at microsoft.com> wrote:
> > From: Fergus Henderson [mailto:fjh at cs.mu.OZ.AU]
> > Sent: 23 July 2001 13:20
> > 
> > What should happen if `T' is an abstract equivalence type that is
> defined
> > 	(a) in the same module as `foo'
> > or	(b) in some other module
> > as being equivalent to a higher-order function type?
> > 
> > I would not be suprised if the current compiler gets that wrong,
> > e.g. allowing mode-incorrect code to compile and crash at runtime.
> 
> The idea is that the refinement would occur at the call site.  If the
> call site doesn't know the concrete type of X then it can't perform
> inst refinement on the returned value.  However, should quantity X
> ever be returned to a site that does know its type then it can have
> its inst refined.
> 
> Can you give an example where a mode problem could arise?

See attached.
The first one, func.m, shows how the problem can arise with polymorphic types.
The second, func3.m, shows how it can arise with abstract types.
The current implementation correctly rejects func.m, reporting a mode error,
but incorrectly allows func3.m, generating incorrect code.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
-------------- next part --------------
:- module (func).

:- interface.
:- import_module io.

:- pred main(io__state, io__state).
:- mode main(di, uo) is det.

:- implementation.

:- import_module int, std_util.

main -->
	{ baz(foo, F) },
	io__write_int(F(42)), nl.

:- func foo(int) = int.
foo(X) = X + 1.

:- func bar(int) = int.
:- mode bar(out) = in is det.
bar(X) = X + 1.

:- pred baz(T::in, T::out) is det.
baz(X, Y) :-
	( univ_to_type(univ(bar), Y0) ->
		Y = Y0
	;
		Y = X
	).

-------------- next part --------------
:- module func3.

:- interface.
:- import_module io.

:- pred main(io__state, io__state).
:- mode main(di, uo) is det.

:- implementation.

:- import_module func3__sub.
:- import_module func3__id.

:- import_module int, std_util.

main -->
	{ baz(IdF), eq(getval(IdF), F) },
	do_io(F).

:- func foo(int) = int.
foo(X) = X + 1.

:- func bar(int) = int.
:- mode bar(out) = in is det.
bar(X) = X + 1.

:- module sub.
:- interface.
:- type t.
:- pred baz(id(t)::out) is det.
:- pred eq(t::in, t::out) is det.
:- pred do_io(t::in, io__state::di, io__state::uo) is det.
:- implementation.
:- type t == (func(int) = int).
baz(mkid(bar)).
eq(X,X).
do_io(F) --> io__write_int(F(42)), nl.
:- end_module sub.

:- module id.
:- interface.
:- type id(T).
:- func mkid(T) = id(T).
:- func getval(id(T)) = T.
:- implementation.
:- type id(T) ---> id(T).
mkid(X) = id(X).
getval(id(X)) = X.
:- end_module id.



More information about the developers mailing list