[m-users.] IO and global state.

Dirk Ziegemeyer dirk at ziegemeyer.de
Mon Apr 26 18:39:20 AEST 2021


Hi Sean,

the following function declaration should satisfy the compiler:

:- func debug_on(io::di, io::uo) = (bool::out) is det.

If I were you, I would add a custom type and pass it around explicitly as a separate argument.

:- type debugging_flag
    --->    debugging_on
    ;       debugging_off.

Dirk


> Am 26.04.2021 um 08:51 schrieb Sean Charles (emacstheviking) <objitsu at gmail.com>:
> 
> Zoltan, Julien,
> 
> Thank you for your replies. I don’t think my application will remain ’small’ going forward but the one mitigating feature is that the values I want to save into the IO state are never going to change; they are the option_table values from a successful call to getopt, i.e. one where there were no unrecognised options and none that required immediate service and then termination e.g. help / version / list targets.
> 
> Excellent then, I shall happily save my constant data into IO state and see how it goes.
> 
> I do have one error I cannot figure out yet… I attempted to re-code my ‘debug_on’ predicate to use IO instead of the Options and I get an error I cannot yet figure out ( again :| )…
> 
> The exports:
> 
> :- func debug_on(felt_options) = bool.
> :- func debug_on(io::di, io::uo) = bool.   % LINE 28, see error message below.
> 
> 
> and the code:
> 
>     % helper: is debug_mode on or off ?
>     %
> debug_on(Options) = Mode :-
>     Mode = getopt.lookup_bool_option(Options, options.debug_mode).
> 
> debug_on(!IO) = Mode :-
>     io.get_globals(Options, !IO),
>     Mode = getopt.lookup_bool_option(Options, options.debug_mode).
> 
> 
> and I get the error message:
> 
> ➜  f2 git:(develop) ✗ make
> mmc -s hlc.gc -O4 -E --make felt
> Making Mercury/int3s/options.int3
> options.m:028: Error: some but not all arguments have modes.
> options.m:028:   The argument without a mode is the return value.
> ** Error making `Mercury/int3s/options.int3'.
> make: *** [felt] Error 1
> 
> 
> Help! I am confused because it looks identical to the declaration on the previous line except it uses IO not the option_table...
> 
> 
> 
> 
>> On 26 Apr 2021, at 07:36, Zoltan Somogyi <zoltan.somogyi at runbox.com> wrote:
>> 
>> 
>> 
>> On Mon, 26 Apr 2021 07:16:52 +0100, "Sean Charles (emacstheviking)" <objitsu at gmail.com> wrote:
>>> Is it a —wise— idea to consider using globals on the IO State?
>> 
>> We initially thought so, and wrote the compiler that way.
>> 
>> We later realized that beyond a certain complexity, it was simply
>> less error-prone to pass the globals explicitly to every part of the code
>> that needed it, even though it required writing more code.
>> The compiler now consistently passes the globals *separately*
>> from the I/O state, except maybe in the very initial startup code.
>> (I don't know for sure, I haven't looked at that code in a long time.)
>> 
>> The problem with consistently storing the globals in the I/O state
>> is debugging. When you are looking at a call that updates the
>> I/O state, you cannot be certain whether that call also updated
>> the globals, unless you inspect both the callee *and its entire
>> call tree*. In a small program, that is not too much of a burden;
>> in a large program, it is. Getting such things wrong can cause bugs
>> that are annoyingly hard to track down. Writing explicit code
>> to pass the globals is a tiny bit of extra work in the usual case,
>> but can save a lot unpleasant debugging.
>> 
>> So the answer to your question is: if you are sure that your program
>> will always remain small, then yes; otherwise, no.
>> 
>> Zoltan.
>> 
> 
> _______________________________________________
> users mailing list
> users at lists.mercurylang.org
> https://lists.mercurylang.org/listinfo/users



More information about the users mailing list