[m-users.] Problem with higher-order pred passed as argument

Sean Charles (emacstheviking) objitsu at gmail.com
Tue Jan 25 01:49:47 AEDT 2022


Thank you Zoltan, I think I understand now. I will make it work then break it deliberately and then make sure I have understood.

Thanks again!
Sean


> On 24 Jan 2022, at 14:38, Zoltan Somogyi <zoltan.somogyi at runbox.com> wrote:
> 
> 
> 2022-01-25 01:24 GMT+11:00 "Sean Charles (emacstheviking)" <objitsu at gmail.com>:
>>    % Processor program inlined-code
>>    %
>> :- type tpu_inject == (pred(tpu_state, tpu_state)).
>> :- mode tpu_inject == (pred(in, out) is det).
> 
> Mercury does not automatically apply a mode with a given name
> to arguments whose type has the same name.
> 
>>        ;
>>            Op = t_indent(Closure),  <= line 169
>>            Closure(!S)
>>        )
> 
> You don't show us the code that determines what the mode of Op is.
> I am betting that it is simply "in", because ...
> 
>> The line in bold is the source of the errors, those being that it says…
>> 
>> tpu.m:169:   In clause for `tpu_run(in, sub_identifier, sub_callterm, in, out,
>> tpu.m:169:   out, in, out)':
>> tpu.m:169:   in argument 1 (i.e. the predicate term) of higher-order predicate
>> tpu.m:169:   call:
>> tpu.m:169:   mode error: variable `Closure' has instantiatedness `ground',
>> tpu.m:169:   expecting higher-order pred inst of arity 2.
> 
> ... this is exactly the error I would expect in that case. The Mercury
> compiler knows, from the definition of tpu_inst, that the argument
> of t_indent is a predicate, but if Op's mode is just "in", and from that
> same source it knows how many arguments the predicate has and what
> their *types* are,  but it does not know their *modes*.
> 
> To tell it the modes, you should define an inst such as
> 
> :- inst tpu_inst
>    --->    loads(ground)
>    ;       vartype
>    ;       identifier
>    ;       callterm(ground, ground, ground)
>    ;       t_indent(pred(in, out) is det).
> 
> and then specify the mode of the Op argument as "in(tpu_inst)".
> 
>> I pass higher-order functions around with no issues as I have the pred and mode declarations correctyl defined but in this case, WHY is the compiler not seeing it as a higher order function despite the datatype t_indent(tpu_inject) and how do I tell it so?
> 
> Because it is a predicate, not a function. Functions have a default mode and determinism,
> which is why functions that have this mode and determinism can be passed in arguments
> whose mode is "in". Predicates do not have a default mode or a default determinism,
> so this does not apply to them.
> 
> Zoltan.



More information about the users mailing list