[mercury-users] Re: Mercury Tutorial / Functions

Ralph Becket rafe at cs.mu.OZ.AU
Thu Apr 24 10:30:48 AEST 2003

Goncalo Jorge Coelho e Silva, Wednesday, 23 April 2003:
> When I get to compile your sample code, I get a 
> 'mode error'.

> main -->
>         read_strings(Ss).

> inter.m:023: In clause for predicate `inter:main/2':
> inter.m:023:   warning: variable `Ss' occurs only once in this scope.

>  Appearently, the 'Ss' variable isn't unified with
> anything and/or can't get 'grounded'.

This simply tells you that Ss only occurs once.  If this is intentional,
you can prevent Mercury from issuing a warning by renaming Ss as _Ss.

> The 'unique'
> issue and the passing of state_of_the_word arguments
> like the IO0 and IO, are still not very strong to
> me.

I *strongly* suggest you don't use DCG notation (as you have for main/2)
until you're more familiar with how IO and uniqueness work.

In a nutshell, every IO operation takes as input a value denoting "the
state of the world" and computes a new value denoting "the state of the
world after the IO operation".  These "world states" have type
io__state.  IO operations affect the real world and, because one cannot
travel backwards in time and undo a physical action, one cannot
backtrack over IO operations or reuse old io__states.  Making io__states
unique guarantees these properties (i.e. the compiler can always tell
when a program could break one of these rules and report an error.)

>  As with list VS arrays, I had prevously seen the
> great easiness with which one can be converted into
> the other and vice-versa. It's indeed more clever
> to use lists once you don't know the size of the
> inout at the STD_IN.

Arrays are necessary when you need O(1) access and update.  But this
comes at a cost: mutable arrays must be unique (which imposes the same
constraints on arrays as io__states) and consequently have more
complicated modes.

The mode system isn't too complex, but I'd get comfortable with lists
and IO before delving into arrays.

> Here's the compilation error:
> inter.m:040: In clause for `read_strings_2(in, out, di, uo)':
> inter.m:040:   mode error in conjunction. The next 3 error messages
> inter.m:040:   indicate possible causes of this error.
> [...]
> read_strings_2(RevSs, Ss, IO0, IO) :-
>         io__read_line_as_string(Result, IO0, IO1),
>         (
>                 Result = ok(S),
>                 %io__write_string(S,IO0, IO1),
>                 read_strings_2([S | RevSs], Ss, IO1, IO)
>         ;
>                 Result = eof,

Here I omitted the goal

                  IO     = IO1,

which is necessary to ensure that IO is instantiated (as we promise in
the mode declaration) when read_strings_2/4 terminates.

>                 Ss     = list__reverse(RevSs)
>         ;
>                 Result = error(_),
>                 exception__throw(Result)

We don't need to add a goal instantiating IO in this disjunct because it
has determinism erroneous due to the call to exception__throw/1.

>         ).

> > > %myRead(MyArray) -->
> > > myRead(MyArray):-   
> Right again. This was where I was using those mischivious
> 'mode' declarations with 3 arguments. :(

As I say, don't use DCG notation for IO.

Number the IO states explicitly to start with.

Then look up the section on state variable syntax in the reference
manual and use that for IO instead.

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