FW: [mercury-users] Records

Peter Schachte schachte at cs.mu.OZ.AU
Fri Nov 5 17:34:23 AEDT 1999


n Wed, Nov 03, 1999 at 03:29:29PM +1100, Simon Taylor wrote:
> One other idea I had was that one of the reasons for making a field private
> is that there is an invariant on the field that must be checked on
> each update. It would be a shame to have to use different syntax for
> updating such fields. One way to fix that would be allow the user
> to override the field update function.
> 
> 	:- module foo4.
> 	:- interface.
> 	:- type t4
> 		---> t4(
> 					% field1 must be positive.
> 			field1 :: int where set is set_field1,
> 			field2 :: int
> 		).

On Wed, Nov 03, 1999 at 03:35:30AM -0800, Ralph Becket replied:
> However, this is all starting to niggle my sense of aesthetics.  Perhaps
> the best thing to do is to just keep it simple and write out the special
> cases by hand.  Hmm...

Actually, I think something like what Simon is proposing is really
necessary.  

The current approach to civilized handling of ADTs in Prolog/Mercury
is to define an abstract type with some accessor and setter
functions/predicates.  One aspect of this approach which we should be
careful not to lose is that code written this way can cope with a
field in the record being removed (as long as the information can be
recovered) by redefining the accessor and setter for that field to
compute the information.  It is very important that this can be done
without affecting any other modules.  If a field access syntax with
the ability to redefine accessors/setters is developed, it means
that even truely abstract data types can specify and export
accessors.  It also means that there is a single syntax that can be
used to access (conceptual) fields of a data structure, whether that
data structure is abstract or not.

However, I think there's a simpler way to achieve what Simon is after,
and provide some other benefits along the way.  Let's consider
semantics first, and then I'll sprinkle on a little syntactic sugar.

For a type t with a field f, where f has type v, an accessor for f is
really nothing but a function f: t -> v, and a setter is just a
function f: t -> v -> t (I'm using Mercury's overloading ability here
to let me use the same name for the accessor and setter).

My proposal is to just let it go at that: use ordinary functions as
accessors and setters, and have field names in type declarations just
generate those functions automatically.  If the type declaration is in
an interface section, the generated functions are public, otherwise
not.  But one can always put a type declaration in the implementation
section, and add function declarations for (some of) the accessors and
setters in the interface section.  Thus issues of public and private
can be handled as usual by the module system (as it should be).
Removing a field from a type can be handled by just defining a new
public function with the right name.

On to syntax.  For concreteness, I'll use `Value = Variable @ field'
for accessors, and `Newterm = Variable @ field := Newvalue' for
setters, but this can be adapted to other syntaxes.  If an accessor is
just a function f: t -> v, then all Mercury has to do to support `Var
@ field' syntax is translate `X @ Y' to `Y(X)'.  Of course, we'd want
the `@' operator to associate to the left.  Easy.

Handling `:=' is a little harder.  We need to expand f(X) := Y (where
X is not a function application) to f(X,Y).  But that won't handle
things like Foo @ bar @ baz := Zip properly.  For this we also need to
expand g(f(X)) := Y to what f(X) := g(f(X), Y) expands to, for any X
(including function applications).  It seems a bit confusing, but
users really don't need to understand that, and I don't think it
should be very hard to implement, if the transformation is done at the
right point in the compilation.


-- 
Peter Schachte                     Keeping the unrich gruntled constantly
mailto:schachte at cs.mu.OZ.AU        occupies our two political parties.
http://www.cs.mu.oz.au/~schachte/      -- Russell Baker 
PGP: finger schachte at 128.250.37.3  
--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the users mailing list