[m-users.] ui modes
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) :- 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?
Prince: Print with CSS!
More information about the users