[m-rev.] for post-commit review: better diagnostic for missing higher order insts

Zoltan Somogyi zoltan.somogyi at runbox.com
Fri Jul 21 02:06:11 AEST 2023


On 2023-07-20 09:08 +02:00 CEST, "Peter Wang" <novalazy at gmail.com> wrote:
> As far as I'm aware, the language only allows higher order inst info in
> the argument type of a du type definition. I don't think it's completely
> obvious to allow higher order inst info elsewhere, so I wouldn't call
> it a compiler limitation but a question of language design.

I agree it is a question of language design. I also thought that we agreed
on that extension a fair while ago. I don't recall to what extent, if any, it was
actually implemented.

> I consider the solution of keeping the higher order value within a term
> of a bespoke du type "pretty good".

As do I.

> We don't have to mention it in the
> error message though.

Agreed. In an error message about a predicate-valued variable
that was passed on its own, talking about predicate values inside
data structures would be misleading.

What follows is my attempt to incorporate the suggestions in
this email thread in the text of the message.

  In clause for `run_loop(in, in, out, di, uo)':
    in argument 1 (i.e. the predicate term) of higher-order
    predicate call:
    mode error: context requires a predicate of arity 4.
    The type of AppHandler does match that expectation. However,
    to check the correctness of the call, the compiler also needs
    to know the modes of the arguments, and the determinism, of
    the predicate that AppHandler represents. The insts of
    higher order values should contain this information,
    but AppHandler's inst, which is `ground' at this point, does not.

    The fix for this error is to add this information.
    For example, given a higher order type such as
      :- type callback_t == (pred(world, world, io, io).
    you would define a corresponding inst, such as
      :- inst callback_i == (pred(in, out, di, uo) is det).
    This inst, which usually called a higher order inst,
    specifies the modes of the arguments and the
    determinism of a predicate. Search for `higher order inst'
    in the Mercury language reference manual for a corresponding
    example for functions.

    You can then tell the compiler that a value of type callback_t
    has inst callback_i by specifying either the mode `in(callback_i)'
    (when taking a value of type callback_t as input) or the mode
    `out(callback_i)' (when returning a value of type callback_t as output).

The blank lines and indentation are intended to represent
the final product; the line wrapping is incidental, and will probably
differ in the final product.

This text includes "higher order inst" and recommends its use
as a search term, but I propose that we include that sentence in the
error message only when it actually finds something useful.
At the moment, the refman contains only two matches, both
in the same sentence, when it describes that the higher order insts
must match between a subtype and its supertype.  Even the section
that is intended to discuss inst/mode info for higher order values,
section 8.3.1, does NOT actually say what higher order insts ARE,
because it is focused on higher order MODES. That looks like a big
omission, which may be one cause of Mercury users' lack of
understanding of this issue. I will propose some fixes for the refman soon.

Zoltan.


More information about the reviews mailing list