Est. 1995 Advanced

Curry

The functional logic programming language that seamlessly integrates Haskell-style functional programming with logic programming through narrowing and non-determinism.

Created by Michael Hanus, Sergio Antoy, Herbert Kuchen, et al.

Paradigm Functional, Logic, Constraint
Typing Static, Strong, Inferred
First Appeared 1995
Latest Version Curry Report 0.9.0 (PAKCS 3.9.0, 2025)

Curry is a declarative multi-paradigm programming language that seamlessly combines features from functional programming and logic programming into a single coherent language. Nearly a superset of Haskell in syntax, Curry extends purely functional programming with logic variables, non-deterministic operations, and built-in search capabilities, making it the most prominent language in the functional logic programming paradigm.

History & Origins

In the early 1990s, the functional logic programming community faced a fragmentation problem similar to what the Haskell committee had addressed for lazy functional languages. Multiple research groups had developed their own functional logic languages – ALF, BABEL, Escher, and others – each exploring different approaches to integrating functional and logic programming. There was no common platform for researchers, teachers, and practitioners to share their work.

The Birth of Curry

In 1995, Michael Hanus (then at RWTH Aachen, later at Kiel University), Herbert Kuchen (University of Munster), and Juan Jose Moreno-Navarro (Technical University of Madrid) presented the initial design of Curry at the International Logic Programming Symposium. The language was conceived as an international initiative to provide a common platform for research, teaching, and application of integrated functional logic languages.

The name “Curry” is a tribute to Haskell Brooks Curry (1900-1982), the American mathematician and logician whose work on combinatory logic is foundational to functional programming. The name also connects Curry to its Haskell heritage, since both languages honor the same person.

The Curry Report

The language was formalized through the Curry Report, with version 0.6 published on October 22, 1999. This specification has been refined over the years through versions 0.7, 0.8, and the current version 0.9.0, each expanding and clarifying the language’s semantics. Sergio Antoy (Portland State University) has been a major contributor to both the theoretical foundations and practical development of Curry throughout its history.

Design Philosophy

Curry’s central idea is that functional programming and logic programming are not fundamentally opposed paradigms but rather complementary aspects of declarative computation. Rather than choosing between them, Curry integrates both into a single language where:

  • Functions define computations through equations and pattern matching (as in Haskell)
  • Logic variables allow unknown values to be constrained and solved
  • Non-determinism is a first-class concept, with operations that can return multiple results
  • Search is built into the language rather than requiring external libraries

This integration is not merely syntactic. Curry’s operational semantics, based on needed narrowing, provides a principled unification of lazy evaluation (from functional programming) and unification-based search (from logic programming).

Key Features

Haskell Compatibility

Curry’s syntax is nearly a superset of Haskell 98. Most pure Haskell programs are valid Curry programs:

-- Standard functional programming, identical to Haskell
factorial :: Int -> Int
factorial 0 = 1
factorial n = n * factorial (n - 1)

-- Higher-order functions work as expected
map :: (a -> b) -> [a] -> [b]
map _ []     = []
map f (x:xs) = f x : map f xs

This compatibility means that Haskell programmers can quickly become productive in Curry while gaining access to logic programming features.

Non-Deterministic Operations

Unlike Haskell, Curry allows functions to be non-deterministic – they can return different values for the same input. The choice operator (?) expresses this directly:

-- A coin can be heads or tails
coin :: Int
coin = 0 ? 1

-- Insert an element at any position in a list
insert :: a -> [a] -> [a]
insert x ys     = x : ys
insert x (y:ys) = y : insert x ys

When a non-deterministic operation is evaluated, Curry’s search mechanism explores all possible results.

Free Variables and Narrowing

Curry supports logic (free) variables that can appear in expressions without being bound to a value. The narrowing mechanism binds these variables to values that satisfy the given constraints:

-- Find x such that x ++ [3,4] == [1,2,3,4]
-- where x is a free variable
goal | xs ++ [3,4] =:= [1,2,3,4] = xs
  where xs free

Narrowing combines pattern matching with unification: when a function is applied to a free variable, the variable is instantiated to the patterns that allow the function to proceed. This is more powerful than either pure rewriting or pure resolution alone.

Functional Patterns

Curry introduces functional patterns, which allow function calls to appear in pattern positions. This enables deep pattern matching that would be cumbersome to express otherwise:

-- Match the last element of a list
last :: [a] -> a
last (_ ++ [x]) = x

Here, (_ ++ [x]) is a functional pattern – it calls the append function within a pattern to destructure the list. This is a feature unique to Curry among mainstream declarative languages.

Constraint Programming

Beyond equational constraints (=:=), Curry supports various constraint domains. Constraints over finite domains, for example, allow solving combinatorial problems declaratively:

-- Using arithmetic constraints
add :: Int -> Int -> Int -> Success
add x y z = x + y =:= z

Curry provides mechanisms to encapsulate non-deterministic computations and control the search strategy:

-- Collect all solutions into a list
allSolutions :: (a -> Success) -> [a]

This allows programmers to use non-determinism locally while maintaining a deterministic interface to the rest of the program.

Implementations

Curry has several mature implementations, each targeting a different backend:

PAKCS (Portland Aachen Kiel Curry System)

PAKCS is the most widely used Curry implementation. It compiles Curry programs to Prolog (specifically SICStus Prolog or SWI-Prolog), leveraging Prolog’s built-in search and unification capabilities. PAKCS provides a complete development environment including an interactive interpreter, a debugger, and integration with the Curry Package Manager (CPM).

KiCS2 (Kiel Curry System version 2)

KiCS2 takes a different approach by compiling Curry programs to Haskell, which is then compiled by GHC. This enables Curry programs to benefit from GHC’s sophisticated optimization pipeline. KiCS2 was first presented in a 2011 paper and represents non-determinism through a pull-tabbing approach.

MCC (Munster Curry Compiler)

The Munster Curry Compiler, developed by Wolfgang Lux at the University of Munster, compiles Curry to C. MCC is notable for its integration of a declarative debugger for detecting wrong answers. It conforms to the Curry Report except for committed choice.

Curry2Go

The newest implementation compiles Curry to Go, with a distinctive feature: its default search strategy is a fair parallel strategy that takes advantage of multi-processor systems. This makes it possible to explore multiple non-deterministic branches concurrently.

The Curry Ecosystem

Package Manager (CPM)

Curry has a centralized package manager and package index. CPM manages dependencies, library distribution, and project configuration, following modern package management conventions.

Development Tools

  • CurryDoc – Generates HTML documentation from Curry source code
  • Curr(y)gle – A search engine for Curry libraries, analogous to Haskell’s Hoogle
  • CurryCheck – Property-based testing tool leveraging Curry’s non-determinism
  • CurryBrowser – An analysis and visualization tool for Curry programs

Web Development

The Spicey framework generates web applications from entity-relationship models, demonstrating that functional logic programming can be applied to practical web development tasks.

Evolution

Curry has evolved steadily since its initial design in 1995. The language specification has progressed through multiple versions of the Curry Report:

  • Version 0.6 (1999): The first formal specification
  • Version 0.8.3 (2014): Refined semantics and additional features
  • Version 0.9.0 (current): The latest specification with further refinements

Each version has refined the language’s approach to non-determinism, search strategies, and the interaction between functional and logic features. The implementation landscape has also evolved, from the early PAKCS system to the multi-backend approach available today with KiCS2, MCC, and Curry2Go.

Current Relevance

Curry remains actively developed, with PAKCS 3.9.0 released in October 2025 and ongoing work on all major implementations. The language continues to serve its primary role as a research platform for functional logic programming, while also finding use in university teaching.

The ideas pioneered in Curry – particularly narrowing-based evaluation, functional patterns, and the seamless integration of deterministic and non-deterministic computation – represent important contributions to programming language theory. While Curry has not achieved mainstream adoption, its concepts influence research in program transformation, partial evaluation, and multi-paradigm language design.

Why It Matters

Curry occupies a unique position in the landscape of programming languages. It demonstrates that the boundary between functional and logic programming is not as rigid as it might seem – that a single language can support both paradigms without compromise, using a clean theoretical foundation.

For researchers, Curry provides a testbed for ideas in narrowing strategies, search control, and declarative programming. For students, it offers a window into how different programming paradigms relate to each other. And for programming language designers, Curry’s solutions to integrating determinism with non-determinism, and functions with logic variables, offer patterns that may influence future language designs.

The language’s name captures this bridging role perfectly: Haskell Curry’s work on combinatory logic connects the mathematical foundations of both functional and logic programming, just as the language Curry connects these two paradigms in practice.

Timeline

1995
Michael Hanus, Herbert Kuchen, and Juan Jose Moreno-Navarro present Curry at the International Logic Programming Symposium (ILPS '95)
1999
First Curry Report (version 0.6) published on October 22, establishing a formal language specification
2003
PAKCS (Portland Aachen Kiel Curry System) matures as the primary Curry implementation, compiling to Prolog
2005
International Workshop on Curry and Functional Logic Programming (WCFLP 2005) held in Tallinn, Estonia
2011
KiCS2 (Kiel Curry System version 2) introduced, compiling Curry programs to Haskell via GHC
2014
Curry Report version 0.8.3 published (February 27, 2014) with refined language semantics
2020
Curry2Go compiler introduced, targeting Go with support for fair parallel search on multi-processor systems
2025
PAKCS 3.9.0, KiCS2 3.4.0, and Curry2Go 1.6.0 released; Curry Report version 0.9.0 is the current specification

Notable Uses & Legacy

Functional Logic Programming Research

Curry serves as the primary vehicle for international research into functional logic programming, with dozens of published papers exploring narrowing, residuation, and non-deterministic evaluation strategies.

University Teaching

Used in programming language courses at institutions including Kiel University and Portland State University to teach declarative programming, type systems, and the integration of functional and logic paradigms.

Spicey Web Framework

An entity-relationship-based web framework written in Curry that generates web applications from data models, demonstrating practical application of functional logic programming to web development.

CurryCheck Property Testing

A property-based testing tool for Curry programs that leverages the language's built-in non-determinism and free variables to automatically generate test cases and verify program properties.

Language Influence

Influenced By

Running Today

Run examples using the official Docker image:

docker pull
Last updated: