14.11.2012 Views

Curry: An Integrated Functional Logic Language

Curry: An Integrated Functional Logic Language

Curry: An Integrated Functional Logic Language

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!