[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