views:

565

answers:

4

I Just can't seem to wrap my head around them.

As I understand it's dynamicly adding logic to a class. Are classes within the framework prepaired for this?

Why should I just extend the class and add the funtionality to it in the extention. I would be globally accessable and afaik much easier to maintain.

I've Read there are 4 functor types:

Comparer
Closure
Predicate
Transformer

We should probably Handle each one of them.

p.s. is there something like it in vb?

So I can state I think that lambda expressions are functors. This clears up things for me a bit :) (hehe)

  • Lambda expressions are functors?
  • Anonymous functions are functors?

But I asked this question because I ran into another type of fucntors namely these ones:

delegate void FunctorDelegate(int value);
class Addition {
    FunctorDelegate _delegate;

    public Addition AddDelegate(FunctorDelegate deleg) {
        _delegate += deleg;
        return this;
    }
    public int AddAllElements(IList< int> list) {
        int runningTotal = 0;
        foreach( int value in list) {
            runningTotal += value;
            _delegate(value);
        }
        return runningTotal;
    }
}

And then calling it with this:

 int runningTotal = new Addition()
     .AddDelegate(new FunctorDelegate(
                     delegate(int value) {
                         if ((value % 2) == 1) {
                             runningOddTotal += value;
                         }
                     }))
    .AddDelegate(new FunctorDelegate(
                     delegate(int value) {
                         if ((value % 2) == 0) {
                             runningEvenTotal += value;
                         }
                     }))
    .AddAllElements(list);

So no fancy lambda style things.

Now I have this example but it isn't at all clear why this is a "good" solution.

Are delegates (functors) used as lambda expressions or anonymous methods "in most cases" just there as a shortcut for the programmer? There are as far as I can see only a few cases where they're actually the prefered choice for a problem.

+4  A: 

In .NET terms, I think what you are describing is the Delegate - and it exists in all of .NET, not just C#.

I'm not sure that a "closure" would a "type" in the same was as a comparer/predicate/transformer, since in C# terms a closure is simply an implementation detail but can be any of those three.

In .NET, delegates are used in two main ways:

  • as the eventing mechanism
  • to provide functional-style programming

The first is important, but it sounds like you are more interested in the second. In reality, they operate much like single-method interfaces... consider:

List<int> vals = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
List<int> evenVals = vals.FindAll(i => i % 2 == 0); // predicate
List<string> valsAsStrings = vals.ConvertAll(i => i.ToString()); // transformer
// sort descending
vals.Sort((x, y) => y.CompareTo(x)); // comparer

A closure is more where we bring additional scope from outside the delegate into the delegate:

int max = int.Parse(Console.ReadLine()); // perhaps 6
List<int> limited = vals.FindAll(i => i <= max);

here the max is captured into the delegate as a closure.

Re "Are classes within the framework prepaired for this?" - many are, and LINQ goes a long way to allowing this even wider. LINQ provides extension methods over (for example) all of IEnumerable<T> - meaning that collections without delegate-based access aquire them for free:

int[] data = { 1,2,3,4,5,6,7,8,9 };
var oddData = data.Where( i => i % 2 == 1 );
var descending = data.OrderBy(i => -i);
var asStrings = data.Select(i => i.ToString());

Here the Where and OrderBy methods are LINQ extension methods that take delegates.

Marc Gravell
Hi thanks for the answer.I knew they have things to do with delegates. I don't think it possible to do any serious c# programming without running into delegates. I've mainly used them for async functions and events. But I asked this question because I ran into another form of functors. I didn't know the linq like predicate stuff were functors aswell. I'll update the question about the styles.
the_ajp
The LINQ stuff is... complicated ;-p The extension methods on IEnumerable<T> use delegates, but the extension methods on IQueryable<T> use Expression trees, which look identical to the caller (assuming they are using either lambda statements or query syntax) but which are **completely, 100%** different ;-p
Marc Gravell
So only part of the linq lamba expression things are functors. riiiight. :) I Love the guy that thought that was a good idea :P It works, and I use the stuff daily, but how or why it works only a few people really know :)
the_ajp
No... that isn't it; a lambda-delegate is a functor, as is an anonymous method, as is a regular method. The difference is the subtle difference between Func<...> and Expression<Func<...>>: http://marcgravell.blogspot.com/2009/03/explaining-expression.html
Marc Gravell
That is a very interesting post although it probably requires a bit more reading to fully understand it. Like you said you covered a lot in a small(ish) space. But it's definately clearer now what and why functors are.
the_ajp
A: 

I'm sure you mean Lambda Expressions. Those are Small Functions you can write very quickly, and they have the characteristic "=>" Operator. These are a new Feature of C# 3.0.

This Example will be a classic Transformer; to use one we need a delegate to define the signature for the Lambda Function.

delegate int Transformer(int i);

Now Declare a Lambda with this delegate:

Transformer sqr = x => x * x;

We can use it like a normal function:

Console.WriteLine(sqr(3)); //9

These are used in LINQ Queries a lot, for example to Sort (Comparer), to Search through (Predicate).

The book "C# Pocket Reference" (apart from beign the best around in my opinion, has a very good part on Lambdas. (ISBN 978-0-596-51922-3 )

wsd
As an aside - with .NET 3.5 it would be more common to use a Func<int,int> than to define a new Transformer delegate to do the same thing...
Marc Gravell
It's not only lambda expressions. As we've established (I think) only part or the lambda expressions are actually functors.
the_ajp
+1  A: 

Interesting with terminology; my spontaneous interpretation of the term "Functor" was that it referred to anonymous methods. So that will be my take on it.

These are some of my typical uses:

Comparisons (usually for sorting a list):

List<int> ints = new List<int>();
ints.AddRange(new int[] { 9, 5, 7, 4, 3, 5, 3 });
ints.Sort(new Comparison<int>(delegate(int x, int y)
    {
        return x.CompareTo(y);
    }));
// yes I am aware the ints.Sort() would yield the same result, but hey, it's just
// a conceptual code sample ;o)

// and the shorter .NET 3.5 version:
ints.Sort((x, y) =>
{
    return x.CompareTo(y);
});

I will use this approach for comparisons, rather than having it in its own method an using a delegate for that method, in the cases where this particular sort happens in one place only. If it is likely that I will want to use the same comparison somewhere else, it gets to live in its own, reusable method.

Another of my fairly common uses is in unit testing, when the test relies on some event being raised. I have found that to be essential when unit testing workflows in Workflow Foundation:

WorkflowRuntime runtime = WorkflowHost.Runtime;  
WorkflowInstance instance = runtime.CreateWorkflow(typeof(CreateFile)); 
EventHandler<WorkflowEventArgs> WorkflowIdledHandler = delegate(object sender, WorkflowEventArgs e)
{
    // get the ICreateFileService instance from the runtime  
    ISomeWorkflowService service = WorkflowHost.Runtime.GetService<ISomeWorkflowService>();

    // set the desired file content  
    service.DoSomeWork(instance.InstanceId, inputData);
};  
// attach event handler
runtime.WorkflowIdled += WorkflowIdledHandler;  

instance.Start();  
// perform the test, and then detach the event handler
runtime.WorkflowIdled -= WorkflowIdledHandler;

In this case it is simpler to have the event handler declared as anonymous methods since it uses the instance variable that is defined in the unit test method scope. Had I intstead opted to implelment the event handler as its own separate method I would also need to figure out a way for it to pick up instance, probably by introducing a class level member, which would not seem like a perfect design in a unit test class.

There are more cases where I find this in my code, but they usually have one or two things in common:

  • I have no interest in referencing that piece of code from anywhere else than in that particular place.
  • The method needs access to data that would be out of the scope for a regular method
Fredrik Mörk
This look more like what I initially thought were functors. I think the last two sentances of your post really hit ground with me this explains why I would use functors/anonymousmethods/lambdaexpression.
the_ajp
+4  A: 

I think you're confusing terms from different languages. You seem to be using "Functor" in the C++ or Java sense, e.g. see the wikipedia page. In C++, it's an object of a class that overloads the function-call operator, so it can be used as a function but with state.

This is logically the same thing as a delegate bound to an instance method in C# (or any .NET language).

There are three ways to write such a thing. First, you can write an ordinary method, and then assign the name of the method to a delegate variable.

void MyMethod() { Console.WriteLine("Hi!"); }

void Foo()
{
    Action a = MyMethod;
    a();
}

Second, you can use anonymous method syntax, introduced in C# 2.0:

void Foo()
{
    Action a = delegate { Console.WriteLine("Hi!"); }
    a();
}

Thirdly, you can use lambda syntax, introduced in C# 3.0:

void Foo()
{
    Action a = () => Console.WriteLine("Hi!");
    a();
}

The advantage of the last two is that the body of the method can read and write local variables in the containing method.

The advantage of lambda syntax over anon-methods are that it is more succinct and it does type inference on parameters.

Update: The advantage of anon-methods (delegate keyword) over lambdas is that you can omit the parameters altogether if you don't need them:

// correct way using lambda
button.Click += (sender, eventArgs) => MessageBox.Show("Clicked!");

// compile error - wrong number of arguments
button.Click += () => MessageBox.Show("Clicked!");

// anon method, omitting arguments, works fine
button.Click += delegate { MessageBox.Show("Clicked!"); };

I know of only one situation where this is worth knowing, which is when initializing an event so that you don't have to check for null before firing it:

event EventHandler Birthday = delegate { };

Avoids a lot of nonsense elsewhere.

Finally, you mention that there are four kinds of functor. In fact there are an infinity of possibly delegate types, although some authors may have their favourites and there obviously will be some common patterns. An Action or Command takes no parameters and returns void, and a predicate takes an instance of some type and returns true or false.

In C# 3.0, you can whip up a delegate with up to four parameters of any types you like:

Func<string, int, double> f;  // takes a string and an in, returns a double

Re: Updated Question

You ask (I think) if there are many use cases for lambdas. There are more than can possibly be listed!

You most often see them in the middle of larger expressions that operate on sequences (lists computed on-the-fly). Suppose I have a list of people, and I want a list of people exactly forty years old:

var exactlyForty = people.Where(person => person.Age == 40);

The Where method is an extension method on the IEnumerable<T> interface, where T in this case is some kind of Person class.

This is known in .NET as "Linq to Objects", but known elsewhere as pure functional programming on sequences or streams or "lazy" lists (all different names for the same thing).

Daniel Earwicker
right. Now we're getting somewhere. So functors (as in the name) do not really exsist in .net they are delegates.The succinctness of lambda is I think personal flavour I don't mind typing more to keep it readable. But the type inferance is ever so cool and is a definite pro for the lambda flavour. I'll add a bit more to my question.
the_ajp
Thanks for accepting, I added a bonus update about omitting arguments to delegate.
Daniel Earwicker
Thanks :) I think we did a great job clearing this up and making a case for lambdas, delegates and anonymous functions. Where I work they're v. scared of this stuff. But hey you can't stop the future right. :).
the_ajp