[mercury-users] list functor style functions

Michael Day mikeday at corplink.com.au
Fri Nov 12 12:38:23 AEDT 1999


> I would suggest putting them into to separate type classes.  There may
> be collections you can deconstruct one element at a time but not
> construct that way, or vice versa.  Or you may be able to do both, but
> not the same way.  Eg, a set: it certainly makes sense to traverse a
> set one element at a time (say, in lexicographic order).  It also
> makes sense to build up a set one element at a time.  However, these
> are not inverses unless you can guarantee that the set will be
> constructed in (reverse) order.

I'm thinking I might play around with versions of these functions that
look less like lists, to avoid confusion if they have a very different
meaning. Making lists a special case of something else could be more
fruitful than making everything else a special case of lists?

> Here's a tough question about the current type class implementation
> (and about what other languages' type class systems do):  if I define
> input_sequence and output_sequence type classes to each have the
> approriate (dual) modes of these functions, can I then define sequence
> to be just these two classes, *and* have Mercury require that these
> two pairs of functions be the identical, but with different modes?
> Ie, a sequence type can not only add and remove an element, but these
> two operations are forced to be duals because they're just different
> modes of the same function?  That would be pretty cool.

This seems rather dependent on the point below concerning different
implementations for different modes, for instance an iostream with
identical syntax for reading and writing still has to call either read()
or write() somewhere in its implementation depending on the mode.

> This idiom in the library has always irked me because it discourages
> reuse-through-reversibility.

The one case where it appears justified is in the graph module:

        % graph__init(Graph) binds Graph to an empty graph
        % containing no nodes and no arcs. (The graph contains
        % a counter of the number of nodes allocated in it, so
        % it is possible for a graph to contain no nodes or arcs
        % and still fail to unify with the binding of Graph from
        % graph__init.)

If I'm reading that correctly, it would be hard to make a single predicate
that both created an empty graph and checked if an existing graph was
empty. I'm guessing it would be this way for other complex types also.
This still feels annoying however, as it would work for an awful lot of
other types.

> Sure you should; I don't think that should be controversial.  No one
> should be surprised if the best algorithm to compute some relation is
> different in different modes.  The only controversy should be over
> what to do about the possibility that the code you write that you
> implicitly assert just computes different modes of the same relation
> in fact computes different relations.  I'd argue that the benefit of
> this flexibility outweighs the danger, but I can see why some might
> disagree.  (Actually, as you point out, this is possible now via the C
> interface, it's just very unpleasant and inefficient.  This is another
> argument for supporting it directly).

The sine example is not perfect as it is just a wrapper for a C function
anyway, but it was the first thing I thought of when browsing through the
maths module, thinking reversible functions should be just that.

The empty/init example is a little better, as it should not require the
involvement of the C interface at all, but I'll look at the source for
graph before commenting on that.

I'm assuming it wouldn't hurt the implementation of the compiler that much
to support multiple implementations, as currently it generates them itself
automatically, one for each mode declaration correct? But the syntax would
probably need to deviate from its current garnished Prolog mentality, to
specify which mode a particular clause body referred to (there really
isn't enough information to infer modes in this case, is there?)

As to whether you could create two completely different relations with the
same name but different modes, I guess you could :) Would that break any
declarative semantics that Mercury programs must uphold, or would it just
mess with the programmer's mind if there is a bug in one mode of a
multiple moded predicate and they try to track it down?

Michael


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