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

Peter Schachte schachte at csse.unimelb.edu.au
Tue Jan 30 14:03:29 AEDT 2007


Julien Fischer wrote:

>> Touché!  And for the X>>dead mode, doesn't X have to be unique?
> 
> It makes sense for it to be dead, however the current implementation
> doesn't complain if it isn't unique (which is almost certainly a bug).
> Actually, in a funny way, it makes sense to be able to define the mode
> X >> dead
> where X is not unique, but not to actually use it anywhere.

I thought 'dead' meant "there are no references to this term anywhere"?  If so,
you can't know there are no references to it unless you know there are no
references to it outside the arguments to this call.

>> If that covers all useful cases, how about this for a syntax:
>>
>>  !(X)                 means X>>X, free>>X
>>  !destructive         means unique>>dead, free>>unique
>>  !mostly_destructive  means mostly_unique>>mostly_dead,
>> free>>mostly_unique
>>  !input(X)            means X>>X, X>>X
> 
> I think !input(X) is badly named.  After all !input(free) is really just
> (unused, unused).

You know, I really can't imagine when you'd ever use !input(X), so drop it.  I
was worried about trying to make this comprehensive, but it really doesn't have
to be.  It's just syntactic sugar.  If you want (in, in), just write it.

 > I have a few problems with the inst based proposal as it stands:
> 
> (1) it has a much higher syntatic overhead than the mode based one
>     in which I only had to remember one piece of syntax; I now have
>     to remember five or six new pieces.

I don't think it's quite that bad.  Most of it is pretty intuitive after you
get the basic idea.  The conceptual shift is that you think of a state variable
!Var as specifying a value that changes throughout the execution of the clause,
rather than as a different pair of variables every place it appears, with the
variables threaded together in a certain way.  Then !.Var denotes the current
value, and !:Var specifies a new value, for that state variable.

With that view, it makes sense for it to have a single type and a single,
consistent instantiation state (rather than the confusion of 4 instantiation
states).  There is a catch with uniqueness that the final inst of the input
must be dead, requiring a special case.  But let's get rid of the !destructive
notation I specified before and just make !unique and !mostly_unique "do the
right thing" by forcing the final inst of the input to be dead.  And while I'm
simplifying, let's drop the !backwards(Inst), because I really doubt it'll ever
be used.  With those changes, and dropping !input(Inst), there's only !Type,
!Inst, and !(Type::Inst).  Now I think it's conceptually simpler than the other
proposal.

> (2) it isn't as future proof as the mode based one, it's eventually
>     going to have be extendend to handle (mostly-)uniquness and
>     subtyping, e.g !destructive(X) means unique(X) >> dead etc ...
>     (or however we end up denoting that.)

I think the previous paragraph fixes that.

> In the end I think a better proposal would be to separate that
> subtype and uniqueness apects as Mark suggested somewhere (on this
> thread?)

Absolutely.  I'd very much like to see modes specified in terms of what a call
does to the instantiation of the arguments, rather than what the initial and
final insts are.  But that's a topic for another day....

> (3) I cannot use the inst based syntax to encode a change of uniqueness,
>     which is trivial to do with the mode based one, e.g.
> 
>   :- pred do_complex_op_and_make_unique(!foo::(in, uo)) is det.
> 
>   do_complex_op_and_make_unique(!Foo) :-
>     op_part1(!Foo),
>     ...
>     op_partn(!Foo),
>     make_unique(!Foo),
>     do_more_stuff(!Foo).

That's a feature, not a bug.  You also might want to change *types* in a goal
(eg, from an association list to a map), and my syntax doesn't allow that
either.  I note that your preferred syntax inconsistently allows the inst to
change, but not the type.  But if a state variable changes type or
instantiation state, then it can't just be called anywhere.  You divide preds
that use that state variable into three classes:  those that use the first type
or inst, those that use the second, and those that transform from one to the
other.  I think you're much better off *not* using state variable notation in
such cases, at least not for the predicates that do the transformation.

So let's compare the proposals.  The current proposal, as I understand it:

	pred declarations:	!type specifies types of two arguments
	mode declarations:	no support; must specify two modes
	predmode declarns:	!Type::(Mode, Mode)

	Note that nothing stops you from writing, eg:

		:- pred append(!list(T), list(T)).
	    or	:- pred append(!list(T)::(in, in), list(T)::out).

My updated proposal:

	pred declarations:	!type specifies type for a state variable
	mode declarations:	!inst specifies instantiation of a state var
	predmode declarns:	!(type::inst) specifies type and inst for
				state variable

If you find it annoying, as I do, that pred and mode declarations specify two
types and modes for a predicate when the call looks to only have one, then I
think my proposal works better.  If, OTOH, you're just looking for a way to
save yourself from having to repeat type specifications over and over in pred
and predmode declarations (that's the only benefit I see from the current
proposal), then the following 2 changes, taken together, are more widely
applicable and seem simpler than the current proposal:

	In a predmode declaration, allow Type::(Inst1,... Instn) as an 		abbreviation
for Type::Inst1, ... Type::Instn.   Eg, :- pred append(list(T)::(in, in, out)).

	In a pred declaration, allow N * Type, where N is an integer, as an
abbreviation for N repetitions of Type.  Eg:  :- pred append(3 * list(T)).

-- 
Peter Schachte              There never has been, nor will there ever be,
schachte at cs.mu.OZ.AU        any programming language in which it is the
www.cs.mu.oz.au/~schachte/  least bit difficult to write bad code.
Phone: +61 3 8344 1338          -- Lawrence Flon


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