Lambda in C# 3.0

Maybe on the edge of being off-topic, but I figure that since this place is called Lambda-the-Ultimate, perhaps questions about lambda in evolving languages might be tolerated.

I've been hearing that the next-gen of C# was supposed to add support for lambdas, so I downloaded the beta. Starting out, it looks rather hopeful.

delegate int IntToInt(int i);

static IntToInt Factorial = 
    (n) => n <= 1 ? 1 : n * Factorial(n - 1);

First inconvenience is that I have to declare delegates that match the signature of any lambda functions I want to assign. Wonders if it's possible to do this without having to declare a delegate?

More inconvenient is that recursion only works for static declarations. The following is fairly identical to the above, other than the fact that it is an instance variable, but will not compile:

delegate int IntToInt(int i);

IntToInt Factorial = 
    (n) => n <= 1 ? 1 : n * Factorial(n - 1);

So I'm wondering how one goes about getting recursive functions using the lambda syntax? ML does this with the 'rec' attribute keyword but I don't find anything similar in the new C# specs.

My own opinion is that there should not be a distinction between named and anonymous functions, though a lot of languages I encounter seem to make this distinction. C# 3.0 doesn't have Python's limitation of being restricted to expressions - control structures can be used:

static IntToInt Factorial = 
    (n) =>
    { 
        if (n <= 1) 
            return 1; 
        else 
            return n * Factorial(n - 1); 
    };

Nor does it require special application like Ruby's call. But it does seem to have rules about forbidding the reuse of parameter names that are in the scope of the defining body (if X is declared in the surrounding scope, then X can't be a parameter for the lambda function).

I'm guessing that the main impetus for lambdas in C# is the new DLinq syntax, so perhaps assigning lambdas to variables in trying to create blocked scoped functions is not a priority.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Answering my own question

Stumbling across Anonymous Recursion in C#, I see one solution is as follows:

Func<int, int> Factorial = null;
Factorial = (n) => n <= 1 ? 1 : n * Factorial(n - 1);

Func can be used in lieu of explicitly declaring the delegate. And splitting the declaration away from assignment gets around the instance declaration (though the link above takes issue whether this qualifies as true recursion).

No difference, what about recursion?

>My own opinion is that there should not be a distinction between named and anonymous functions

Well, it's a bit difficult to have anonymous recursive function, sure the language can provide a 'this/self' keyword, but it's a little weird.

So no difference is a bit too strong IMHO.

Names and Recursion

[Edit Note: Meant as reply to renox]

Once you introduce the ability to name functions, it should not make a difference whether the function being called is one defined elsewhere or the one currently being defined. The only special consideration that recursion introduces is that the function being called has not been completely defined yet - a forward reference of sorts.

In languages that don't allow forward references, you have to introduce a special form to work around this limit. In ML, the 'rec' keyword can be used for this purpose. The function form of:

fun fact n =
   if (n <= 1)
      then 1
      else n * fact (n-1)

Is just syntactic sugar for:

val rec fact = fn n =>
   if (n <= 1)
      then 1
      else n * fact (n-1)

In PLs that don't allow reassignment of names, there is not a similar need for a special form. In Haskell, the function syntax of:

factorial n =
   if n <= 1
      then 1
      else n * factorial (n - 1)

Is just a special form for:

factorial = \n ->
   if n <= 1
      then 1
      else n * factorial (n - 1)

Since I'm discussing this in terms of C# lambdas, and I just went through the motions of translating SICP chapter 1 to C#, the example of calculating square roots with block scoping gives us:

double Sqrt(double x)
{
    Func<double, bool> Good_Enough = (guess) => 
        Math.Abs(Square(guess) - x) < 0.001;
    Func<double, double> Improve = (guess) =>
        Average(guess, x / guess);
    Func<double, double> Iter = null;
    Iter = (guess) =>
        {
            if (Good_Enough(guess))
                return guess;
            else
                return Sqrt(Improve(guess));
        };
    return Iter(1.0);
}

Looking beyond the problem of recursive functions that manifests itself in the Iter function, what I'm trying to say is that the above should be equivalent to the following code that the compiler won't accept:

double Sqrt(double x)
{
    bool Good_Enough(double guess)
    {
        return Math.Abs(Square(guess) - x) < 0.001;
    }
    double Improve(double guess)
    {
        return Average(guess, x / guess);
    }
    double Iter(double guess)
    {
        if (Good_Enough(guess))
            return guess;
        else 
            return Iter(Improve(guessx));
    }
    return Iter(1.0);
}

In other words, the problem works both ways. Sometimes I want to use lambdas where the language requires the use of named functions. And at other times, I want to use named functions where the language requires me to use lambdas. I prefer a PL that allows the user to select the most readable and maintainable form.

Java Closures

As long as I'm doing lambdas in mainstream languages, I was wanting to also take a look at Java Closures. Sticking with factorials, my guess would be that the equivalent for Java 1.7 would be:

{int=>int} factorial = 
   {int n => (n <= 1) ? 1 : n * factorial(n - 1)};

However, I downloaded the nigtly build for beta jdk 1.7 and it doesn't seem to be implemented just yet. Anyone know when java closures are going to be available for consumption?

Delegates in C# suck

In Virgil, I have a slightly more elegant way of expressing delegates, but currently do not have lambda. Virgil generalizes the common expr.method(...) syntax for method calls to expr(...) and generalize the member access operator to create a delegate by simply writing expr.method, which represents a first-class value that is the delegate bound to the function method and the object expr. Then the expr.method() invocation syntax just becomes a special case of the more general invocation syntax. Delegates in Virgil are typed by their argument and return types only, and there is a special type constructor called function that can be used to refer to function types.

Example from my paper:

class List {
    field head: Link;
    method add(i: Item) { . . . }
    method apply(f: function(Item)) {
        local pos = head;
        while ( pos != null ) {
            f(pos.item);
            pos = pos.next;
        }
    }
}
component K {
    method printAll(l: List) {
        l.apply(print);
    }
    method append(src: List, dst: List) {
        src.apply(dst.add);
    }
    method print(i: Item) { . . . }
}

The implementation represents delegate values as a two-word tuple of a pointer to a method and a pointer to an object, and so does not require memory allocation.

The drawback is that you sacrifice method overloading, because a delegate expression becomes ambiguous. Since there aren't any parameters in a delegate expression, there is no way to infer which of the overloaded methods is being called.

At any rate, retrofitting C# and Java with lambda seems like it's going to be ugly!