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?
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.
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.
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.
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.
There isn't really a problem that needs solving here.
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".
So, partial application can be defined in terms of currying, application, and uncurrying, but its not the same as currying.
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.
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".
"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.
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.
"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'.
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.
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.
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.
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".
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.
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.