jamheadart
jamheadart

Reputation: 5293

What is the use of lambda in the last function here?

I'm trying to understand Lambda expressions;

I've got a basic function Sq1 which is squaring the number i I can rewrite this with a lambda to oneline it, Sq2

I can also write it like Sq4 with a Func<>, but I'm not sure why I'd want to

and furthermore, with Sq3 I was trying to write the long-hand version of Sq4 because writing Sq1 helped me understand what Sq2 was actually doing

   public int Sq1(int i)
    {
        return i * i;
    }

    public int Sq2(int i) => i * i;

    public Func<int, int> Sq3(int i)
    {
        // Not sure what goes here, I don't want to return a function?
    }

    public Func<int, int> Sq4 = x => x * x;

Can anybody help me understand why I'd write the function as per Sq4 and what this is actually shorthand for?

Upvotes: 1

Views: 75

Answers (2)

Panagiotis Kanavos
Panagiotis Kanavos

Reputation: 131180

Sq1 and Sq2 are identical functions, not lambdas. Sq2 uses the expression body syntax that allows simplifying simple methods. Sq2 is essentially:

public int Sq2(int i) {
    return  i * i;
}

You can use Sharplab.io to see the generated code in both cases. You'll see that the body of both methods is the same

You can't make the Sq3 function behave like Sq4, because Sq4 on the other hand is a Func-typed field that holds the x => x * x delegate. Sq3 on the other hand is a function that returns a Func, a common idiom in functional programming.

You can use Sq4 as if it were a function, eg :

var result=Sq4(2);

As for Sq3, what you do depends on what you want to do. If you only want to execute the function, use the same syntax as Sq1 or Sq2. If you really want to return a Func<> you could use something like this :

public Func<int,int> Sq3F()
{
    return (int i)=>i*i;
}

And use it like this:

var fun=Sq3F();
var result=fun(4);

Why a Func<>?

That doesn't look like much until you realize you can pass functions as parameters and construct complex transformations dynamically, eg :

public Func<int,double> LogF(Func<int,int> fun)
{
    return (int i)=>Math.Log(fun(i));
}

...

var func=LogF(Sq3F());
var result=func(4);

Another common technique is partial application - take a function with multiple arguments and produce another one where some of the arguments are fixed. Let's say you want to create a single-argument Log method that works for a specific base, which means you can't just use `Math.Log(double,double). You could do this :

public Func<double,double> LogN(double N)
{
    return (double d)=>Math.Log(d,N);
}

...

var log5F=LogN(5);
var result=log5F(5);

Upvotes: 4

Alejandro Vicaria
Alejandro Vicaria

Reputation: 158

You would use the lambda expression for the sake of simplicity, to avoid having to write a full function for a simple operation.

And it would translate to the following normal function:

public int Sq4(int x):
{
  return x * x;
}

Also you have used an arrow function that is different of a lambda. An arrow function is a way to simplify the body of a function but it has the same structure

(string param1, int param2) => {

// To do here

}

Upvotes: -1

Related Questions