Search code examples
scala

Difference between currying and higher-order functions


Looking at Programming in Scala (control abstraction) I saw these two examples that have the same effect:

1. Higher-Order Function

def withPrintWriter(file: File, op: PrintWriter => Unit) {
  val writer = new PrintWriter(file)
  try {
    op(writer)
  } finally {
    writer.close()
  }
}

2. Currying function

def withPrintWriter(file: File)(op: PrintWriter => Unit) {
  val writer = new PrintWriter(file)
  try {
    op(writer)
  } finally {
    writer.close()
  }
}

What is the difference between them? Can we always achieve the same result in both ways?


Solution

  • The concepts of higher-order functions and curried functions are generally used in an orthogonal way. A higher-order function is simply a function that takes a function as an argument or returns a function as a result, and it may or may not be curried. In general usage, someone referring to a higher-order function is usually talking about a function that takes another function as an argument.

    A curried function, on the other hand, is one that returns a function as its result. A fully curried function is a one-argument function that either returns an ordinary result or returns a fully curried function. Note that a curried function is necessarily a higher-order function, since it returns a function as its result.

    Thus, your second example is an example of a curried function that returns a higher-order function. Here's another example of curried function that does not take a function as an argument, expressed in various (nearly equivalent) ways:

    def plus(a: Int)(b:Int) = a + b
    def plus(a: Int) = (b: Int) => a + b
    val plus = (a: Int) => (b: Int) => a + b