News for hackers. Stuff that matters.
Re:What is the advantage of currying? by crntaylor on Saturday February 02, 2013 @01:01PM (#5156712)
Here's a line of code taken from a (Haskell) Game of Life simulation I was writing just a couple of days ago [0]:

  showGrid (Grid _ ((_,b),(_,b')) arr) =
      L.intercalate "\n" $ cut (b'-b+1) $ map toChar $ elems arr
This is the full code to convert a state of the board to a string, ready to be printed to stdout. It consists of a chain of four function applications, which respectively

1. Get the elements of the array as a list (elems)

2. Convert each element to a char (map toChar ... toChar is defined elsewhere - it's also a one-liner).

3. Cut the list into sublists of the correct length (cut (b'-b+1)).

4. Join the lists together into a single string, separating them with newlines (L.intercalate "\n").

Three of the four functions are curried. I contend that without currying by default, it would take more resources (in terms of lines, characters and mental effort) to write this function.

[0] https://github.com/chris-taylor/Life

Re:What is the advantage of currying? by taeric on Saturday February 02, 2013 @02:17PM (#5156952)
Of course... I think many would say that your savings in resources came at the expense of readability. Basically, I think this falls dangerously close to Duff's device in the argument space of currying.
Re:What is the advantage of currying? by crntaylor on Saturday February 02, 2013 @03:24PM (#5157196)
Your first point is fair. Of course, 'readability' is extremely subjective. It should always be judged in terms of the intended audience for the code - we'd have to ask a Haskell programmer to be sure.

Your second point I disagree with completely. Duff's device is non-idiomatic C that relies on oddities of C syntax (fall-through of cases in a switch statement, and the ability to jump into the middle of a loop). My code is reasonably idiomatic Haskell.

Re:What is the advantage of currying? by taeric on Saturday February 02, 2013 @03:41PM (#5157255)
Apologies, I should have made the second point more on the humor side than not.

I should also stress that I don't think this being somewhat difficult to read is really bad. Just saying that I would expect a lot of folks to balk at it.

Re:What is the advantage of currying? by tikhonj on Saturday February 02, 2013 @03:40PM (#5157252)
I'm guessing that you don't find this code readable because of the $ operator. Admittedly, if you aren't used to it, it does look weird; however, once you are used to it--and it doesn't take too long--it makes the code readable.

In particular, it naturally splits apart the different function calls. So you can look at the parts separately: L.intercalate "\n", cut (b'-b+1), map toChar, elems arr. Now you have a nice little pipeline.

Perhaps to somebody without Haskell experience, the version with parentheses would be easier to understand:

    L.intercalate "\n" (cut (b'-b+1) (map toChar (elems arr)))
However, in general, I find the $ version easier to follow.

I also think that this version is better than the same code broken up into arbitrary temporary variables. The pipeline is short and clear; adding temporary bindings would just give me more things to keep in my mind at the same time.

One way to think about this is that the $ is very similar to the | in bash, just backwards. So in a bash-like pseudocode, this is something like:

    elems arr | map toChar | cut (b' - b+1) | L.intercalate "\n"
Hopefully that clarifies the structure of the code and why that structure is actually very reasonable.

Basically, my point is that the given code is clear and simple; chances are you find it hard to read because Haskell is somewhat foreign and not because the given code is particularly complicated or obfuscated. In fact, I think this way of writing the code is clearer than what you would get in most other languages because it forms a very clear sequence of transformations on the input.

Re:What is the advantage of currying? by taeric on Saturday February 02, 2013 @03:43PM (#5157264)
My main point is simply that most of the folks that do not see the benefit of currying, are not likely to be swayed by this. I muddied that by bringing up Duff's device.
Re:What is the advantage of currying? by tikhonj on Saturday February 02, 2013 @04:01PM (#5157312)
I suppose that's fair. The core problem is that the benefits of currying depend to some degree on having amenable syntax, and this means that all the examples are going to seem foreign to people.
Re:What is the advantage of currying? by taeric on Sunday February 03, 2013 @09:17AM (#5159707)
This same thought is made ridiculously clear when you try and use closure like structures in java. Especially if you have folks insisting on the @Override nonsense. Compared to languages that make full use of them, where you have to try and look for them to spot them. (Closures, that is.)
Re:What is the advantage of currying? by eliben on Saturday February 02, 2013 @11:41AM (#5156428)
This mainly makes me lament the fragmentation of the Stack Exchange network. This question, in particular, should have been on Stack Overflow. IMHO this fragmentation hurts the community. Very much.
Re:What is the advantage of currying? by michaelfeathers on Saturday February 02, 2013 @09:31AM (#5156028)
I don't think that people really see the advantage of currying until they work in an ML-derived language like Haskell. The syntax is tuned to make it easy and you get very nice design affordances.

In languages like Scala, C#, etc., currying was an afterthought and it shows. I actually think it's a shame that the Lisps make currying unnatural also. Yes, they have homoiconicity, but it's a sad tradeoff.

Re:What is the advantage of currying? by jacquesm on Saturday February 02, 2013 @08:04AM (#5155887)
I read all those answers and I'm either not getting it or there really is something missing there. Isn't the big advantage that when you use currying that all functions have an arity of '1'?

That means no more messing with varargs, named args (on the calling side), positional args, defaults and so on, every function takes one argument and one argument only, currying is then used to bypass the limitations of having only one argument to work with.

Re:What is the advantage of currying? by jerf on Saturday February 02, 2013 @10:23AM (#5156154)
There are some things in the world of programming or software engineering that are difficult to explain the cost/benefits of in a nice little blog post, because the costs or benefits don't become apparent in anything that fits in a blog post.

As you'd suspect from that lead-in, currying is one of those things. Explaining how it works is easy in a blog post, explaining why it is interesting is hard to do without being A: trivial or B: gibberish if you don't already know Haskell fairly well. Both approaches are taken in the StackOverflow there.

While it does mean you lose default and named args, it turns out to hurt less than you'd think, because the whole runtime and library is set up around functions without named args. I'm not sure exactly why, but when you can break things down into such smaller grained functions it seems to matter less. Positional is handled by a variety of functions that can reorder arguments, most commonly "flip" which switches the order of the first and second arguments, and while that is used and idiomatic it's probably used less than you'd think.

I can assure you it gets used a lot in idiomatic Haskell.

Re:What is the advantage of currying? by rwmj on Saturday February 02, 2013 @09:04AM (#5155966)
In a traditionally compiled language, currying doesn't provide varargs: the compiler still has to know how many parameters a function takes before it can be called. You cannot write `printf "%d" 1' expecting that at runtime printf is going to parse the string and read further arguments, because the compiler wouldn't know when printf can be called.

OCaml famously (or notoriously) hacks this knowledge into the compiler, so the compiler knows about format strings and parses them. This is nicely typesafe, but means you cannot use varargs in your own functions, and there are odd restrictions on the format string. (You can use the camlp4 preprocessor, or lists-as-parameters, to get around this).

Re:What is the advantage of currying? by chongli on Saturday February 02, 2013 @11:36AM (#5156411)
Haskell has printf without using lists-as-parameters. It accomplishes this by doing some very clever type-level trickery. The key idea is in the recursive definition of this instance of PrintfType:

    instance (PrintfArg a, PrintfType r) => PrintfType (a -> r) where
Re:What is the advantage of currying? by philsnow on Saturday February 02, 2013 @03:43PM (#5157263)
Your snippet got cut off, care to paste the rest? I'm guessing it works by popping the format string and the first operand off the args, and then finding the first formatting escape in the format string and formatting it, then recurse.
Re:What is the advantage of currying? by chongli on Saturday February 02, 2013 @04:52PM (#5157504)
Yeah, sorry. Here's the full snippet:

    instance (PrintfArg a, PrintfType r) => PrintfType (a -> r) where
    spr fmts args = \ a -> spr fmts (toUPrintf a : args)
And spr is a polymorphic function of the type:

    spr :: String -> [UPrintf] -> t
Essentially the way this works is that it recursively conses up a list of the arguments, calling toUPrintf on each.
Re:What is the advantage of currying? by guard-of-terra on Saturday February 02, 2013 @09:07AM (#5155977)
"the compiler still has to know how many parameters a function takes before it can be called"

I guess it's better viewed as: type system has to figure out whether a consecutive currying/calling will return a scalar/function of zero arguments.

Re:What is the advantage of currying? by pcwalton on Saturday February 02, 2013 @09:29AM (#5156023)
Defaults and named args don't really work that well with currying. OCaml ended up adding them as a separate feature (so functions are now sorta-curried, sorta-not in OCaml).

Not that currying is a bad thing, of course. For the right functional combinators (map, reduce, etc.) currying can be put to very elegant use.

Re:What is the advantage of currying? by Peaker on Saturday February 02, 2013 @08:18AM (#5155911)
The lack of named args is seen as a disadvantage. Varargs are modeled with Maybe params and such.

The main benefit is syntactic ease of partial application.

Re:What is the advantage of currying? by groue on Saturday February 02, 2013 @11:05AM (#5156278)
Another perspective of currying, from a guy that is not versed in functional programming.

I have written an expression evaluation engine whose internal implementation only manipulates functions that have a single argument. Merely value transformers.

It used to only interpret expressions like `f(x)`, `g(f(x))`. Later, functions were able to return other functions, and `f(x)(y)` was allowed. However, this last expression really looks like it would be better written `f(x,y)`. Why force the user to use a convoluted curried syntax such as `f(x)(y)` for his two-parameter function?

So the `f(x,y)` form has been added as a mere syntactic sugar. However the guts of the engine are still made of single-argument functions. That can get curried.

So currying is not only a tool for the end-user. It's also a tool for the language implementor :-)

Re:What is the advantage of currying? by huhtenberg on Saturday February 02, 2013 @07:52AM (#5155872)
It'd be nice to have a form of currying in C/C++ as applied to function pointers. Specifically, if I have

  int foo(void * bar, int baz);
then I should be able to use

  foo(, 10)
where

  int (*)(void *)
is expected.

Taking it beyond constant-based specialization would obviously require a support for closures, but I think it's a safe bet that the standard C will get it sooner rather than later.

Re:What is the advantage of currying? by Someone on Saturday February 02, 2013 @08:18AM (#5155910)
Safe bet? For C, I am not sure of that.

They would want to stay close to the metal, and have true function pointers. Creating those on the fly means having them in the data segment (or some horrendous OS-specific and likely slow hack), and that is at odds with data execution prevention.

C++ already has them, sort of. Templates accept 'anything that you can put () behind'. That includes function pointers and operator() overloads.

Re:What is the advantage of currying? by CJefferson on Saturday February 02, 2013 @08:55AM (#5155953)
In C++11, you can write bind(f,_1,10). Not quite as neat, but not bad.
Re:What is the advantage of currying? by huhtenberg on Saturday February 02, 2013 @12:47PM (#5156665)
A lot of things are possible with C++, but they are universally just that - "not quite as neat".

:)

Re:What is the advantage of currying? by manojlds on Saturday February 02, 2013 @08:22AM (#5155917)
The OP had not understood what currying is, and went about asking the question. Was expecting a more well thought question. Wonder why it was upvoted. The question itself is poor.
Re:What is the advantage of currying? by Kiro on Saturday February 02, 2013 @08:44AM (#5155940)
The answers are worse.
Re:What is the advantage of currying? by tikhonj on Saturday February 02, 2013 @12:55PM (#5156694)
What's wrong with the answers?
Re:What is the advantage of currying? by thisone on Saturday February 02, 2013 @03:16PM (#5157170)
I'm betting 99% this question is coming from someone taking the coursera "Programming Languages" course, since this week covered currying (in SML/NJ), amongst other things.

The question is poor because it specifically gives such a simple example of currying. You can't understand certain concepts without understanding when they are used, and when they aren't.

If the OP had instead said "I don't understand why List.foldl is curried instead of just accepting a tuple." Then you'd see a more productive discussion. Perhaps touching on the differences between functional language implementations.

As it is, since the question isn't formulated well, the answers are all over the place.

Re:What is the advantage of currying? by virmundi on Saturday February 02, 2013 @03:05PM (#5157129)
I've been reviewing OO patterns for my class. I've also studied Scala a bit in the last year. One thing currying seems to look like is a builder pattern for functional programming. I can start with a function that requires N number of different arguments. I can use currying to accumulate specific setting for the function over time. Eventually when I get everything actually required for the function, I can invoke it.
Re:What is the advantage of currying? by jonjacky on Saturday February 02, 2013 @02:47PM (#5157064)
"Fields in Physics are like Curried Functions, or Physics for Functional Programmers" - 1994 paper by Gary Leavens

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.49.1... (also, full paper .ps at author's web page)

Re:What is the advantage of currying? by egonschiele on Saturday February 02, 2013 @02:28PM (#5157001)
Aha, finally a place to show off my curry gem for Ruby! https://github.com/egonSchiele/Curry

Note: this was written purely for fun, don't use it in a real project!

Re:What is the advantage of currying? by markov_twain on Saturday February 02, 2013 @02:07PM (#5156921)
Why has arithmetic become the universal example of currying and partial function application?

Examples: "Currying", Section 9.3 of Programming in Scala (addition); Ruby 1.9.3 documentation for Proc#curry http://www.ruby-doc.org/core-1.9.3/Proc.html#method-i-curry (addition); "Currying" at the Haskell Wiki http://www.haskell.org/haskellwiki/Currying (division); "Currying" at Wikipedia http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_... (division); "Currying" at c2 wiki http://c2.com/cgi/wiki?CurryingSchonfinkelling (addition, multiplication); PEP 0309 for adding curry to Python http://www.python.org/dev/peps/pep-0309/ (addition); this StackExchange post; etc.

Surprisingly, searching for currying in JavaScript returns this John Resig post with actually useful examples: http://ejohn.org/blog/partial-functions-in-javascript/ although they still have no advantage over doing partial application by just defining a new function.

The only situation in which I've ever thought to myself "I know, I'll use curried functions," was in passing a set of data through a bunch of filters with different arities.

To take an example from HN's front page today, say you want to take some map of key value pairs, grab all the keys, convert them to strings, reject duplicates, sort them alphabetically, and finally concatenate them separated by commas.

Let's assume you have the following functions available (in pseudocode):

  keys(map) -> vector
  flatmap(func, vector) -> vector
  tostring(anything) -> string
  sort(sort-func, vector) -> vector
  compare-strings(string, string) -> first-is-greater, theyre-equal, or last-is-greater
  unique(compare-func, vector) -> vector
  concat(separator, vector) -> vector
and assume you have some way of connecting a list of these filter functions together like pipes, where the output of each function becomes the input of the next:

  reduce(composing-func, list-of-filter-functions, initial-input) -> final-result
Here, the composing-func takes two arguments: input, which is the output of the last iteration (or initial-input); and filter, which represents each function that will be applied in turn to produce some output. Notice that each filter function must take exactly one argument, which matches the return type of the previous filter-function in the pipeline.

  composing-func = (previous-result, filter) -> {
    apply(filter, previous-result)
  }
Now looking at our available functions, we can use currying and partial function application to pre-fill-in some arguments needed so that their input and output types line up:

  list-of-filter-functions = [
    flatmap(keys),
    map(tostring),
    unique(compare-strings),
    sort(compare-strings),
    concat(",")
  ]
And actually, we're now done. All of our filter functions have been partially applied as a sort of initialization for a complicated pipeline.

I'm guessing that currying and partial function application are useful in building parsers (like haskell & scala's parser combinators) but I don't know.

Re:What is the advantage of currying? by bcoates on Saturday February 02, 2013 @02:17PM (#5156951)
I think people use currying with arithmetic examples because currying gives you general partial application if your function is commutative, and almost the only commutative functions in real programs are arithmetic and some comparison functions.

It's kind of weird because the more arguments your function has, the more useful partial application is, and the less likely the curried form is going to work without reordering.

Re:What is the advantage of currying? by dschiptsov on Saturday February 02, 2013 @10:34AM (#5156182)
You can write fancy code in Haskell and then write long, narcissistic blog posts.)

Seriously, it is all about closures - you could capture (and delay) the computation, like creating a closure (a function with its parameters) and then actually execute the code when some other conditions were meet. Currying allows you to execute all steps but last one, for example, so you will have a returned function to call whenever you wish.

Re:What is the advantage of currying? by guard-of-terra on Saturday February 02, 2013 @09:04AM (#5155968)
Currying is a functional approach. But there is an object-oriented approach that works even better: You have a Function add object that has methods bindWith1(x) and bindWith2(y) both returning a function of one argument.

With add they do the same but with say divide they do different things (both useful).

Re:What is the advantage of currying? by michaelfeathers on Saturday February 02, 2013 @09:25AM (#5156014)
Yes, you can do that, but to me it's not as nice as having as syntax that makes it easy and natural. This is where the ML-derived languages like OCaml, F# and Haskell beat other functional languages, in my opinion.

You can argue that it's nice to be able to choose the argument to bind, but I think that's actually a bad feature. It gets rid of the design pressure to pick an order of arguments that maximizes easy composition.

Re:What is the advantage of currying? by guard-of-terra on Saturday February 02, 2013 @09:52AM (#5156085)
My experience with clojure/haskell tells me that order of arguments of common functions feels horribly wrong sometimes.
Re:What is the advantage of currying? by pohl on Saturday February 02, 2013 @11:27AM (#5156370)
I've noticed that, too. One of the answers/comments for this question suggests that (for Haskell, at least) the order of arguments is chosen to be in decreasing probability of partial application. Maybe that accounts for the odd feel.
Re:What is the advantage of currying? by michaelfeathers on Saturday February 02, 2013 @09:55AM (#5156093)
I guess there are no guarantees. Which ones are you thinking of in Haskell? There it seems to matter more.
Re:What is the advantage of currying? by guard-of-terra on Saturday February 02, 2013 @11:19AM (#5156340)
I always seem to struggle with array/list indexing functions.
Re:What is the advantage of currying? by crntaylor on Saturday February 02, 2013 @12:49PM (#5156675)
Like these?

  > let lst = [1,2,3]
  > lst!!0
  1
  > lst!!1
  2
  > let arr = listArray (0,2) [1,2,3]
  > arr!0
  1
  > arr!2
  2
I don't see how it would be particularly helpful to have the arguments to the indexing functions the other way around, but in case you really like the index coming before the list/array, you can always do

  > (!0) arr
  1
  > (!!1) lst
  2
Re:What is the advantage of currying? by jes5199 on Saturday February 02, 2013 @02:39PM (#5157035)
I was going to say that learning clojure, I get confused because some of the functions are backwards from haskell. So, I think maybe there's just not consensus about what's the best order.
Re:What is the advantage of currying? by tikhonj on Saturday February 02, 2013 @03:50PM (#5157281)
I had exactly the same experience when doing a project in Racket after using Haskell for a while. For what it's worth, I like the Haskell ordering more in most cases.
Re:What is the advantage of currying? by freyrs3 on Saturday February 02, 2013 @09:28AM (#5156021)
You can do the same in Haskell with the flip function. In fact the bindWith2 is the same as the flip function for binary functions, but without the need for "functions objects" with bound methods.

λ: (/) 2 4

0.5

λ: flip (/) 2 4

2.0