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.
to an expression):<br />
Eval [ϕ(e1, . . . , em)@e] ⇒ ϕ(e1, . . . , em, e) if ϕ has arity n and m < n<br />
Thus, we evaluate an application by simply adding the argument to a partial application. If<br />
a function has the right number of arguments, it is evaluated by the rules in Figure 2. Note<br />
that the function application is “rigid” in its first argument since the application suspends if the<br />
applied function is unknown (instead of a possible but expensive non-deterministic search for the<br />
appropriate function).<br />
λ-abstractions occurring in expressions are anonymous functions and can be implemented by<br />
assigning a new name to each λ-abstraction, where the free variables become parameters of the<br />
function. For instance, the λ-abstraction (f is a free variable)<br />
\x y -> f x y + 2<br />
can be replaced by the (partial) application (lambda f), where lambda is a new name, and adding<br />
the rule<br />
lambda f x y = f x y + 2<br />
Note that this transformation (as well as the extension of Eval [·] above) is only used to explain the<br />
operational meaning of <strong>Curry</strong>’s higher-order features. A concrete <strong>Curry</strong> system is free to choose<br />
other implementation techniques.<br />
D.6 Generating Definitional Trees<br />
<strong>Curry</strong>’s computation model is based on the specification of a definitional tree for each operation.<br />
Although definitional trees are a high-level formalism to specify evaluation strategies, it is tedious<br />
to annotate each operation which its definitional tree. Therefore, the user need not write them<br />
explicitly in the program since they are automatically inserted by the <strong>Curry</strong> system. In the following,<br />
we present <strong>Curry</strong>’s algorithm to generate definitional trees from the left-hand sides of the<br />
functions’ rules.<br />
The generation of definitional trees for each function is not straightforward, since there may<br />
exist many non-isomorphic definitional trees for a single function representing different evaluation<br />
strategies. This demands for a default strategy to generate definitional trees. <strong>Curry</strong> uses the<br />
following default strategy:<br />
1. The leftmost argument, where a constructor occurs at the corresponding position in all lefthand<br />
sides defining this function, is evaluated to head normal form.<br />
2. or nodes (i.e., disjunctions) are generated in case of a conflict between constructors and<br />
variables in the left-hand sides, i.e., if two rules have a variable and a constructor at the same<br />
position on the left-hand side.<br />
In the following, we assume that all rules are unconditional (it is obvious how to extend it to<br />
conditional rules since only the left-hand sides of the rules are relevant for the definitional trees).<br />
To specify the construction algorithm, we define by<br />
DP (π, R) = {o position of a variable in π | root(l|o) ∈ C for some l = r ∈ R}<br />
70