[m-dev.] Re: bug in scoping for higher order terms

Fergus Henderson fjh at cs.mu.OZ.AU
Sun Mar 7 18:14:03 AEDT 1999


On 07-Mar-1999, Peter Schachte <schachte at cs.mu.OZ.AU> wrote:
> On Sat, Mar 06, 1999 at 03:06:10AM +1100, Fergus Henderson wrote:
> > If so, what about this example:
> > 
> > 	p(A, B, C, P) :-
> > 		q(A, B, C),
> > 		P = (func(A::in, B::out) = (C::in) is semidet :- A+B=C).
> 
> Yes, I agree this question is harder, because the intuition about
> functions written in a sort of relational form is not well developed.
> My intuition is basically that any variables appearing in "the thing
> being defined" should be scoped to the definition (to do otherwise
> really makes no sense), while other variables appearing in the
> definition should be scoped to the larger clause (to scope them
> tighter than that would be too restrictive, making closures pretty
> much useless).  In this case, the problem is that "the thing being
> defined" at first would appear to be func(A,B), but on closer
> examination seems to be forced to be func(A,B) = C.  This view is
> unfortunate because cases like the one originally reported become
> clumsier than they should be.

Yes.

> The difficulty for me is that I'd like to be able to write things like
> 
> 	C = ...,
> 	Addconst = (func(A) = A+C)
> 
> If I correctly understand the types/modes problem presented by
> closures, Mercury can't support this, because I must include modes and
> determinism for the func.  Is that right?

No.  If you don't specify the mode and determinism for a func,
they default to `func(in, in, ..., in) = out is det'.
So they above code is perfectly legal.

It's also possible to specify the modes, even though you
use a complicated expression for the arguments and/or
return value, rather than just a variable.  For example:

 	InverseAddconst = (func(A::out) = ((A+C)::in) is det)

...
> the intuitive rule (to me) is more complicated: If there is a `:-' in a
> func closure, then variables appearing left of it are scoped to the
> closure; otherwise, variables appearing left of the `=' are scoped to
> the closure.

I don't like that rule very much.  It means that `func(A) = B'
is not the same thing as `func(A) = B :- true', which I find rather
unintuitive.

> > Perhaps we should just say that variables in a lambda expression
> > are *never* distinct from variables occurring outside; that would
> > mean that if you want a fresh variable, then you must use a
> > different variable name.
> 
> That's a pretty unnatural rule for both preds *and* funcs.  It'll
> probably bite people less often than the current rule (because people
> will naturally tend to use different variable names for head variables
> in closures), so perhaps it's an improvement.  Still, despite the
> greater complication, the second scoping rule for funcs I suggested
> just above seems more intuitive and less error prone.  If that rule
> seems too complicated to you, I suppose an alternative intuition is
> that, in a function, `:-' is pronounced `where', and so "the thing
> being defined" is always what's left of the `=', and everything right
> of the `=' is scoped to the enclosing clause.

This is much closer to my natural intuition.

I think this is probably the right thing to do.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.



More information about the developers mailing list