Curry: An Integrated Functional Logic Language
Curry: An Integrated Functional Logic Language
Curry: An Integrated Functional Logic Language
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
may cause the reactivation of c1 at some later time (due to the binding of common variables). In<br />
a sequential implementation, the evaluation of c1 & c2 could be started by an attempt to solve c1.<br />
If the evaluation of c1 suspends, an evaluation step is applied to c2.<br />
It is interesting to note that parallel functional computation models [11, 12] are covered by the<br />
use of concurrent constraints. For instance, a constraint of the form<br />
x =:= f t1 & y =:= g t2 & z =:= h x y<br />
specifies a potentially concurrent computation of the functions f, g and h where the function h can<br />
proceed its computation only if the arguments have been bound by evaluating the expressions f t1<br />
and g t2. Since constraints could be passed as arguments or results of functions (like any other<br />
data object or function), it is possible to specify general operators to create flexible communication<br />
architectures similarly to Goffin [12]. Thus, the same abstraction facilities could be used for<br />
sequential as well as concurrent programming. On the other hand, the clear separation between<br />
sequential and concurrent computations (e.g., a program without any occurrences of concurrent<br />
conjunctions is purely sequential) supports the use of efficient and optimal evaluation strategies for<br />
the sequential parts [4, 6], where similar techniques for the concurrent parts are not available.<br />
2.7 Higher-order Features<br />
<strong>Curry</strong> is a higher-order language supporting the common functional programming techniques by<br />
partial function applications and lambda abstractions. Function application is denoted by juxtaposition<br />
the function and its argument. For instance, the well-known map function is defined in<br />
<strong>Curry</strong> by<br />
map :: (a -> b) -> [a] -> [b]<br />
map f [] = []<br />
map f (x:xs) = f x : map f xs<br />
However, there is an important difference w.r.t. to functional programming. Since <strong>Curry</strong> is also<br />
a logic language, it allows logical variables also for functional values, i.e., it is possible to evaluate<br />
the equation map f [1 2] =:= [2 3] which has, for instance, a solution {f=inc} if inc is the<br />
increment function on natural numbers. In principle, such solutions can be computed by extending<br />
(first-order) unification to higher-order unification [24, 38, 43]. Since higher-order unification is a<br />
computationally expensive operation, <strong>Curry</strong> delays the application of unknown functions until the<br />
function becomes known [2, 46]. 5 Thus, the application operation can be considered as a function<br />
(“@” is a left-associative infix operator)<br />
(@) :: (a -> b) -> a -> b<br />
f@x = f x<br />
which is “rigid” in its first argument (cf. Section 3).<br />
In cases where a function is only used a single time, it is tedious to assign a name to it. For<br />
5 Note that an unbound functional variable can never be instantiated if all program rules are constructor-based and<br />
the equational constraint =:= denotes equality between data terms. However, extensions of <strong>Curry</strong> might overcome<br />
this weakness by instantiating unbound functional variables to (type-conform) functions occurring in the program in<br />
order to evaluate an application (as in [19]), or by considering partial applications (i.e., functions calls with less than<br />
the required number of arguments) as data terms (as in [49]).<br />
11