[m-users.] Existential higher-order type

Volker Wysk post at volker-wysk.de
Wed Oct 12 03:48:16 AEDT 2022


Am Dienstag, dem 11.10.2022 um 21:49 +1100 schrieb Zoltan Somogyi:
> 
> 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.

Hmm... I'm trying to get the compiler to delete such a call, but it doesn't,
even with the "-O6" parameter:

:- pred wirf(int::in) is det.

wirf(I) :-
    ( if I < 0 then throw("Geworfen.")
               else true ).

main(!IO) :-
    wirf(-1).

> *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.

This seems to make sense...

> 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.

How would you define such a predicate with no output argument, that does
nothing but throw an exception, depending on its input? If you want to use 
exceptions?

I've taken a peek at the "Impurity declarations" chapter of the Language
Reference Manual and tried this:

:- impure pred wirf(int::in) is det.

But the compiler says: "warning: declared impure but actually pure.". And I
needed to promise main to be pure, what might not be the case (I don't fully
comprehend).

Would it work to define a dummy output argument, or could this optimized
away as well?

> 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.


Bye,
Volker
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <http://lists.mercurylang.org/archives/users/attachments/20221011/43ae787e/attachment.sig>


More information about the users mailing list