HN
Today

A Case Against Currying

This article dives deep into a fundamental functional programming concept, challenging the pervasive use of currying for multi-parameter functions. The author argues that the 'tuple style' often offers clearer semantics and better composability, despite currying's elegant partial application. It's a thought-provoking technical critique that questions established practices.

3
Score
0
Comments
#3
Highest Rank
6h
on Front Page
First Seen
Mar 22, 1:00 PM
Last Seen
Mar 22, 7:00 PM
Rank Over Time
739111115

The Lowdown

In "A Case Against Currying," emih presents a detailed argument against the widespread adoption of curried functions in functional programming, proposing the 'tuple style' as a superior alternative for many common scenarios. While acknowledging the elegance and natural support for partial application that currying offers, the author systematically breaks down its perceived advantages and highlights its practical drawbacks.

  • Defining Currying: The article begins by explaining currying as an inductive way to define n-parameter functions as a sequence of single-parameter functions, contrasting it with the 'parameter list' (imperative) and 'tuple' styles.
  • Challenging Partial Application: A key argument for currying is its straightforward partial application. However, emih demonstrates that partial application is also achievable and potentially more flexible with the tuple style, especially with syntactic sugar like a 'hole operator' ($), which can fix non-initial parameters more easily.
  • The 'Cool' Factor: The author speculates that the appeal of currying might partly stem from its perceived intellectual elegance and 'coolness' among functional programmers, rather than purely pragmatic reasons.
  • Arguments Against Currying: Several disadvantages are outlined:
    • Performance: Potential overhead from creating intermediate function closures.
    • Asymmetric Type Shape: Curried types (P1 -> P2 -> R) are seen as less logical than tupled types ((P1, P2) -> R) because they treat inputs and outputs differently, making composition with generic higher-order functions like map awkward.
    • Composition Difficulties: This asymmetry often requires explicit uncurry operations when composing with functions that expect a single In -> Out type.
    • Proof Assistant Frustrations: The author shares personal experience where curried functions in proof assistants (like Rocq) caused type unification issues, necessitating manual uncurrying.
  • When Currying Excels: Acknowledging its strengths, the article notes that currying is genuinely superior for dependent function types in dependently-typed languages (e.g., Gallina, Agda), where the type of a parameter or return value can depend on the value of a preceding parameter.

Ultimately, while the author recognizes the deeply entrenched nature of currying in existing functional languages, they encourage the consideration of the tuple style—potentially with expressive partial application syntax—when designing new functional languages or libraries, suggesting it offers a more pragmatic and often clearer approach for most use cases.