[mercury-users] Higher order programming

Peter Schachte schachte at cs.mu.OZ.AU
Mon Apr 26 09:33:33 AEST 1999


I agree with Lee that the interface between the functional and
relational parts of Mercury could be smoother.  But I disagree with
his suggestion to make functions single-moded versions of predicates
with one fewer argument.  I have two specific objections, aside from
the knee-jerk "this seems a bit of a hack" reaction.

Firstly, as Fergus pointed out to me, there are two different views of
the relationship between functions and predicates.  The view you're
taking is that functions are relations in which one of the arguments
is uniquely determined by all the others.  That's a perfectly
reasonable view for a logician.  The other view is that a predicate is
just a function which returns a bool, and this is a perfectly
reasonable view for a functional programmer.  In fact, I'd argue that
the inconvenience for functional programmers of Mercury not taking
this view is much greater than the inconvenience to logic programmers
of it not taking your view.  I believe a functional programmer should
be able to write functional programs in Mercury without needing to
learn Mercury's relational syntax, if she doesn't need backtracking.
But unfortunately the distinction between predicates and functions
returning bool means, eg, you can't define:

	:- func small(int) = bool.
	small(N) = N < 10.

unless someone goes off and defines a whole raft of predicates as
functions returning bool.  More seriously, if you manage to define the
small/1 function (predicate), you still can't write

	if small(X) then ... else ...

because the if-then-else functional form expects a predication for its
condition.

My second objection to Lee's suggestion is that I believe reversable
functions are potentially a very useful feature, especially with type
classes.  In fact, I would like to see Mercury move toward removing
the distinction between functors and functions.  This would, in my
opinion, provide a cleaner model of abstract vs. concrete types: an
abstract type is just one whose functors are not exported.  (Though
separately exporting all the constructor functions of a type would be
ugly, so some syntactic sugar would be called for).  This model would
also allow for "semi-abstract" types, eg, you could define a tree type
making its tree/3 constructor private but its empty/0 constructor
public, which would let client modules create empty trees and check
trees for emptiness in a very natural and straightforward manner,
while still hiding the implementation (note that you could later
define empty/0 as a separate function if you want to use some
different representation that doesn't include an empty/0 constructor).

We can push this even further, by providing a type that appears to be
a concrete type, but in fact its constructors are actually just
functions that construct some representation of the term.  When
applied to constructor classes, this flexibility can allow us to
define a whole constructor class that appears to have a fixed set of
constructors, as well as a set of defined operations, but in fact
these are all implemented differently for each type.

So I would hate to see Mercury's functions be just a single-moded view
of a predicate.

-- 
Peter Schachte                     The wrong sort of people are always in
mailto:schachte at cs.mu.OZ.AU        power because they would not be in power
http://www.cs.mu.oz.au/~schachte/  if they were not the wrong sort of people.
PGP: finger schachte at 128.250.37.3      -- Jon Wynne-Tyson 
--------------------------------------------------------------------------
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