[m-rev.] for review: state vars syntax in language reference

Jonathan Morgan jonmmorgan at gmail.com
Mon Jan 29 22:35:22 AEDT 2007


On 1/29/07, Ondrej Bojar <obo at cuni.cz> wrote:
> After the last explanatory mail from Peter (Schachte), I blindly adopted
> his view. Here is a proposal of changes to the reference manual for
> sweetening state vars modes.
>
> Breaking the link between syntax and semantics, I interpret
> "!type::svmode" as "!(type::svmode)", although the parse is different
> given current priorities.

This proposal moves further away from our current situation.  In many
ways I would prefer a simple !type::(mode1, mode2) declaration, though
I think this suggestion is undoubtedly clever.

> I have also included the proposal of "pure functions with side effects"
> with all the dangers these can bring (I am aware only of
> compiler-dependent order of evaluation), so please reject this section
> separately from the main part.

As state variables imply ordering, this either introduces order of
evaluation problems, or requires users to stick to one function
application per line, in which case you have not improved much on
predicates.  I think that the change to state variable modes is a good
idea, but I'm not so keen on this one (I do think that it would be
somewhat appropriate for dummy types like IO, as they do not exist in
the final code - but that is really overly implementation minded).

> I am attaching the diff twice, in the body and as an attachment, because
> I am afraid of line wrapping problems.
>
> Cheers, Ondrej.
>
>
> Index: reference_manual.texi
> ===================================================================
> RCS file:
> /home/mercury/mercury1/repository/mercury/doc/reference_manual.texi,v
> retrieving revision 1.379
> diff -u -r1.379 reference_manual.texi
> --- reference_manual.texi       15 Jan 2007 02:23:58 -0000      1.379
> +++ reference_manual.texi       29 Jan 2007 07:41:42 -0000
> @@ -937,13 +937,9 @@
>    condition and then-goal of the if-then-else expression, hence
> @samp{!:@var{X}}
>    may appear therein.
>
> -There are three restrictions concerning state variables in lambdas: first,
> - at samp{!@var{X}} is not a legitimate function result, since it stands
> for two
> -arguments, rather than one; second, @samp{!@var{X}} may not appear as a
> -parameter term in the head of a lambda since there is no syntax for
> specifying
> -the modes of the two implied parameters; third, @samp{!@var{X}} may not
> appear
> -as an argument in a function application since this would not make
> sense given
> -the usual interpretation of state variables and functions.

At a very minimum I would disallow state-var pairs in the result of a
function.  I suspect that it would be better to avoid state variables
in function application altogether, though having them in the head of
a lambda is a useful syntactic shortcut.

> +Special syntax for has been introduced to simplify predicate and
> function mode
> +declarations for state variables (@pxref{Predicate and function mode
> +declarations with state variables}).
...
> @@ -2819,6 +2816,95 @@
>
>    The mode analysis algorithm annotates each call with the mode used.
>
> + at node Predicate and function mode declarations with state variables
> + at section Predicate and function mode declarations with state variables
> +
> +Type and mode declarations for predicates and functions that use state
> +variables (@pxref{State variables}) can be simplified.

While this proposal largely reuses the syntax of state variables, it
is still applicable to all predicates that thread state in this way,
though I would consider state variables the preferred way of doing
this.

> +
> +For instance, imagine a predicate
> + at example
> +       :- pred foo(int::in, int::out) is det.
> + at end example
> + at noindent
> +that is typically called using a state variable, i.e. as
> @samp{foo(!@var{Var})}.
> +Without using the standard mode shortcuts, the predicate declaration
> would be:
> + at example
> +       :- pred foo(int::(ground>>ground), int::(free>>ground)) is det.
> + at end example
> + at noindent
> +
> +Making use of the chain introduced by state variables where the final
> +instantiatedness of the first argument must match the initial
> instantiatedness of the
> +second argument, we can omit the intermediate instantiatednesses and
> declare the
> +type and mode of both input and output arguments at once:
> + at example
> +       :- pred foo(!int::ground) is det.
> + at end example
> +
> +Note that the scope of the bang (@samp{!}) semantically covers both the
> type
> +and the mode declaration. If the type and mode declarations were to be
> written
> +separately, the bang would appear twice:

The "bang" does not appear elsewhere in the reference manual (though
it does in the compiler).  Is this the best way of describing the
symbol?

> +
> + at example
> +       :- pred foo(!int).
> +       :- mode foo(!ground) is det.
> + at end example
> +
> +The following table summarizes all defined @dfn{state variables modes}:
> +
> + at example
> +!(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
> +!backward(X)         means B, A if !(X) means A, B
> + at end example
> +
> +The most common state variable modes are thus:
> +
> + at example
> +!ground         for ground>>ground, free>>ground   which corresponds to
> modes    in, out
> +!destructive    for unique>>dead, free>>unique     which corresponds to
> modes    di, uo
> + at end example
> +
> +The @samp{!backward(X)} mode is intended for cases where the state variable
> +chain is used ``backwards'', i.e. with input argument being the second
> one and
> +output being the first.
> +
> +Same syntax can be used for state variables appearing as function input
> arguments:

s/Same/The same

> + at example
> +       :- func bar(!int::ground) = (int::out) is det.
> + at end example
> + at noindent
> +with the function being called as e.g. @samp{Out = bar(!State)}. This
> syntactic
> +construction thus allows a pure account for defining and calling
> ``functions
> +with side effects''. State variables can not appear as the output
> argument of a
> +function because they in fact encode a pair of arguments.
>
> +
> +For convenience, if all normal (stateless) arguments to a function appear
> +without a mode declaration, the default @samp{in} mode is assumed for input
> +arguments and @samp{out} is assumed for the output argument. A function
> +declaration thus in most cases needs to mention only state variable modes.

I'm not sure that this would be the most common mode pair (the other
contender being di, uo).  However, this probably fits best with the
current implied modes for functions.

The last sentence doesn't sound quite right.  The current compiler
does not allow a function to specify modes for only some parts of a
function, whereas your sentence seems to suggest that modes need only
be specified for state variable modes.

> +
> +Lambda expressions (@pxref{Lambda expressions}) can also use the state
> variables modes defined here.
> +E.g.

I'd prefer "For example: ".

Jon

> + at example
> +pred(!StateVar1::StateMode1, Var2::Mode2, ...) is Det :- Goal
> + at end example
> + at noindent
...
--------------------------------------------------------------------------
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