[m-users.] Reasoning behind a compile failure on list destructuring

Sean Charles (emacstheviking) objitsu at gmail.com
Fri May 21 23:23:54 AEST 2021


I wanted a list of environment variables in one hit so I wrote a predicate to do it…I initially a lambda in list.map but IO was complaining etc and so I wrote my version:

get_env_str(Vars, Out, !IO) :-
    get_env_str_list_(Vars, [], Out, !IO).
    % Aux.
:- pred get_env_str_list_(
    list(string)::in, list(string)::in, list(string)::out,
    io::di, io::uo) is det.
    % done, reverse.
get_env_str_list_([], Acc, Out, !_IO) :-
    Out = list.reverse(Acc).
    % find, prepend.
get_env_str_list_([V|Vs], Acc, Out, !IO) :-
    get_env_str(V, "", Val, !IO),
    get_env_str_list_(Vs, [Val|Acc], Out, !IO).

Then I called it like this:

    utils.get_env_str([
        "FELT_INST", "FELT_PAGER", "FELT_EDITOR",
        "FELT_REPL", "FELT_LEX", "FELT_AST"],
        [Inst, Pager, Editor, Repl, Lex, Ast],
        !IO),

And got this:

repl.m:248: In `run_info'(di, uo):
repl.m:248:   error: determinism declaration not satisfied.
repl.m:248:   Declared `det', inferred `semidet'.
repl.m:253:   In argument 2 of call to predicate `utils.get_env_str'/4:
repl.m:253:   in argument 2 of functor `[|]/2':
repl.m:253:   in argument 2 of functor `[|]/2':
repl.m:253:   in argument 2 of functor `[|]/2':
repl.m:253:   in argument 2 of functor `[|]/2':
repl.m:253:   in argument 2 of functor `[|]/2':
repl.m:253:   unification with `V_60' can fail.
repl.m:253:   In argument 2 of call to predicate `utils.get_env_str'/4:
repl.m:253:   in argument 2 of functor `[|]/2':
repl.m:253:   in argument 2 of functor `[|]/2':
repl.m:253:   in argument 2 of functor `[|]/2':
repl.m:253:   in argument 2 of functor `[|]/2':
... error log truncated, see `repl.err' for the complete log.
** Error making `Mercury/cs/repl.c’.

It took me a while to figure it out, but I reasoned that despite the fact I know I passed in six variable names, the compiler could not know how many values might well be in the returned list, despite me knowing that the internal implementation would always return the same number of strings, even a blank one. That then made sense of the error message, my final code then is:

    utils.get_env_str([
        "FELT_INST", "FELT_PAGER", "FELT_EDITOR",
        "FELT_REPL", "FELT_LEX", "FELT_AST"],
        Vars, !IO),
    ( Vars = [Inst, Pager, Editor, Repl, Lex, Ast]
    -> do stuff
    ; apologise to user
    ).
Is that the correct reasoning behind the error? I hope so becaise I can’t really think of any other cause!

Thank you,
Sean.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20210521/65ed4327/attachment-0001.html>


More information about the users mailing list