[m-users.] Existential higher-order type

Zoltan Somogyi zoltan.somogyi at runbox.com
Tue Oct 11 21:49:48 AEDT 2022



On Tue, 11 Oct 2022 12:38:18 +0200, Volker Wysk <post at volker-wysk.de> wrote:
> Am Dienstag, dem 11.10.2022 um 19:27 +1100 schrieb Mark Brown:
> > I assumed you _weren't_ doing that. I think the reference manual
> > leaves this behaviour unspecified if a det predicate has no outputs
> > (i.e., it doesn't require that the exception is thrown), so that would
> > mean your code doesn't say what you intend it to, or the reference
> > manual doesn't say what we intend it to. Either way, I'd avoid it
> > personally.
> 
> Could someone who knows how it is, please clarify this?
> 
> I thought the compiler would keep track of which parts can throw an
> exception. There's the "erroneous" determinism category for such parts...

A predicate with the signature "pred(in) is det)" has no outputs,
and its determinism says it succeeds exactly once. This means that
it has no effect on the rest of the computation at all. When the
optimizer sees such a call, it is allowed to delete it, and it *will*
delete it at most optimization levels.

*If* the predicate's signature were "pred(in) is erroneous",
the compiler would know not to delete it.

The idea is that the compiler will preserve exceptions that you encounter
in the process of trying to compute some result, but won't even try to
preserve exceptions in computations that have no visible result.
An output argument, being declared erroneous, and being declared
impure are three different ways to tell the compiler "I am computing
something you cannot see", but the code Mark was talking about
contains none of these things.

As for the compiler keeping track of "which parts can throw an exception",
this won't work in the case of the predicate involved being defined
in another module, and it *can't* work without doing some kind of
whole-program analysis, which the Mercury compiler does not do.

Zoltan.


More information about the users mailing list