Currying is basically the concept that you can decompose a function...
e.g. f(x,y,z) = x + 2y + 3z
...into...
g(x) = x + h(y)
where h(y) = 2y + i(z)
where i(z) = 3z
Now obviously I feel a need to show off my new found skills, so I thought to myself, when would this ever be useful? I asked around and nobody seemed to have a good answer. At that point, Google was my only recourse and to my delight it actually returned a thread on Ruby Forum.
Apparently Ruby 1.9.1 has a curry method built-in (also some new syntax, which is nice) and people there were trying to figure out what it's good for.
"It's not difficult at all,
proc {|x, y, z| x + y + z }.curry
returns the proc object equivalent to
proc {|x| proc {|y| proc {|z| x + y + z } } }
""Uh, how do we call that?
...
proc{...}.call(x).call(y).call(z)
What problem does that solve?"
"this one:
plus_five = proc {|x,y,z| x + y + z }.curry.call(2).call(3)
plus_five[10] #=> 15
"I gave a good chortle at this point, because the not retarded way of doing the same thing would just be:
sum = proc{|x,y,z| x + y + x}
plus_five = proc{|x| sum[x,2,3]}
plus_five[10] #=> 15
Which is pretty much what people have been doing since forever in imperative languages. It's also more flexible because
plus_five
doesn't have to be {|x| sum[x,2,3]}
, it could just as easily be {|y| sum[2,y,3]}
.So where does this leave me? Well, I still have no idea what use currying is for. I hope someone can give me a practical example outside of Lisp, because being able to do this:
f = proc{|a,b,c| a + b + c}.curry
g = f[1][2]
puts g[3] #=> Outputs 6
...is actually pretty cool.
No comments:
Post a Comment