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

Sean Charles (emacstheviking) objitsu at gmail.com
Sat May 22 00:12:58 AEST 2021


Hi Dirk
I thought the intention was clear enough; to read N strings from the environment, my predicate get_env_var_str will allow a default value to be returned if the named variable is not found.

I could have used a map I guess, that would be simpler for anything long term but the place where I needed it was just a command handler in my REPL code.

Thanks anyway!
Sean


> On 21 May 2021, at 15:10, Dirk Ziegemeyer <dirk at ziegemeyer.de> wrote:
> 
> Hi Sean,
> 
> I’m not completely sure if I understand the intention behind your code. Assuming you want to pass a list of options together with their values to a predicate you have several possibilities:
> 
> If there are always six options, you can define a record:
> 
> :- type env_variables
>    --->    env_variables(
>                felt_inst   :: string,
>                felt_pager  :: string,
>                felt_editor :: string,
>                felt_repl   :: string,
>                felt_lex    :: string,
>                felt_ast    :: string
>            ).
> 
> 
> Alternatively, you could use a key-value collection type like a map:
> 
> :- type env_variables == map(env_variable_name, string).
> 
> :- type env_variable_name
>    --->    felt_inst
>    ;       felt_pager
>    ;       felt_editor
>    ;       felt_repl
>    ;       felt_lex
>    ;       felt_ast.
> 
> 
> Dirk.
> 
> 
>> Am 21.05.2021 um 15:23 schrieb Sean Charles (emacstheviking) <objitsu at gmail.com>:
>> 
>> 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.
>> 
>> _______________________________________________
>> users mailing list
>> users at lists.mercurylang.org
>> https://lists.mercurylang.org/listinfo/users
> 



More information about the users mailing list