Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Curry (programming language)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{Short description|Programming language}} {{About|the programming language Curry (named in honour of a mathematician and logician)|the mathematician and logician|Haskell Curry|the computer science technique|Currying}} {{Primary sources|date=July 2019}} {{Infobox programming language |name = Curry |logo = |paradigm = [[Functional programming|functional]], [[Logic programming|logic]], non-strict, modular |designer = Michael Hanus, Sergio Antoy, et al. |developer = [[Kiel University]]<br/>[[Ludwig Maximilian University of Munich]]<br/>[[University of MΓΌnster]]<br/>[[Portland State University]]<br/>[[Complutense University of Madrid]]<br/>[[Technical University of Madrid]] |released = {{Start date and age|1995}} |latest release version = {{wikidata|property|reference|edit|P348|P548=Q2804309}} |latest release date = ({{wikidata|qualifier|P348|P577}}) |latest preview version = |latest preview date = |typing = [[static typing|static]], [[Strong and weak typing|strong]], [[type inference|inferred]] |platform = [[x86-64]] |operating system = [[Cross-platform software|Cross-platform]]: [[Linux]] |license = [[BSD licenses|BSD]] 3-clause |website = {{URL|www.curry-lang.org}} |implementations = [https://www.curry-lang.org/pakcs PAKCS] ([[Prolog]] target), [http://danae.uni-muenster.de/curry/ mcc] ([[C (programming language)|C]] target), [https://www.curry-lang.org/kics2/ KiCS2] ([[Haskell]] target) |dialects = |influenced by = [[Haskell]], [[Prolog]] |influenced = }} '''Curry''' is a [[declarative programming]] language, an implementation of the [[functional logic programming]] paradigm,<ref>{{cite web |editor-last=Hanus |editor-first=Michael |title=Curry: A Truly Integrated Functional Logic Language |url=http://www.curry-lang.org/}}</ref><ref>{{cite journal |last1=Sergio |first1=Antoy |last2=Hanus |first2=Michael |year=2010 |title=Functional Logic Programming |journal=Communications of the ACM |volume=53 |issue=4 |pages=74β85 |publisher=ACM |doi=10.1145/1721654.1721675 |s2cid=14578759}}</ref> and based on the [[Haskell]] language. It merges elements of functional and logic programming,<ref name="Curry and Curl programming languages"> {{cite web |title=Curry experimental programming language |url=https://www.mvps.net/docs/curry-and-curl-programming-languages |website=MVPS.net |access-date=2 September 2021}}</ref> including [[constraint programming]] integration. It is nearly a superset of Haskell but does not support all language extensions of Haskell. In contrast to Haskell, Curry has built-in support for non-deterministic computations involving search. ==Foundations of functional logic programming== ===Basic concepts=== A functional program is a set of functions defined by equations or rules. A functional computation consists of replacing subexpressions by equal (with regard to the function definitions) subexpressions until no more replacements (or reductions) are possible and a value or normal form is obtained. For instance, consider the function double defined by double x = x+x The expression β{{Mono|double 1}}β is replaced by {{Mono|1+1}}. The latter can be replaced by {{Mono|2}} if we interpret the operator β{{Mono|+}}β to be defined by an infinite set of equations, e.g., {{Mono|1=1+1 = 2}}, {{Mono|1=1+2 = 3}}, etc. In a similar way, one can evaluate nested expressions (where the subexpressions to be replaced are quoted): 'double (1+2)' β '(1+2)'+(1+2) β 3+'(1+2)' β '3+3' β 6 There is also another order of evaluation if we replace the arguments of operators from right to left: 'double (1+2)' β (1+2)+'(1+2)' β '(1+2)'+3 β '3+3' β 6 In this case, both derivations lead to the same result, a property known as [[Confluence (term rewriting)|confluence]]. This follows from a fundamental property of pure functional languages, termed [[referential transparency]]: the value of a computed result does not depend on the order or time of evaluation, due to the absence of [[Side effect (computer science)|side effects]]. This simplifies reasoning about, and maintaining, pure functional programs. As many functional languages like [[Haskell]] do, Curry supports the definition of [[algebraic data type]]s by enumerating their constructors. For instance, the type of Boolean values consists of the constructors {{Mono|True}} and {{Mono|False}} that are declared as follows: <syntaxhighlight lang="haskell"> data Bool = True | False </syntaxhighlight> Functions on Booleans can be defined by pattern matching, i.e., by providing several equations for different argument values: <syntaxhighlight lang="haskell"> not True = False not False = True </syntaxhighlight> The principle of replacing equals by equals is still valid provided that the actual arguments have the required form, e.g.: not '(not False)' β 'not True' β False More complex [[data structure]]s can be obtained by [[recursive data type]]s. For instance, a list of elements, where the type of elements is arbitrary (denoted by the type variable {{Mono|a}}), is either the empty list β{{Mono|[]}}β or the non-empty list β{{Mono|x:xs}}β consisting of a first element {{Mono|x}} and a list {{Mono|xs}}: <syntaxhighlight lang="haskell"> data List a = [] | a : List a </syntaxhighlight> The type β{{Mono|List a}}β is usually written as {{Mono|[a]}} and finite lists x1{{Mono|:}}x2{{Mono|:}}...{{Mono|:}}xn{{Mono|:[]}} are written as {{Mono|[}}x1{{Mono|,}}x2{{Mono|,}}...{{Mono|,}}xn{{Mono|]}}. We can define operations on recursive types by inductive definitions where pattern matching supports the convenient separation of the different cases. For instance, the concatenation operation β{{Mono|++}}β on polymorphic lists can be defined as follows (the optional type declaration in the first line specifies that β{{Mono|++}}β takes two lists as input and produces an output list, where all list elements are of the same unspecified type): <syntaxhighlight lang="haskell"> (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : xs++ys </syntaxhighlight> Beyond its application for various programming tasks, the operation β{{Mono|++}}β is also useful to specify the behavior of other functions on lists. For instance, the behavior of a function last that yields the last element of a list can be specified as follows: for all lists xs and elements e, {{Mono|last}} xs = e if βys{{Mono|:}}ys{{Mono|++[}}e{{Mono|]}} = xs. Based on this specification, one can define a function that satisfies this specification by employing logic programming features. Similarly to logic languages, functional logic languages provide search for solutions for existentially quantified variables. In contrast to pure logic languages, they support equation solving over nested functional expressions so that an equation like ys{{Mono|++[}}e{{Mono|]}} = {{Mono|[1,2,3]}} is solved by instantiating ys to the list {{Mono|[1,2]}} and e to the value {{Mono|3}}. In Curry one can define the operation last as follows: <syntaxhighlight lang="haskell"> last xs | ys++[e] =:= xs = e where ys,e free </syntaxhighlight> Here, the symbol β{{Mono|1==:=}}β is used for equational constraints in order to provide a syntactic distinction from defining equations. Similarly, extra variables (i.e., variables not occurring in the left-hand side of the defining equation) are explicitly declared by β{{Mono|where...free}}β in order to provide some opportunities to detect bugs caused by typos. A conditional equation of the form l {{Mono|{{!}}}} c {{Mono|1==}} r is applicable for reduction if its condition c has been solved. In contrast to purely functional languages where conditions are only evaluated to a Boolean value, functional logic languages support the solving of conditions by guessing values for the unknowns in the condition. Narrowing as discussed in the next section is used to solve this kind of conditions. ===Narrowing=== Narrowing is a mechanism whereby a variable is [[name binding|bound]] to a value selected from among alternatives imposed by constraints. Each possible value is tried in some order, with the remainder of the program invoked in each case to determine the validity of the binding. Narrowing is an extension of logic programming, in that it performs a similar search, but can actually generate values as part of the search rather than just being limited to testing them. Narrowing is useful because it allows a function to be treated as a relation: its value can be computed "in both directions". The Curry examples of the previous section illustrate this. As noted in the prior section, narrowing can be thought of as reduction on a program term graph, and there are often many different ways (''strategies'') to reduce a given term graph. Antoy et al.<ref>{{cite journal |last1=Sergio |first1=Antoy |last2=Echahed |first2=Rachid |last3=Hanus |first3=Michael |title=A Needed Narrowing Strategy |journal=Journal of the ACM |volume=47 |issue=4 |pages=776β822 |publisher=ACM |year=2007 |issn=0004-5411 |doi=10.1145/347476.347484 | s2cid=47275506 }}</ref> proved in the 1990s that a particular narrowing strategy, ''needed narrowing'', is optimal in the sense of doing a number of reductions to get to a "normal form" corresponding to a solution that is minimal among sound and complete strategies. Needed narrowing corresponds to a lazy strategy, in contrast to the [[SLD resolution|SLD-resolution]] strategy of [[Prolog]]. ===Functional patterns=== The rule defining {{Mono|last}} shown above expresses the fact that the actual argument must match the result of narrowing the expression {{Mono|ys++[e]}}. Curry can express this property also in the following more concise way: <syntaxhighlight lang="haskell"> last (ys++[e]) = e </syntaxhighlight> Haskell does not allow such a declaration since the pattern in the left-hand side contains a defined function ({{Mono|++}}). Such a pattern is also called ''functional pattern''.<ref>{{cite book |last1=Sergio |first1=Antoy |last2=Hanus |first2=Michael |title=Logic Based Program Synthesis and Transformation |chapter=Declarative Programming with Function Patterns |series=Lecture Notes in Computer Science |year=2006 |doi=10.1007/11680093_2 |volume=3901 |pages=6β22 |isbn=978-3-540-32654-0}}</ref> Functional patterns are enabled by the combined functional and logic features of Curry and support concise definitions of tasks requiring deep pattern matching in hierarchical data structures. ===Non-determinism=== Since Curry is able to solve equations containing function calls with unknown values, its execution mechanism is based on non-deterministic computations, similarly to logic programming. This mechanism supports also the definition of ''non-deterministic operations'', i.e., operations that delivers more than one result for a given input. The archetype of non-deterministic operations is the predefined infix operation {{Mono|?}}, called ''choice'' operator, that returns one of its arguments. This operator is defined by the following rules: x ? y = x x ? y = y Thus, the evaluation of the expression {{Mono|0 ? 1}} returns {{Mono|0}} as well as {{Mono|1}}. Computing with non-deterministic operations and computing with free variables by narrowing has the same expressive power.<ref>{{cite book |last1=Sergio |first1=Antoy |last2=Hanus |first2=Michael |title=Logic Programming |chapter=Overlapping Rules and Logic Variables in Functional Logic Programs |series=Lecture Notes in Computer Science |year=2006 |doi=10.1007/11799573_9 |volume=4079 |pages=87β101 |isbn=978-3-540-36635-5}}</ref> The rules defining {{Mono|?}} show an important feature of Curry: all rules are tried in order to evaluate some operation. Hence, one can define by <syntaxhighlight lang="haskell"> insert x ys = x : ys insert x (y:ys) = y : insert x ys </syntaxhighlight> an operation to insert an element into a list at an indeterminate position so that the operation {{Mono|perm}} defined by <syntaxhighlight lang="haskell"> perm [] = [] perm (x:xs) = insert x (perm xs) </syntaxhighlight> returns any permutation of a given input list. ===Strategies=== Due to the absence of side effects, a functional logic program can be executed with different strategies. To evaluate expressions, Curry uses a variant of the ''needed narrowing'' strategy which combines [[lazy evaluation]] with non-deterministic search strategies. In contrast to Prolog, which uses backtracking to search for solutions, Curry does not fix a particular search strategy. Hence, there are implementations of Curry, like [http://www-ps.informatik.uni-kiel.de/kics2/ KiCS2], where the user can easily select a search strategy, like [[depth-first search]] (backtracking), [[breadth-first search]], iterative deepening, or parallel search. ==References== {{Reflist}} ==External links== *{{Official website|www.curry-lang.org}} *[https://smap.informatik.uni-kiel.de/ Smap] - A web-based execution environment for Curry and Haskell with various example programs *[https://cpm.curry-lang.org/ Curry packages] - A collection of software packages for Curry *[http://danae.uni-muenster.de/curry/ MCC] - The MΓΌnster Curry Compiler, targets [[C (programming language)|C]] *[https://www.curry-lang.org/pakcs/ PAKCS] A major Curry implementation, targets [[Prolog]] *[https://www.curry-lang.org/kics2/ KiCS2] A Curry implementation, targets [[Haskell]] *[https://www.curry-lang.org/curry2go/ Curry2Go] A Curry implementation, targets [[Go (programming language)|Go]], and supports fair parallel search *[https://curry-lang.org/various/mailinglist/ Curry Mailing List] *[http://www.informatik.uni-kiel.de/~mh Michael Hanus's home page] * ''[http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.148.524 Purely Functional Lazy Non-deterministic Programming]'' (Fischer, Kiselyov, Shan, 2009), ''[http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.157.4578 Transforming Functional Logic Programs into Monadic Functional Programs]'' (BraΓel, Fischer, Hanus, Reck, 2010) on modeling lazy non-deterministic (logic) programming (like in Curry) in a purely functional language ([[Haskell]]); such approach might give the programmer more flexibility in the control over the strategies thatβin the case of Curryβare built-in. {{Haskell programming}} {{Haskell Curry}} {{Authority control}} [[Category:High-level programming languages]] [[Category:Concurrent programming languages]] [[Category:Experimental programming languages]] [[Category:Functional logic programming languages]] [[Category:Haskell programming language family]] [[Category:Programming languages created in 1995]] [[Category:Nondeterministic programming languages]] [[Category:Literate programming]] [[Category:Academic programming languages]] [[Category:Software using the BSD license]] <!-- Hidden categories below --> [[Category:Articles with example Haskell code]] [[Category:Statically typed programming languages]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:About
(
edit
)
Template:Authority control
(
edit
)
Template:Cite book
(
edit
)
Template:Cite journal
(
edit
)
Template:Cite web
(
edit
)
Template:Haskell Curry
(
edit
)
Template:Haskell programming
(
edit
)
Template:Infobox programming language
(
edit
)
Template:Mono
(
edit
)
Template:Official website
(
edit
)
Template:Primary sources
(
edit
)
Template:Reflist
(
edit
)
Template:Short description
(
edit
)