The real difference between lambda expression and anonymous delegates

M

Matt

Hi There,
Can anyone explain me the real advantages of (other than syntax)
lambda expressions over anonymous delegates?
From the following example that I tried, I couldn't derive any real
advantage for one over the other.

delegate int F(int a);

F fLambda = a => a++;
F fAnonymous = delegate(int a) { return a++; };
fLambda(1);
fAnonymous(1);

Thanks,
Matt
 
T

Tom Spink

Matt said:
Hi There,
Can anyone explain me the real advantages of (other than syntax)
lambda expressions over anonymous delegates?
advantage for one over the other.

delegate int F(int a);

F fLambda = a => a++;
F fAnonymous = delegate(int a) { return a++; };
fLambda(1);
fAnonymous(1);

Thanks,
Matt

Hi Matt,

Functionally: none. It really is just syntactic sugar. However, there
advantages to using either approach in your code.

For example, lambda expressions enable concise, small and readable code when
small expressions are being, err, expressed. Also, it provides a nice
bridge between functional and imperative/procedural programming.

However, when you have a really complex task to perform, it may be wiser
and/or necessary to use a delegate.

Your question was what's the advantage of lambda expressions over anonymous
delegates, however, if you asked what's the advantage of anonymous
delegates over lambda expressions, I'd say that they allow more programming
constructs to go in your anonymous routine (such as scoped variable
declaration, multiple statement execution) and represent this as a function
within a function.
 
N

Nicholas Paldino [.NET/C# MVP]

Tom,

Lambda Expressions actually are different functionally than delegates.
With lambda expressions, you can do this:

Expression<Predicate<int>> e = i => i > 5;

You can't do that with a delegate (assign it to an Expression<T>). When
you compile this code, the compiler creates an expression tree, where the
model can be accessed which gives the details of the expression.

You can convert the expression to a delegate by calling:

Predicate<int> greaterThanFive = e.Compile();

Of course, if you assign the lamba expression to a delegate, the
compiler creates an anonymous delegate all the same.
 
T

Tom Spink

Nicholas said:
Tom,

Lambda Expressions actually are different functionally than delegates.
With lambda expressions, you can do this:

Expression<Predicate<int>> e = i => i > 5;

You can't do that with a delegate (assign it to an Expression<T>).
When
you compile this code, the compiler creates an expression tree, where the
model can be accessed which gives the details of the expression.

You can convert the expression to a delegate by calling:

Predicate<int> greaterThanFive = e.Compile();

Of course, if you assign the lamba expression to a delegate, the
compiler creates an anonymous delegate all the same.

Hi Nicholas,

Thanks for the clarification there! That's quite interesting, and really
cool. :)
 
B

Ben Voigt [C++ MVP]

Nicholas Paldino said:
Tom,

Lambda Expressions actually are different functionally than delegates.
With lambda expressions, you can do this:

Expression<Predicate<int>> e = i => i > 5;

You can't do that with a delegate (assign it to an Expression<T>).
When you compile this code, the compiler creates an expression tree, where
the model can be accessed which gives the details of the expression.

That presumbly enables a computer algebra system? Like symbolic
differentiation?
You can convert the expression to a delegate by calling:

Predicate<int> greaterThanFive = e.Compile();

Of course, if you assign the lamba expression to a delegate, the
compiler creates an anonymous delegate all the same.
 
M

Matt

Hello Nicholas,
Thanks for your answer. Is there any way to use the lambda expression
other than compiling it as a delegate and then using it? What would be
an appropriate use case for such an expression? I had used anonymous
delegates extensively when dealing with "InvokeRequired" in ui code.
It would be great if you can point such a use case for the lambda
expression (Expression<Predicate<int>> e = i => i > 5;).
Thanks,
Matt
 
C

Christof Nordiek

Matt said:
Hi There,
Can anyone explain me the real advantages of (other than syntax)
lambda expressions over anonymous delegates?
advantage for one over the other.

delegate int F(int a);

F fLambda = a => a++;
F fAnonymous = delegate(int a) { return a++; };
fLambda(1);
fAnonymous(1);

The lambda expression is more readable IMO.

Christof
 
C

Christof Nordiek

Matt said:
Hello Nicholas,
Thanks for your answer. Is there any way to use the lambda expression
other than compiling it as a delegate and then using it?

It can be used in LINQ, where the expression tree could be resolved e.g. to
a filter condition in a SQL-Statement.

Christof
 
N

Nicholas Paldino [.NET/C# MVP]

Matt,

Well, you can do this as well:

Predicate<int> greaterThanFive = i => i > 5;

And the compiler will compile it into an anonymous delegate.

There are two main benefits for lambda expressions. The first is the
ability to do this:

ParameterExpression param = Expression.Parameter(typeof(int), "i");
Expression greaterThan = Expression.GreaterThan(param,
Expression.Constant(5));
LambdaExpression greaterThanFive =
Expression.Lambda<Predicate<int>>(greaterThan, param);

// Compile.
Predicate<int> check = (Predicate<int>) greaterThanFive.Compile();

// Compare.
Console.WriteLine(check(10));
Console.WriteLine(check(4));

This will allow you to dynamically create and execute expressions in
code. Dynamic code generation becomes a lot simpler with this (at least,
simple code generation).

Given that lambda expressions can be pulled apart into an object model
and analyzed, when you do this:

Expression<Predicate<int>> e = i => i > 5;

You can look at the components of the expression, so that you can
convert the query syntax into another language, which is in fact, exactly
what LINQ to SQL does.
 
N

Nicholas Paldino [.NET/C# MVP]

To a limited degree, yes, in that you are able to pass around code as
data, but only to a limited degree, of course.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
Nicholas Paldino said:
Tom,

Lambda Expressions actually are different functionally than delegates.
With lambda expressions, you can do this:

Expression<Predicate<int>> e = i => i > 5;

You can't do that with a delegate (assign it to an Expression<T>).
When you compile this code, the compiler creates an expression tree,
where the model can be accessed which gives the details of the
expression.

That presumbly enables a computer algebra system? Like symbolic
differentiation?
You can convert the expression to a delegate by calling:

Predicate<int> greaterThanFive = e.Compile();

Of course, if you assign the lamba expression to a delegate, the
compiler creates an anonymous delegate all the same.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Tom Spink said:
Matt wrote:

Hi There,
Can anyone explain me the real advantages of (other than syntax)
lambda expressions over anonymous delegates?
From the following example that I tried, I couldn't derive any real
advantage for one over the other.

delegate int F(int a);

F fLambda = a => a++;
F fAnonymous = delegate(int a) { return a++; };
fLambda(1);
fAnonymous(1);

Thanks,
Matt

Hi Matt,

Functionally: none. It really is just syntactic sugar. However, there
advantages to using either approach in your code.

For example, lambda expressions enable concise, small and readable code
when
small expressions are being, err, expressed. Also, it provides a nice
bridge between functional and imperative/procedural programming.

However, when you have a really complex task to perform, it may be wiser
and/or necessary to use a delegate.

Your question was what's the advantage of lambda expressions over
anonymous
delegates, however, if you asked what's the advantage of anonymous
delegates over lambda expressions, I'd say that they allow more
programming
constructs to go in your anonymous routine (such as scoped variable
declaration, multiple statement execution) and represent this as a
function
within a function.
 
B

Brian Gideon

That presumbly enables a computer algebra system? Like symbolic
differentiation?

Well, except that a CAS[1] really has the ability to reduce and
simplify expressions. That ability requires specialized data
structures that I'm thinking are incompatible with how the expression
tree is stored. You may be able to do trivial simplifications, but
monomial and polynomial simplification and especially differentiation,
factorization, and integration would be too difficult if not
impossible. It's probably easier to just write the CAS compiler and
operations from scatch.

I still have not played around much with C# 3.0. Can lambda
expression trees even be compiled from a string input?

[1] I do not consider a trivial expression evaluator to be a CAS.
 
J

Jon Skeet [C# MVP]

Your question was what's the advantage of lambda expressions over anonymous
delegates, however, if you asked what's the advantage of anonymous
delegates over lambda expressions, I'd say that they allow more programming
constructs to go in your anonymous routine (such as scoped variable
declaration, multiple statement execution) and represent this as a function
within a function.

This is allowed within lambda expressions too, although the
functionality is relatively rarely used. Here's a short but complete
example:

using System;
using System.Threading;

class Program
{
static void Main()
{
ThreadStart ts = () =>
{
DateTime date = DateTime.Today;
date = date.AddDays(10);
Console.WriteLine(date);
};

new Thread(ts).Start();
}
}

It's relatively rare to see this kind of thing in examples at the
moment, admittedly - usually a single expression (not even a whole
statement, necessarily) is used, particularly in LINQ examples.
 
B

Ben Voigt [C++ MVP]

Brian Gideon said:
That presumbly enables a computer algebra system? Like symbolic
differentiation?

Well, except that a CAS[1] really has the ability to reduce and
simplify expressions. That ability requires specialized data
structures that I'm thinking are incompatible with how the expression
tree is stored. You may be able to do trivial simplifications, but
monomial and polynomial simplification and especially differentiation,
factorization, and integration would be too difficult if not
impossible. It's probably easier to just write the CAS compiler and
operations from scatch.

I still have not played around much with C# 3.0. Can lambda
expression trees even be compiled from a string input?

[1] I do not consider a trivial expression evaluator to be a CAS.

Well, being able to evaluate a derivative of an arbitrary expression without
resorting to a difference quotient approximation is already useful IMHO,
even without simplification. But additionally having the C# compiler
generate an expression tree would simply a CAS considerably even if that
isn't the final form used for manipulation, plus the API is given much
cleaner syntax.
 
B

Brian Gideon

Well, being able to evaluate a derivative of an arbitrary expression without
resorting to a difference quotient approximation is already useful IMHO,
even without simplification. But additionally having the C# compiler
generate an expression tree would simply a CAS considerably even if that
isn't the final form used for manipulation, plus the API is given much
cleaner syntax.

I'm not seeing that the C# compiler can dynamically generate the
expression trees from user input though. Don't you still need to
provide a lexer and parser for that? Even if it can I'm afraid the
language it would accept would be very (if not entirely) C#'ish which
isn't ideal for a CAS. It would, however, be sufficient for an
expression evaluator which is still quite useful :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top