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

Peter Schachte schachte at csse.unimelb.edu.au
Wed Jan 31 14:19:17 AEDT 2007

Julien Fischer wrote:

> Going back to the above proposal (and since we seem to be optimising for
> the common case), there's a fairly good argument for making !(X) mean
> unique >> dead, free >> unique given that probably the most common use
> for state varaibles is for threading the I/O state.

I would expect they'd also be used for all kinds of accumulators, like
counters, lists, etc, which would mostly be ground, not unique.

>> 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.
> I don't think of state variables that way: they are a sequence of values,

That sounds pretty much like what I'm saying.  So if you see !Var as a sequence
of values, why do you want to think of it in terms of the implementation as
pairs of variables?  And if you're not thinking of it as pairs of variables,
why do you want to be forced to think of pairs of modes?

>> 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).
> Even leaving uniqueness aside I don't see that there needs to be a single
> instantiation state.  It is perfectly reasonable for subtype information
> to be change through a sequence of operations (and the type to remain
> unchanged).

... Just as the type may change through a sequence of operations.  But we're
just discussing syntactic sugar; it should handle the common cases elegantly
and succinctly.  Other cases can be handled in unsweetened form.  How many
predicates have you written using state variables that change instantiation as
they evolve?

>> 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
> Not quite, you can specify (mode, mode) in the list of modes but it is just
> flattened out.

OK, so you can write parentheses around an adjacent pair of modes.  This has no
semantics, just some documentation value.  But since the compiler can't check
it in any way, it's not reliable documentation.  That's why I prefer the idea
of allowing Type::(Mode1, ..., Moden) as an abbreviation for Type::Mode1, ...
Type::Moden:  at least it doesn't appear to have a semantics the compiler
cannot check at all.  It's also more useful.

>>     predmode declarns:    !Type::(Mode, Mode)
> To which you can add:
>      typeclass method decls of various sorts - as above
>      lambda expressions
>      mode-specific clauses
>      foreign_export pragmas - maybe

AFAICS, these are all covered by the syntax I proposed.  I'll comment on
lambdas below.

>>     Note that nothing stops you from writing, eg:
>>         :- pred append(!list(T), list(T)).
>>         or    :- pred append(!list(T)::(in, in), list(T)::out).
> In that case the difficulty of writing the corresponding clauses
> for append with that particular arrangment of state variables might
> soon give me pause for thought.

Not at all.  The compiler would accept this with your preferred syntax:

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

	append([], !V).
	append([H|T], !V) :-
		append(T, !V),
		!:V = [H|!.V].

The equivalent of that pred declaration with my proposal would be:

	:- pred append(!list(T)::ground, list(T)::out) is det.

which the compiler would not accept because the mode doesn't match the code.
My syntax is more restrictive, so it would catch more errors.  Personally, I'd
advocate allowing state variable notation in clause heads only where they're
declared in pred declarations, and vice versa.

> Previously (and in the current proposal), :: is always followed by a mode
> or a 2-tuple of modes, with your proposal I now have to switch my
> thinking between modes and insts depending on whether the argument I'm
> looking at is a state variable pair or not

Yup.  With your approach, the right side of a :: could be one mode or two, ie,
two insts or four.  With my approach, it's two insts or one.  With your
approach, you know it's something different because you've got two things
there; with mine you know it's different because you've got an inst instead of
a mode.  With your approach, you have to specify the modes of the two arguments
that you are forced to think of state variables as; with mine, you specify the
inst that each value of the state variable must have.

> Actually, what I'm looking for is way of simplifying the state variables
> in the heads of labmda expressions, e.g.
>      P = (pred(X::in, !IO::(di, uo)) is det :-
>          ...
>      )

Easy peasy:  P = (pred(X::in, !IO::unique) is det :- ... )

Peter Schachte              The government of the United States is not, in
schachte at cs.mu.OZ.AU        any sense, founded on the Christian religion.
www.cs.mu.oz.au/~schachte/      -- George Washington, 1796
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