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

Julien Fischer jfischer at opturion.com
Tue Aug 6 12:38:13 AEST 2019


Hi Sean,

On Mon, 5 Aug 2019, emacstheviking wrote:

> 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.

In *principle*, that's the idea.  In practice, the current implementation
won't re-use the dead game_state and app_state values there.
(See
<http://www.mercurylang.org/information/doc-latest/mercury_ref/Limitations-of-the-current-implementation.html#Limitations-of-the-current-implementation>.)

*If* destructive update is important for performance there, then you may
want to consider the use the standard library's store module.  Something
like:

     :- type app_state
         --->    app_state(
                    thing1 :: io_mutvar(int),
                    thing2 :: io_mutvar(settings),
                     ....
                 ).

     :- type game_state
         --->     game_state(
                     position  :: io_mutvar(position),
                     inventory :: io_mutvar(inventory),
                     hitpoints :: io_mutvar(int)
                   ).

     :- pred game_loop(app_state::in, game_state::in,
        io::di, io::uo) is det.

     game_loop(AppState, GameState, !IO) :-
         ...
         % Remove 10 hitpoints from the player's total.
         store.get_mutvar(GameState ^ hitpoints, HitPoints, !IO),
         store.set_mutvar(GameState ^ hitpoints, HitPoints - 10, !IO),
         ...
         game_loop(AppState, GameState, !IO).

(You don't necessarily need to use the I/O state as the I have here.)

Julien.


More information about the users mailing list