Dear Colleague,
I have updated the report on Curry.
This update is based on the discussion which we had on this mailing
list and further discussions with individual people.
The new version is available via the Curry web pages or directly at
http://www-i2.informatik.rwth-aachen.de/~hanus/curry/papers/report.dvi.Z
In order to encourage the discussion on the proposed changes,
I summarize the most important changes w.r.t. the first version of
December 5, 1996:
- the syntax is made compatible with Haskell
- restriction to confluent programs are dropped, i.e., non-deterministic
functions are allowed, but sufficient criteria to ensure
"well-definedness" of functions in the traditional sense are given,
see Section 2.2
- equational constraints and concurrent conjunction introduced (Section 2.3)
- meaning of committed choice modified (now it is compatible
with concurrent constraint languages)
- Prelude added (Appendix B)
- Syntax added (Appendix C)
The main conceptual change is the introduction of equational
constraints, which are described in Section 2.3.
This is only a slight conceptual modification (on the level of
types), but it solves a lot of problems with the current definition
of equality. Here are the main ideas concerning the introduction of
equational constraints:
1. Distinguish between usual Boolean functions (as in Haskell)
and constraints. Boolean functions can deliver True and False
as result values, whereas constraints are either satisfiable
and the computation proceeds or unsatisfiable and the computation
is discarded. Since the type of Boolean values is different
from constraints, you cannot apply the function "not" to negate
constraints (this causes one of the problems in the old version).
If one wants to compute with negative constraints, the constraint
system (currently only equations on data terms) must be enriched.
Thus, we distinguish between the test equality t1==t2, which a Boolean
function like in Haskell (since it suspends if one argument is an unkown
value), and the equational constraint {t1=t2}, which must be
solved in order to proceed the computation and thus may bind
unknown arguments. In terms of Saraswat's framework for concurrent
constraint programming, t1==t2 corresponds to "ask" and {t1=t2} to
"tell".
2. Constraints are applied (i.e., solved) only in conditions of
function rules, i.e., the condition of a function
rule has not type Bool but type "constraint" (in contrast
to the condition in if-then-else which has type Bool since
the outcomes True and False are necessary). This view
is fully compatible with logic programming and CLP
where the constraint in the conditional part must be satisfied
in order to apply the rule. If the constraint is not satisfiable,
then this rule cannot be applied. In order to be compatible
with Haskell, a Haskell rule "l | b = r" can be viewed
as equivalent to "l | {b=True} = r". This clearly shows
that one is interested in only computing the value True for
the condition.
3. Constraints can be constructed using the (concurrent) conjunction
/\, i.e., the sequential conjunction && of Haskell is a Boolean
function whereas /\ works on constraints. An important difference
is that a constraint {c1 /\ c2} can be evaluated concurrently.
Thus, all potential parallelism is expressed by constraints,
while the functional kernel (without constraints) expresses
a sequential computation. This point of view is compatible
with recent parallel functional languages like Goffin or Eden:
They use Haskell as a kernel language plus a coordination
language (constraints in Goffin, process constructs in Eden)
to express parallelism. By this simple distinction between
Boolean functions and constraints, Curry does not only
cover CLP but also covers and generalizes concurrent constraint
languages and functional parallel languages.
4. Since constraints are first-class citizens, one can also
define functions to generate constraints (which corresponds
to "skeletons" of high-level parallel languages). Functions
could also have constraints as parameters, but the only way
to use a constraint parameter is to pass it to the output or
apply it in the condition of its rule.
5. The introduction of constraints makes it also clear how to
connect external constraints solvers or enrich Curry with
more sophisticated constraint structures (like disequality,
arithmetic, or finite domain constraints): constraints are
only applied or tested for satisfiability in conditions of rules.
6. The introduction of constraints solves also some problems
which we have in connection with encapsulated search, but this
will be the topic of a future version.
You may look into the report for examples, in particular
Appendix A.5, where I have added a simple example how to do
concurrent object-oriented programming in Curry.
I hope that you agree with this proposal, since, after working
with this, I become more and more convinced that this is a
reasonable way to go.
If you want to see some really running examples, you could also
use our prototype implementation of Curry. This implementation,
called TasteCurry, is implemented by a very simple interpreter
written in Prolog. It is slow, but it implements a substantial
subset of Curry (e.g., it has polymorphic type inference,
an automatic generator for definitional trees, higher-order
functions and lambda-abstraction, local "where"-declarations,
monadic I/O, comitted choice etc). Since we haven't written any
parser, we use a Prolog-like syntax instead of concrete Curry
syntax, but I hope this will be improved in the next time
with the help of Sergio Antoy. You can run this interpreter
via our web interface for running TasteCurry programs. Please look at
http://www-i2.informatik.rwth-aachen.de/~hanus/tastecurry/
Enjoy!
Any kinds of comments are welcome!
Best regards,
Michael
Received on Fr Jun 06 1997 - 19:36:00 CEST