[m-users.] di / uo -- some clarification please.

Mark Brown mark at mercurylang.org
Tue Aug 6 17:08:07 AEST 2019


On Tue, Aug 6, 2019 at 3:19 AM emacstheviking <objitsu at gmail.com> wrote:
>
> Hello,
>
> I seem to have somehow conflated the use of the state variable form !X with the use of the modes "di" and "uo" because so far the the only place I have used such notation has been with the special !IO state variable.
>
> I now have a game loop:
>
> :- pred game_loop(
>     app_state::di,  app_state::uo,
>     game_state::di, game_state::uo,
>     io::di,         io::uo)
> is det.
>
> game_loop(!AppState, !GameState, !IO) :-
>      :
>      : game state and app state code...
>      :
>     game_loop(!AppState, !GameState, !IO).
>
> This is condensed for clarity(!) but have I understood the concepts correctly. My intention is that after one pass of the game loop the "old" (di) application and game states can be junked i.e. their memory deallocated as the new incarnations are now the current ones, ready for the tail-cail back into the next iteration of the game loop.
>
> Is that the correct use case?
>
> The game state will contain all the mutable stuff for the game and the application state is slightly higher level stuff like "should I terminate" etc.

Hi Sean,

As others have said, it's likely you will hit difficulties this way
(unfortunately). I've had a fair bit of success with this kind of
thing, however, by separating out parts of the data structures that
are (mostly) unique and passing them via their own state variables.
The recursive predicate usually ends up looking something like:

    loop(Info, !State, !A1, !A2, ...)

where
 - Info is an 'in' argument containing parameters that don't change
(including things like mutvars)
 - !State is an 'in, out' argument pair that collects together all of
the non-unique, changeable state
 - !A1, ... are 'di, uo' (or 'mdi, muo', or 'array_di, array_uo')
argument pairs, with standard library types such as array, random, io,
etc.

The obvious drawback is that there's no saying how many argument pairs
you might end up needing to pass around, although in practice maybe
that won't be too big a problem for you? (Technically there is a way
around this if really needed, albeit using unsafe promises and a bit
of boilerplate).

Mark


More information about the users mailing list