Hacker News new | ask | show | jobs
Can we stop calling it currying?
14 points by jonlachlan 4105 days ago
I recently learned what the heck "currying" means. I'm sure I'm not the only one who struggled to grasp what this term means, since its name does not come from an intuitive notion of the concept, but rather it is named after Haskell Curry who first explored this approach.

A curried function allows an incomplete argument list, in which case it returns a new function that is still awaiting the missing arguments. This allows you to compose (combine) functions into new, reusable functions. A powerful tool for programmers, and yet unfortunately we give it a name that often reminds us of curry the food and nothing else.

Can we stop calling it "currying" then and instead call it something meaningful? How about Argument-Deferred Functional Composition, or my preferred shorthand: argument deferral.

Obviously, the name "currying" and "curried function" is widespread, so it would be appropriate to say argument deferral (i.e., currying) or argument-deferred function (i.e., curried function).

Am I right to have a pet peeve about this, or should stop programming and go into marketing?

15 comments

Why call them 'arguments' when nobody is arguing?

Currying is the name of the thing. Adding another Enterprise Edition Operational Process Development Pattern like "argument deferral" isn't any better. I mean "Dependency Injection" isn't any easier for beginners to grasp, even though that is what it is.

Besides, it isn't argument deferral. That could easily be confused with evaluation order or things like lazy/normal/strict evaluation.

+1 for "Enterprise Edition Operational Process Development Pattern"
From the perspective of a non-functional language, it is argument deferral because you're composing your sequence of functions first, which can then be used by later adding inputs for evaluation.

Were you thinking of partial application (not the same as currying)? I would agree that this is not argument deferral, rather it's more like argument presetting.

No, I was thinking about what I said: evaluation order and evaluation method.

For instance, if I had a function like

    func(a,b)
with the semantics that a would be evaluated before b, it would be perfectly reasonable to allow someone to evaluate argument b first instead. Thus 'argument deferral': you defer the evaluation of a until after b.

The second case is about when the arguments are evaluated: do you evaluate them when the function is called, or do you defer evaluation until when they are used? This is obviously 'argument deferral' as well, but we usually call it lazy evaluation.

http://en.wikipedia.org/wiki/Evaluation_strategy

The term 'Argument deferral' could apply perfectly well to a discussion of Evaluation Strategy, even though that has little to do with currying.

"Argument deferral" of the type you describe (like partial application, for that matter) is something currying can be used to achieve, but is not what currying is.

So, even if it was proposed when "currying" wasn't well established as the name for currying, it wouldn't be a particularly good choice.

I agree, I've revisited my position. Argument deferral and partial application (my term: argument presetting) is something that currying can achieve, but it's not what currying is.
"Call 'it' something 'meaningful'"?? "Currying" is meaningful...

Perhaps you just aren't comfortable with the idea that its meaning wasn't formed via some sort of compounding pattern you thought would be more inherently meaningful(?), or maybe you feel the need for natural language to be as precise as your programs?

There are lots of different ways that new words come into a language, and one of them is "verbificiation" of a noun (sometimes even a proper one). In this case, Haskell Curry was "verbified", and so now we have "currying". I don't care to speculate as to why "currying" was favored over "some-compounding-of-words-that-you-think-precisely-conveys-the-exact-meaning", but I assure you the first person to use "currying", did it because they thought in that moment that that was the best way to meaningfully convey the idea they were talking about, and the others around that person (implicitly) agreed by using it too. If you really think you can do better, start calling it something else; if it's any good, it'll catch on.

I've read any number of peeves against certain forms of language use, and don't agree that that necessarily pigeonholes someone into marketing.

Lisp, for example, uses 'car' and 'cdr' because of the hardware registers of the IBM 704. Some prefer 'first' and 'rest', but compact composed versions like '(cadr x)' for (car (cdr x)) don't exist for those English variants.

"to curry" as a verb has advantages over your preferred term of "argument deferral", if only because I can write:

  def curry(f, *curry_args):
      def curried(*args):
          return f(curry_args + args)
      curried.__name__ = "curried_" + f.__name
      return curried
using a one word function name instead of "argument_deferral". (I've also seen 'xapply' in Python code, as in http://bytecodehacks.sourceforge.net/bch-docs/bch/module-byt... ).

It also has the inverse 'uncurry', mentioned in https://downloads.haskell.org/~ghc/6.12.2/docs/html/librarie... .

Your version would be "undefer the argument deferred function", I believe, vs. "uncurry the curried function". Not only is it longer, but I see a possible ambiguity: "undefer" might mean to actually call it.

In general though, there is a lot of specialized vocabulary. "A trampoline is a loop that iteratively invokes thunk-returning functions". "I used an AVL tree in the hidden Markov model." I don't see how the big problem is the inability to understand the concept from lexical decomposition of the term.

'To curry' also already was a verb, and as a bonus, that verb has the connotation of 'adding something'. To curry a function, you add a value for its first argument. That helped it become popular. I don't think this would have survived if it would have been called 'to Knuth', 'to Kernighan', or 'to Jensen' (in general, names for stuff one adds in moderation to something larger to improve it give good names for small things one adds to something larger: 'salt' in cryptography and 'syntactic sugar' are other examples)

"Some prefer 'first' and 'rest', but compact composed versions like '(cadr x)' for (car (cdr x)) don't exist for those English variants."

It may be lack in my mastery of English, but AFAIK, 'cadr' didn't exist, either, but that didn't stop it from becoming the standard way to describe the second item in a list.

If they had used first and rest, we likely would have frest and frrest for cadr and caadr, and I wouldn't rule out 'rfirst' either; it is not as if that is harder to pronounce than 'cdar'.

Your description refers to "partial application", which is different from currying. I think that many people are comfortable with "currying" only because they think it's the same as partial application. The fact that this is incorrect is good reason to revisit the term.
Another name for currying is "partial application". See http://en.m.wikipedia.org/wiki/Partial_application
This a common misconception. Partial application is like taking f(x, y) = x + y and turning it into f(y) = 1 + y by supplying x = 1. Currying is like taking the same function and turning it into (f(x))(y) = x + y. Expressing f as a higher-order single argument function in this way gives us the advantages of partial application using normal total application.

A good example is the derivative function from calculus, which could be specified in at least two obvious ways. A simple, but ugly solution is to have it take a function and a point as arguments and return the value of the derivative at that point.

Alternatively, it could take a function and return its derivative as a function, which could then be evaluated at many different points.

This is the difference between e.g.

(Float -> Float, Float) -> Float, and (Float -> Float) -> (Float -> Float).

Taking this idea to its logical conclusion and applying it to any multiple argument function gives you currying.

not quite the same thing- currying turns polyadic function into a sequence of unary functions, whereas partial application gives you a function with a couple arguments filled already
You're right, it should be called Schönfinkeling http://en.wikipedia.org/wiki/Moses_Sch%C3%B6nfinkel
To answer your question, I don't think it matters what it's called, just that you learn what it means (just like any word).

As an aside, what you're describing isn't strictly currying. The key insight of currying is that a function of multiple arguments can be decomposed in to a series of function applications where each function takes only one argument - this is related to but not the same as partial application.

Thanks for this clarification. The fact that these are widely confounded is evidence that many people are comfortable with the term "currying" only because they think it's the same as "partial application", so they appreciate the connotation that you're "adding spice".

So in this case, not only CAN these people stop calling it "currying", but in fact they should, because it's the wrong word.

In my other comment I'm suggesting calling currying "sequencing", and partial application "presetting".

Sometimes you do not want an understandable name for a thing... instead a merely memorable one is far better.

Currying is actually an incredibly specific and universal thing. It's the act of noting that a function space

    (a, b) -> c
is the same as a "higher-order function space"

    a -> (b -> c)
in a very particular way. It's worth it to give this thing it's own name because it's a highly important and unique transformation.

"Curring" and partial application as it exists which take this notion further, such as those which transform (a, b, c) -> d to (a -> b -> c -> d) or (a, b, c) -> d to ((a, c) -> b -> d) are generalizations of the core concept and perhaps don't honestly deserve the name (if you're a stickler).

Merely calling currying and uncurrying by some operational name de-emphasizes these operations. It's like calling a "home run" a "quadruple" in baseball. Sure, it makes sense, but it's really just missing something.

This makes sense. But would you say that there could be easier shorthand descriptors to supplement the terms? Or perhaps terms that are used to describe the utility of currying, but don't actually replace the specific (and useful) term?
I think it's fair to say that pithy ways of explaining the point and mechanism of currying are important. The terms you've been exploring here are definitely in that bucket.
the name isn't the difficult part, so changing it will not make it easier for people to grok.
I don't recall currying -- either the name or the concept -- being a particular stumbling-block for beginners trying to learn functional programming.

There isn't really a problem that needs solving here.

Some languages, like ML family or Haskell, make it an organic part of the language, so beginners doesn't need to worry about the concept to use it.

When first exposed to ML/Haskell code, they may use simple mental models such as "you write function arguments without parens and commas" and "the last type in foo -> bar -> baz is the return type". Then it gets replaced with realization that "oh, so 'let f x y = x + y' is just a sugar for 'let f = fun x -> fun y -> x + y'".

If one is learning the concept in a language that supports functions of multiple arguments and uses something else than currying for built-in partial application mechanism, I can imagine them having problems with it. Learning how familiar things works internally is usually easier than learning "this is what you can do and why you may want it".

Actually it is the lack of currying that is a stumbling block when you go back to a language that doesn't have it.
Another name for this technique is "partial application".
No it is not. For an explanation see http://www.uncarved.com/blog/not_currying.mrk
Can "we" stop using the term because "I" don't like it?
Thanks everyone for the comments. It is interesting to see how widely "currying" is conflated with "partial application". I have to say, I still find the name to be a stumbling block. Perhaps this discussion can help to reverse that trend.

I have also learned a good deal more from these comments and further research. It seems my idea of "currying" was not entirely complete. Per the comment herein: "Currying turns polyadic function into a sequence of unary functions". Practically speaking, this means a curried function is a single-input function that will return a function which is still awaiting an argument, so that other functions can be added to the "currying chain".

I would call this "function sequencing". This term could be equally intuitive for functional languages (ML / Haskell) and non-functional languages alike. However, I think that non-functional language users will still appreciate an explanation that references "argument deferral", since this is one of the practical benefits, and is also the key part of the "functional" context-switch needed to understand the concept (i.e., you can compose functions without providing the arguments/inputs).

Is there an equivalent to "uncurrying"? (un-what-ing??) This verbiage sounds like we're trying to unpluck a chicken. On Wikipedia (the world's collective brain dump), we understand uncurrying to be "the dual transformation to currying, and can be seen as a form of defunctionalization." Crystal. I'll losely interpret this as flattening the unary (single-input) function sequence into one polyadic (multi-input) function. So can we refer to this as "function bundling"?

To summarize, I'm submitting "sequencing" and "bundling" as the two simple verbs that better describe "currying" and "uncurrying".

> To summarize, I'm submitting "sequencing" and "bundling" as the two simple verbs that better describe "currying" and "uncurrying".

"Currying" and "uncurrying" are widely understood by programmers, and "sequencing" and "bundling" are often used in programming for other things, so your idea reduces clarity in favor of some aesthetic preference to avoid turning proper names into verbs when creating new technical terms.

So, I think we're better off just sticking with currying and uncurrying.

Good thoughts. I'm interested to see if there are other opinions.
As a related extension, though I don't think "partial application" is a bad term, I can also think of it as "presetting arguments", so there you go, my last submission is to call this "presetting".
A little surprised by the resistance to your suggestion. Apparently I too am doomed to retire into marketing after 30 years of programming.
Completely agree. It is atypical in any progamming language to have names of functions/operators that do not bear some relation with the nature of the function/operation.

While your suggestion suffers from a lack of concision, the point remains: A single word replacement that approximates the nature of what "currying" does, would be helpful.

See my longer comment. I'm suggesting "sequencing" and the opposite, "bundling".
That's why Clojure calls it "partial" to indicate you're doing partial application http://conj.io/store/v0/org.clojure/clojure/1.7.0-alpha4/clj...
Partial application isn't currying; partially applying a function f to a first argument x is equivalent to currying f, applying the resulting unary function to x, and uncurrying the function that results from that application.

So, partial application can be defined in terms of currying, application, and uncurrying, but its not the same as currying.

Was posting to suggest exactly that, it's also what Python calls it (https://docs.python.org/2/library/functools.html#functools.p...), and a "partially evaluted / filled out" function basically encapsulated the whole concept.
Again, your description refers to "partial application", which is different from currying. I think that many people are comfortable with "currying" only because they think it's the same as partial application. The fact that this is incorrect is good reason to revisit the term.
> I think that many people are comfortable with "currying" only because they think it's the same as partial application.

If currying was the same as partial application, I'd say we don't need the name "currying" and can just use "partial application". So I guess you could say that I am comfortable with currying only because I don't think it is the same as partial application.

Good point. It's a bit of a wonder why so many people think of them as equivalent (perhaps they thought currying was a convenient shorthand for partial application). I'm comfortable with a simple campaign to clarify the difference, and I think my suggested terms would be helpful to accomplish that (so rather than replacements, simply informal descriptions of the term).
Schönfinkelisation is my preferred alternative.