[mercury-users] function types + impure impurity

Ralph Becket rbeck at microsoft.com
Wed Mar 7 01:53:07 AEDT 2001


> From: Dominique de Waleffe [mailto:ddw at miscrit.be]
> Sent: 06 March 2001 14:20
> To: peter.ross at mercury.miscrit.be
> Subject: [mercury-users] function types + impure impurity
> 
> I wanted to define f0 as a function of  no arguments returning
> something:
> 
> :- func f0=(data::out).
> f0=DS:-
> 	DS=mctime__current_date_string.

You can just write that as

	:- func f0 = data.
	f0 = mctime__current_date_string.

> and wanted to store said function (unevaluated) in a data structure,
> 
> :-type data ->
>        data(int)
>        ; closure(func=data).

This is a syntax error.  The trouble here is that `func' is a prefix
operator, so you need to write

	:- type data
		---> data(int)
	      ;    closure((func) = data).

However, since the argument to closure/0 is a constant (i.e. a nullary
function) this raises the question of why you want to store the closure
rather than its result.

If for whatever reason you do need to store the closure and not the
result, you'll have to be careful about modes.  For instance, you'll
want to define something like

	:- inst data == bound( data(ground) ; closure((func) = out is det)
).

and then use modes `in(data)' and `out(data)' rather than `in' and `out'
as you would normally.  This also means that you can't make much use of
many library functions and predicates since they don't have the right
modes (one day this will be fixed).

> This did not work (strange messages about unknown type '='
> 
> I then tried to define a type:
> :-type funarg == (func=data).
> :-type data ->
>        data(int)
>        ; closure(funarg).

Another problem here is that you are using `->' rather than `--->'.
 
> Then, of course I wanted to make f1 impure as it really should...
> 
> As in
> :-impure func f1(T::in)=(data::out).
> f1(_)=DS:-
> 	DS=mctime__current_date_string.

Ah, now I understand why you want to store the closure rather than the
result.  This is a horrible thing to do!  Why does this have to be impure?
Can't you get make mctime__current_date_string depend upon the io__state
and do away with the need for impurity?

> At some spot, I build a data structure which needs to store the
> function pointer in a data structure, for evaluation at a later time.
> 
> add_other_dynamic_keys(args):-
> 	<stuff>
> 	add_dico_entry(Key,def(dynamic(f1)),Dico0,Dico),
> 	<more stuff>

You have to label each call to an impure function; the only accepted
syntax for doing so is

	impure Var = f0	% We don't need f1 - see above.

> To me, there is nothing impure here since the function is not
> evaluated,  however the compiler reports:

But you are passing around an impure function.

 
> Of course, the mctime__current_date_string should also have been
> marked as impure, because it really is.... but since it is not,
> compiler thinks (and warns that f0, f1) are pure even though declared
> impure...

Ouch!  I really advise you to pass around the io__state where necessary
and use the time module which comes with all the machinery you need.
Impure stuff is (I believe) made deliberately cumbersome(*) to dissuade
people from using it.

Ralph

(*) Mind you, it is necessary to flag all the impure parts of your 
program if you are to retain the safety aspects of the language.
--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the users mailing list