What is curry?

Currying is a technique in programming where a function that normally takes several arguments is transformed into a chain of functions, each taking just one argument. The result is a series of nested functions that remember the arguments they received until all required inputs are provided, at which point the original computation is performed.

Let's break it down

Imagine a normal function add(a, b) that returns a + b. After currying, it becomes addCurried(a)(b). First you call addCurried with the first argument (a); this returns a new function that expects the second argument (b). When you finally supply b, the inner function adds the two numbers and returns the result. In code: function add(a, b) { return a + b; } const addCurried = a => b => a + b; let addFive = addCurried(5); // returns a function waiting for the second number let result = addFive(3); // result is 8

Why does it matter?

Currying makes it easy to create specialized versions of a generic function without rewriting code (partial application). It also encourages a functional style where small, single‑argument functions can be composed together, leading to clearer, more reusable code. In large codebases, this can reduce duplication and simplify testing.

Where is it used?

  • Functional programming languages like Haskell and Elm use currying by default.
  • JavaScript libraries (e.g., Ramda, Lodash/fp) provide curried utilities.
  • In React, hooks such as useCallback often rely on partially applied functions.
  • Python’s functools.partial mimics currying for specific use cases.
  • Many functional‑style APIs in Scala, F#, and Clojure encourage curried functions.

Good things about it

  • Enables partial application, letting you pre‑fill some arguments.
  • Improves function composition and pipeline creation.
  • Leads to more modular, testable code.
  • Often results in cleaner, more expressive APIs.
  • Works well with immutable data and pure functions, core ideas of functional programming.

Not-so-good things

  • Can be harder for beginners to read, especially when functions are deeply nested.
  • May introduce slight performance overhead due to extra function calls.
  • Debugging stack traces can become more complex.
  • Over‑use can lead to overly abstract code that’s difficult to maintain.