16

What is the advantage of Currying in C#?

What is the advantage of achieving partial function application on a curried function?

masoud ramezani
  • 22,228
  • 29
  • 98
  • 151
  • 6
    @Mitch: SO is a place for asking questions, isn't it? It's not like he's asking what the parameters to a particular API call are (e.g., where a search would find him the API documentation), he's asking what it's useful for. I expect he could find that info if he searched thoroughly, but that's true for a *lot* of what's asked on SO. If we closed all of those questions... ;-) – T.J. Crowder Mar 08 '10 at 14:57
  • 1
    See http://blogs.msdn.com/wesdyer/archive/2007/01/29/currying-and-partial-function-application.aspx and then http://blogs.msdn.com/ericlippert/archive/2009/06/25/mmm-curry.aspx – Eric Lippert Mar 08 '10 at 14:58
  • 1
    @masoud - are you really asking "why would I ever want to do this?" – Jeff Sternal Mar 08 '10 at 15:07

5 Answers5

14

If your question was how to implement currying in C# , here is an example

public Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(Func<T1, T2, TResult> func)
    {
        return p1 => p2 => func(p1, p2);
    }

Currying can be implemented in any language that supports closures(lambdas), and is useful for partial function application like in UI programming where all the input necessary for the execution of function isnt received, so a curried function is passed around with already received inputs captured in it.

Nagaraj
  • 131
  • 4
  • 3
    Nice clean example and btw you Can curry in any language that has an abstract representation of a method. So C# pre lambda or c++ Can be used tho more work is required up front – Rune FS Mar 08 '10 at 15:18
  • for further clarification see: http://blogs.msdn.com/b/wesdyer/archive/2007/01/29/currying-and-partial-function-application.aspx – Jordan Apr 07 '14 at 12:21
12

From Wikipedia

Currying is actually not very different from what we do when we calculate a function for some given values on a piece of paper.

Take the function f(x,y) = y / x

To evaluate f(2,3), first, replace x with 2.

Since the result is a new function in y, this function g(y) can be defined as

g(y) = f(2,y) = y / 2

Next, replacing the y argument with 3,

provides the result, g(3) = f(2,3) = 3 / 2.

On paper, using classical notation, it's just that we seem to do it all at the same time. But, in fact, when replacing arguments on a piece of paper, it is done sequentially (i.e.partially). Each replacement results in a function within a function. As we sequentially replace each argument, we are currying the function into simpler and simpler versions of the original. Eventually, we end up with a chain of functions as in lambda calculus, where each function takes only one argument, and multi-argument functions are usually represented in curried form.

The practical motivation for currying is that very often the functions obtained by supplying some but not all of the arguments to a curried function (often called partial application) are useful; for example, many languages have a function or operator similar to plus_one. Currying makes it easy to define these functions.

David Pfeffer
  • 38,869
  • 30
  • 127
  • 202
David
  • 72,686
  • 18
  • 132
  • 173
1

I've found partial function application, as opposed to currying, to be useful when I want to reuse code.

To be clear, since the definitions of currying and partial function application seem to get blurred, by partial function application I mean taking a function with N parameters, and converting it into a function with N-1 parameters.

In particular, it's been handy when writing unit tests. Since I'll be writing hundreds of unit tests I try to reuse test code wherever possible. So I may have a common test method that takes a delegate to a method I wish to test, plus some parameters to that method and an expected result. The common test method will execute the method under test with the supplied parameters, and will have several assertions comparing the result to the expected result.

The problem comes when I want to test a method that has more parameters than the delegate being passed into the common test method. I could write another common test method which is identical to the first one, apart from taking a delegate with a different signature. That seems like repeating myself, however. To avoid having to write such duplicate code, I can use partial function application to convert a delegate taking, say, two parameters, into a delegate taking a single parameter. Now I can use my common test method to test methods that take either one or two parameters.

Here's one of the helper methods I use to fix one of the arguments of the delegate that was passed in:

/// <summary>
/// Fixes an argument of an action delegate, creating a closure that combines the 
/// delegate and the argument value. 
/// </summary>
/// <returns>An action delegate which takes only one argument.</returns>
public static Action<TIn1> FixActionArgument<TIn1, TIn2>(Action<TIn1, TIn2> action, 
    TIn2 argumentValue)
{
    return in1 => action(in1, argumentValue);
}
Simon Elms
  • 17,832
  • 21
  • 87
  • 103
0

The advantage of Currying in C# is that it allows C# developers to develop in a Functional Programming style.

Think about LINQ. A LINQ query allows you to pass in a method as a parameter:

someCollection.Where(x => x.someVal == 1);

x.someVal == 1 gets evaluated as a function and then Where uses the return value in its own execution.

It's an example that most .NET 3 developers are familiar with, but few realize that they're dabbling in Function Programming. Without the ability to Curry, LINQ wouldn't be possible.

...hopefull that makes up for my smart-ass comment.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
  • thank you for your useful answer. unfortunately somebody stand in OS to close the questions. – masoud ramezani Mar 08 '10 at 15:09
  • 20
    I don't see where you are using currying there. – alternative Jul 11 '11 at 15:36
  • 3
    "currying effectively decomposes the function into functions taking a single parameter" source: http://msmvps.com/blogs/jon_skeet/archive/2012/01/30/currying-vs-partial-function-application.aspx Linq is an example of simply passing functions, sometimes with multiple parameters. – Opflash Feb 20 '12 at 11:05
  • 1
    `Where` is a function that takes a function, the lambda syntax returns a function, _not_ the result of the function. It is up to the `Where` function whether or not the function is called at all (i.e., it may decide not to call the lambda function when the collection is empty). This has little to do with currying or PFA, though it does have a lot to do with functional programming. – Abel May 29 '13 at 13:02
  • @Abel - You're correct. Unfortunately, I didn't fully understand Currying before answering this question (over three years ago). I would delete it, but it's an accepted answer which means I can't. I also don't want to significantly change the answer since it would change the meaning. – Justin Niessner May 29 '13 at 14:22
  • 2
    Just to add to the above comments: what you describe is not currying. Please update your reply to avoid misleading others (especially because this is the accepted answer). – Zoman Dec 19 '13 at 13:27
-1

A simple Currying will be

using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {

            Func<double, double, double, double, double> newTonLaw = (m1, m2, r, g) => ((m1 * m2) / Math.Pow(r,2)) * g;

            // Mass of Earth= 5.98 * 10e24 , Gravitational Constant = 6.6726 * 10e-11
            Func<double, double, double> onEarth = (m2, r) => newTonLaw.Invoke(5.98 * 10e24, m2, r, 6.6726*10e-11);

            // Mass of Moon= 7.348x10e22 , Gravitational Constant = 6.6726 * 10e-11
            Func<double, double, double> onMoon = (m2, r) => newTonLaw.Invoke(7.348 * 10e22, m2, r, 6.6726 * 10e-11);

            Trace.WriteLine(onEarth(70, 6.38 * 10e6)); // result 686.203545562642
            Trace.WriteLine(onMoon(70, 6.38 * 10e6)); // result 8.43181212841855
        }
    }
}
zawhtut
  • 8,335
  • 5
  • 52
  • 76