Currying and partial application

Add power and indirection to function dispatch


Content series:

This content is part # of # in the series:

Stay tuned for additional content in this series.

This content is part of the

Stay tuned for additional content in this series.

Currying and partial application are language techniques derived from mathematics (based on work by 20th-century mathematician Haskell Curry and others). These techniques are present in various types of languages, and either or both are omnipresent in functional languages. Both currying and partial application give you the ability to manipulate the number of arguments to functions or methods, typically by supplying one or more default values for some arguments (known as fixing arguments). All of the languages include currying and partial application, but they implement them in different ways. In this installment, I explain the difference between the two techniques and show implementation details for Scala, Groovy, and Clojure, along with practical uses.

Definitions and distinction

To the casual observer, currying and partial application appear to have the same effect. With both, you can create a version of a function with pre-supplied values for some of the arguments:

  • Currying describes the conversion of a multi-argument function into a chain of single-argument functions. It describes the transformation process, not the invocation of the converted function. The caller can decide how many arguments to apply, thereby creating a derived function with that smaller number of arguments.
  • Partial application describes the conversion of a multi-argument function into one that accepts fewer arguments, with values for the elided arguments supplied in advance. The technique's name is apt: It partially applies some arguments to a function, returning a function with a signature that consists of the remaining arguments.

With both currying and partial application, you supply argument values and return a function that's invokable with the missing arguments. But currying a function returns the next function in the chain, whereas partial application binds argument values to values that you supply during the operation, producing a function with a smaller arity (number of arguments). This distinction becomes clearer when you consider functions with arity greater than two. For example, the fully curried version of the process(x, y, z) function is process(x)(y)(z), where both process(x) and process(x)(y) are functions that accept a single argument. If you curry only the first argument, the return value of process(x) is a function that accepts a single argument that in turn accepts a single argument. In contrast, with partial application, you are left with a function of smaller arity. Using partial application for a single argument on process(x, y, z) yields a function that accept two arguments: process(y, z).

The two techniques' results are often the same, but the distinction is important and often misconstrued. To complicate matters further, Groovy implements both partial application and currying but calls both currying. And Scala has both partially applied functions and PartialFunctions, which are distinct concepts despite the similar names.

In Scala

Scala supports currying and partial application, along with a trait that gives you the ability to define constrained functions.


In Scala, functions can define multiple argument lists as sets of parentheses. When you call a function with fewer than its defined number of arguments, the return is a function that takes the missing argument lists as its arguments. Consider the example from the Scala documentation that appears in Listing 1.

Listing 1. Scala's currying of arguments
def filter(xs: List[Int], p: Int => Boolean): List[Int] =
    if (xs.isEmpty) xs
    else if (p(xs.head)) xs.head :: filter(xs.tail, p)
    else filter(xs.tail, p)

def modN(n: Int)(x: Int) = ((x % n) == 0)

val nums = List(1, 2, 3, 4, 5, 6, 7, 8)
println(filter(nums, modN(2)))
println(filter(nums, modN(3)))

In Listing 1, the filter() function recursively applies the passed filter criteria. The modN() function is defined with two argument lists. When I call modN by using filter(), I pass a single argument. The filter() function accepts as its second argument a function with an Int argument and a Boolean return, which matches the signature of the curried function that I pass.

Partially applied functions

In Scala you can also partially apply functions, as shown in Listing 2.

Listing 2. Partially applying functions in Scala
def price(product : String) : Double =
  product match {
    case "apples" => 140
    case "oranges" => 223

def withTax(cost: Double, state: String) : Double =
  state match {
    case "NY" => cost * 2
    case "FL" => cost * 3

val locallyTaxed = withTax(_: Double, "NY")
val costOfApples = locallyTaxed(price("apples"))

assert(Math.round(costOfApples) == 280)

In Listing 2, I first create a price function that returns a mapping between product and price. Then I create a withTax() function that accepts cost and state as arguments. However, within a particular source file, I know that I will work exclusively with one state's taxes. Rather than "carry" the extra argument for every invocation, I partially apply the state argument and return a version of the function in which the state value is fixed. The locallyTaxed function accepts a single argument, the cost.

Partial (constrained) functions

The Scala PartialFunction trait is designed to work seamlessly with pattern matching. (Read about pattern matching in the "Either trees and pattern matching" installment of my Functional thinking series.) Despite the similarity in name, this trait does not create a partially applied function. Instead, you can use it to define a function that works only for a defined subset of values and types.

Case blocks are one way to apply partial functions. Listing 3 uses Scala's case without the traditional corresponding match operator.

Listing 3. Using case without match
val cities = Map("Atlanta" -> "GA", "New York" -> "New York",
  "Chicago" -> "IL", "San Francsico " -> "CA", "Dallas" -> "TX")

cities map { case (k, v) => println(k + " -> " + v) }

In Listing 3, I create a map of city and state correspondence. Then I invoke the map function on the collection, and map in turn pulls apart the key-value pairs to print them. In Scala, a code block that contains case statements is one way of defining an anonymous function. You can define anonymous functions more concisely without using case, but the case syntax provides the additional benefits that Listing 4 illustrates.

Listing 4. Differences between map and collect
List(1, 3, 5, "seven") map { case i: Int ? i + 1 } // won't work
// scala.MatchError: seven (of class java.lang.String)

List(1, 3, 5, "seven") collect { case i: Int ? i + 1 }
// verify
assert(List(2, 4, 6) == (List(1, 3, 5, "seven") collect { case i: Int ? i + 1 }))

In Listing 4, I can't use map on a heterogeneous collection with case: I receive a MatchError as the function tries to increment the seven string. But collect works correctly. Why the disparity and where did the error go?

Case blocks define partial functions, but not partially applied functions. Partial functions have a limited range of allowable values. For example, the mathematical function 1/x is invalid if x = 0. Partial functions offer a way to define constraints for allowable values. In the collect example in Listing 4, the case is defined for Int, but not for String, so the seven string isn't collected.

To define a partial function, you can also use the PartialFunction trait, as illustrated in Listing 5.

Listing 5. Defining a partial function in Scala
val answerUnits = new PartialFunction[Int, Int] {
    def apply(d: Int) = 42 / d
    def isDefinedAt(d: Int) = d != 0

assert(! answerUnits.isDefinedAt(0))

assert(answerUnits(42) == 1)
//java.lang.ArithmeticException: / by zero

In Listing 5, I derive answerUnits from the PartialFunction trait and supply two functions: apply() and isDefinedAt(). The apply() function calculates values. I use isDefinedAt()— a required method for a PartialFunction— to define constraints that determine arguments' suitability.

Because you can also implement partial functions with case blocks, answerUnits from Listing 5 can be written more concisely, as shown in Listing 6.

Listing 6. Alternative definition for answerUnits
def pAnswerUnits: PartialFunction[Int, Int] =
    { case d: Int if d != 0 => 42 / d }

assert(pAnswerUnits(42) == 1)
//scala.MatchError: 0 (of class java.lang.Integer)

In Listing 6, I use case in conjunction with a guard condition to constrain values and supply results simultaneously. One notable difference from Listing 5 is the MatchError (rather than ArithmeticException) — because Listing 6 uses pattern matching.

Partial functions aren't limited to numeric types. You can use all types, including Any. Consider the implementation of an incrementer, shown in Listing 7.

Listing 7. Defining an incrementer in Scala
def inc: PartialFunction[Any, Int] =
    { case i: Int => i + 1 }

assert(inc(41) == 42)
//scala.MatchError: Forty-one (of class java.lang.String)

assert(! inc.isDefinedAt("Forty-one"))

assert(List(42) == (List(41, "cat") collect inc))

In Listing 7, I define a partial function to accept any type of input (Any), but choose to react to a subset of types. However, notice that I can also call the isDefinedAt() function for the partial function. Implementers of the PartialFunction trait who use case can call isDefinedAt(), which is implicitly defined. In Listing 4, I illustrated that map and collect behave differently. The behavior of partial functions explains the difference: collect is designed to accept partial functions and to call the isDefinedAt() function for elements, ignoring those that don't match.

Partial functions and partially applied functions in Scala are similar in name, but they offer a different set of orthogonal features. For example, nothing prevents you from partially applying a partial function.

In Groovy

I cover currying and partial application in Groovy in some detail as part of my Functional thinking series in "Thinking functionally, Part 3." Groovy implements currying through the curry() function, which originates from the Closure class. Despite the name, curry() actually implements partial application by manipulating closure blocks underneath. However, you can simulate currying by using partial application to reduce a function to a series of partially applied single-argument functions, as shown in Listing 8.

Listing 8. Groovy's partial application and currying
def volume = { h, w, l -> return h * w * l }
def area = volume.curry(1)
def lengthPA = volume.curry(1, 1) //partial application
def lengthC = volume.curry(1).curry(1) // currying

println "The volume of the 2x3x4 rectangular solid is ${volume(2, 3, 4)}"
println "The area of the 3x4 rectangle is ${area(3, 4)}"
println "The length of the 6 line is ${lengthPA(6)}"
println "The length of the 6 line via curried function is ${lengthC(6)}"

In Listing 8, in both length cases, I use the curry() function to apply arguments partially. But with lengthC, I create the illusion of currying by partially applying arguments until a chain of single-argument functions remains.

In Clojure

Clojure includes the (partial f a1 a2 ...) function, which takes a function f and a fewer-than-required number of arguments and returns a partially applied function that's invokable when you supply the remaining arguments. Listing 9 shows two examples.

Listing 9. Clojure's partial application
(def subtract-from-hundred (partial - 100))

(subtract-from-hundred 10)      ; same as (- 100 10)
; 90

(subtract-from-hundred 10 20)   ; same as (- 100 10 20)
; 70

In Listing 9, I define a subtract-from-hundred function as the partially applied - operator (operators in Clojure are indistinguishable from functions) and supply 100 as the partially applied argument. Partial application in Clojure works for both single- and multiple-argument functions, as shown in the two examples in Listing 9.

Because Clojure is dynamically typed and supports variable argument lists, currying isn't implemented as a language feature. Partial application handles the necessary cases. However, the namespace private (defcurried ...) function that Clojure added to the reducers library (see Related topics), enables much-easier definition of some functions within that library. Given the flexible nature of Clojure's Lisp heritage, it is trivial to widen the use of (defcurried ...) to a broader scope.

Common uses

Despite the tricky definitions and myriad implementation details, currying and partial application do have a place in real-world programming.

Function factories

Currying (and partial application) work well for places where you implement a factory function in traditional object-oriented languages. As an example, Listing 10 implements a simple adder function in Groovy.

Listing 10. Adder and incrementer in Groovy
def adder = { x, y -> x + y}
def incrementer = adder.curry(1)

println "increment 7: ${incrementer(7)}" // 8

In Listing 10, I use the adder() function to derive the incrementer function. Similarly, in Listing 2, I use partial application to create a locally more concise version of the function.

Template Method design pattern

One of the Gang of Four design patterns is the Template Method pattern. Its purpose is to help you define algorithmic shells that use internal abstract methods to enable later implementation flexibility. Partial application and currying can solve the same problem. Using partial application to supply known behavior and leaving the other arguments free for implementation specifics mimics the implementation of this object-oriented design pattern.

Implicit values

A common case, similar to Listing 2, is one in which you have a series of function calls with similar argument values. For example, when you interact with a persistence framework, you must pass the data source as the first argument. By using partial application, you can supply the value implicitly, as shown in Listing 11.

Listing 11. Using partial application to supply implicit values
(defn db-connect [data-source query params]

(def dbc (partial db-connect "db/some-data-source"))

(dbc "select * from %1" "cust")

In Listing 11, I use the convenience dbc function to access the data functions without needing to provide the data source, which is supplied automatically. The essence of object-oriented programming — the idea of an implicit this context that appears as if by magic in every function — can be implemented by using currying to supply this to every function, making it invisible to consumers.


Currying and partial application appear in all the languages in various forms. You can use either of these techniques to make more-concise function definitions, supply implicit values, and build function factories.

In the next installment, I show the surprising similarities among all the languages' functional programming capabilities — along with the sometimes wildly different implementation details for those capabilities.

Downloadable resources

Related topics

  • Scala: Scala is a modern, functional language on the JVM.
  • Clojure: Clojure is a modern, functional Lisp that runs on the JVM.
  • What's the difference between Currying and Partial Application?: Raganwald, a popular developer blog, defines the difference between currying and partial application.
  • reducers: The reducers library is a powerful Clojure extension that enables sophisticated concurrent access for operations such as map.
  • Functional thinking: Explore functional programming in Neal Ford's series on developerWorks.
  • "Language designer's notebook:" In this developerWorks series, Java Language Architect Brian Goetz explores some language design issues that have presented challenges for the evolution of the Java language in Java SE 7, Java SE 8, and beyond.


Sign in or register to add and subscribe to comments.

Zone=Java development
ArticleID=954134 Currying and partial application