[m-rev.] for review: state vars syntax sugar

Peter Schachte schachte at csse.unimelb.edu.au
Thu Feb 1 11:24:17 AEDT 2007


Julien Fischer wrote:

>> How
>> many
>> predicates have you written using state variables that change
>> instantiation as
>> they evolve?
> 
> Not that many at the moment; the extra work required to workaround
> limitations in the current mode analyser's support for subtyping makes
> it too
> much work.  If that weren't the case I could see myself using them more.

This calls to mind the scene in Monty Python's Meaning of Life:

Protestant husband:  That's why it's so much better to be Protestant:  we can
use birth control.  Catholics have to have a baby every time they have sex.

Protestant wife:  So have we.  Two children, ....

Protestant husband:  That's not the point!

> You can abuse most syntax if you try hard enough, e.g.
> 
>     :- pred foo(!list(T)::ground, !list(T)::ground) is det.
> 
>     foo(!.X, !:Y, !.Y, !:X) :-
>         ....
> 
> doesn't really correspond to the spirit of what you are proposing.
> and yet your proposal doesn't disallow that.

No, I would prefer if that weren't allowed.

>> Personally, I'd advocate allowing state variable notation in clause heads
>> only where they're declared in pred declarations, and vice versa.

Please note that I'm not proposing that.  I know it's much too big a leap to
sell here.  I'm just saying I believe ! notation should be considered to be
something separate from ordinary notation, and that it should be used
consistently between clause heads and pred and mode declarations.  But I'm not
trying to sell that point.

> That's a little unclear.  What happens in the situation where there
> is a single state variable in the clause head rather than a state
> variable pair?
> 
>     :- pred foo(counter::in, T::in, T::in, T::out) is det.
> 
>     foo(!.C, X, Y, Z) :-
>         do_something(X, !C),
>         do_something(Y, !C),
>         do_something_else(Z, !.C).

That's pretty confusing.  To do what you're doing here, I would have written

	foo(W, X, Y, Z) :-
		!:C = W,
        	do_something(X, !C),
		do_something(Y, !C),
		do_something_else(Z, !.C).

And then of course I would expect I could replace W in the clause head with !:C
and remove the unification goal.  That's just normal "substitute equals for
equals."  So I would have expected the clause head to have !:C rather than !.C.

But to answer your question, !.Var and !:Var are values (though different
values in different places in the clause), they're not actually state variables
because they can't be updated.  So I think it's OK for !:Var to appear in a
clause head, signifying the initial value for the state variable in that
clause.  So I would say this should be declared as an ordinary type and to have
an input mode.  And !.Var should be able to appear in a clause head, signifying
the final value of the state variable in the clause, and again it should be
declared as a single type and an output mode.

> Also, if as you suggest, state variable notation in a clause head
> must have a corresponding declaration in the pred decl then which
> of the proposed syntaxes are you proposing to use: yours adds a bunch
> of restrictions that aren't currently there.  Now we can't even
> express the corner cases that the unsugared syntax allows.

Yes, that's why I'm not trying to sell so strict a view.  Really what I'm
trying to sell is the idea that state variables can have an intuitive semantics
other than the one that requires you to think of it in terms of the translation
to lots of separate variables.  Personally, I wouldn't use state variable
notation where you need to change the type or inst.  I think there's much more
benefit to having an intuitive semantics to state variable notation, and to
knowing that state variables can't change type or inst, than is lost by being
unable to use them for a few corner cases I don't envision arising very often.

> Modes and insts are distinct at the syntatic level, with your approach
> it is one *mode* or one *inst*.  (At the very minimum I would want the
> operator before the inst to be something other than :: ).

I figured !(Type::Inst) looked different enough from Type::Mode; that the ! and
the parentheses visually flagged it well enough.  If not, then using
!Type::!Inst (and allowing !Type :: !Inst) is probably better, as it avoids the
need for more parentheses.

> State variables are two arguments.  What would you say the arity of the
> following clause is?
> 
>     p(A, B, !C).
> 
> (If your answer is three then you'll find compiler disagreeing with you
> when you try to attach a pragma to it that explicity mentions the arity.)

Yes, that's a fair point.  Users will have to be told that every ! argument
really counts as two.  That's a bit unpleasant, but bearable.

Although, we all know that the *real* arity of p is probably not 3 or 4, as
there will be some hidden arguments.  But Mercury successfully hides them, and
makes people believe the arity is 4.  It could do the same with state variable
arguments.

> For something a little less easy peasy:
> 
>     DeleteBars = (pred(!X::(in(list_skel(foo_or_bar)), out(list_skel(foo)))
>             is det :-
>         ...
>     )
> 
> And I don't see why I should be forced to use the unsugared version just
> because I'm doing something a little unusual with the insts here.  IMO,
> the above is an improvement over what I am currently required to put
> (and what your proposal requires me to put).

I really don't see that what you wrote above is much better than

    DeleteBars = (pred(X0::in(list_skel(foo_or_bar), X1::out(list_skel(foo)))
        is det :-
    ...
    )

It's very slightly shorter; three characters by my count.  But yours has an
extra pair of parentheses, which I find makes code harder to read (compared to
not needing them at all).  But in the common case where the initial and final
insts are the same, you still have to write

    DeleteBars = (pred(!X::(in(list_skel(foo)), out(list_skel(foo))) ...

where I get to write

    DeleteBars = (pred(!X::!list_skel(foo)) ...

That's a big enough difference to care about.

-- 
Peter Schachte              It is a miracle that curiosity survives formal
schachte at cs.mu.OZ.AU        education.
www.cs.mu.oz.au/~schachte/      -- Albert Einstein
Phone: +61 3 8344 1338
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list