[m-users.] ui modes

Michael Day mikeday at yeslogic.com
Thu Aug 1 11:37:19 AEST 2013


I would like to change store.get_mutvar to use ui modes, like this:

:- func get_mutvar(io_mutvar(T), io) = T.
:- mode get_mutvar(in, ui) = out is det.

This seems to have entirely reasonable semantics, as get_mutvar always 
returns the same result in the absence of updates to the io.state, and 
does not change the effect of any other IO operation.

The reason I want to do this is so that I can have read-only access to 
mutable variables in semidet code and if statements.

Generally, ui modes don't work. But for atomic dummy types like io.state 
they seem to work well enough.

However, I have hit a couple of issues. A predicate with multiple 
clauses will bind the IO as ground and lose its uniqueness:

blah([], _IO).
blah([_|_], IO) :- get_mutvar(..., IO)

Whereas writing it as an explicit switch is fine:

     blah(Xs, IO) :- ( Xs = [] ; Xs = [_|_], get_mutvar(..., IO) ... )

This makes code a little more verbose. Also, "not" and implication bind 
the IO as mostly_unique instead of unique:

     not(blah(Xs, IO)) <-- mode error

     blah(Xs, IO) => fail <-- mode error

Whereas writing it as an explicit if-then-else is fine:

     ( if blah(Xs, IO) then fail else true )

So ui modes still seem very fragile, which makes me nervous. But using 
them for get_mutvar is enormously convenient compared to having to 
destructively thread the IO state through absolutely everything.

Is it possible to improve the handling of ui modes for atomic dummy 
types like this?

Best regards,


Prince: Print with CSS!

More information about the users mailing list