[m-users.] IO argument clobbering

Zoltan Somogyi zoltan.somogyi at runbox.com
Tue Jul 18 01:34:36 AEST 2023


On 2023-07-17 17:26 +02:00 CEST, "Sean Charles (emacstheviking)" <objitsu at gmail.com> wrote:
> [A]  :- type callback == (pred(world, world, io, io)).
> [B]  :- inst callback == (pred(in, out, di, uo) is det).
> 
> [C]  :- pred run_loop(
>       callback::in(callback), world::in, world::out, io::di, io::uo
>   ) is det.
> 
> In an attempt to demystify it all then, at point [A] I am defining an equivalence type which is merely a Mercury way of defining something similar to a C preprocessor macro in that the use of callback *as a type* specified will just cause the compiler to use the value on the right hand side of '=='. That much I understand, I think!
> 
> At [B], I am defining an instantiatedness tree, that although it has the same name as that used at [A], bears no actual relationship to it in any way.
> 
> At [C], I am declaring that run_loop/5 is a predicate that takes an argument of *type* callback, and that that it is an input, and that the input MUST have the instantiatedness defined by the definition at [B], the first use of callback being the type, and the in(callback) is stating that the value MUST be ground i.e. contain no free variables.
> 
> Is that not even wrong, or close?

What you write above is exactly right.

Note that giving a type and an inst the same name is just a naming
convention. It is useful in that it tells people who are familiar with
the convention that the type and the inst are expected to be used together.
However, it does have the drawback that it can, and often will, confuse
people who are not familiar with the convention, and who don't know
that when the name (such as "callback" in this case) is used in a context
where the compiler expects a type, it will be interpreted as the name of
the type, whereas in contexts where the compiler expects an inst,
it will be interpreted as the name of the inst.

Zoltan.


More information about the users mailing list