-3

I have been learning about the lambda expression, I got happy when I finally can read/understand the => operator, it kind of means "where" to me

List<int> a = new List<int>(){0,1,2,1,3,4,5,6,7,8,9};
IEnumerable<int> b = a.FindAll(x => x>=5);
foreach (int x in b)
Console.WriteLine(x);

Reading the above line, personally makes sense to read it as "Find all x's from this list WHERE x is greater than or equal 5", very good. But then I come across a different use of the lambda expression with the Select method.

List<int> a = new List<int>(){0,1,2,1,3,4,5,6,7,8,9};
IEnumerable<int> b1 = a.Select(x => x*2);
foreach (int x in b)
Console.WriteLine(x);

With this one, the previous way of reading this operator doesn't make sense, as to me this code does "For each x return x*2", which is very different "function" to what the same operator does in the previous case. I understand that the difference is between .FindAll and .Select, different way of dealing with input and output parameters, but I am talking about the use of the operator => in the lambda expression.

Mocas
  • 1,403
  • 13
  • 20
  • 1
    What is your question? – mrogers Jul 19 '17 at 15:56
  • 6
    The `=>` declares a function. On the left side you have it's parameters and on the right side you have the body of the function. Note that the return statement is implicit. How the function is used strictly depends on the method to which you give it. In the `Select` it will pass you each element and then you return what you want from it. In the `FindAll` you tell it whether you want that element or not – litelite Jul 19 '17 at 15:56
  • [See here as well](https://stackoverflow.com/questions/290061/what-does-the-syntax-in-c-sharp-mean) – Jon B Jul 19 '17 at 15:58
  • 2
    I think you would benefit greatly from more research/tutorials on LINQ/Lambda. – maccettura Jul 19 '17 at 15:59
  • Possible duplicate of [C# Lambda expressions: Why should I use them?](https://stackoverflow.com/questions/167343/c-sharp-lambda-expressions-why-should-i-use-them) – Liam Jul 19 '17 at 16:00
  • @mrogers: Is there a single "word" that describes both cases? Something like the second comment's attempts. – Mocas Jul 19 '17 at 16:01
  • @litelite: but the x in the first case is not a parameters as I understand. – Mocas Jul 19 '17 at 16:01
  • 3
    *`=>` operator, it kind of means "where" to me* is your first mistake. It's not a where statement, it's a delegate that returns a result as an iterator. As mentioned too, what's your question? – Liam Jul 19 '17 at 16:01
  • 2
    @Liam The result isn't an iterator here, or in general. The first one return boolean, the second returns an integer. – Servy Jul 19 '17 at 16:05
  • As @Liam notes, it seems the fundamental problem is that using _"where"_ to describe your lambda expression works only when dealing with a predicate, i.e. an expression that returns a `bool`. It's your mistake to use the word _"where"_ as a replacement for the `=>` operator. You need to get past your own mistake. Admit it, and move on. Oh, and...did you have a _question_ here? It's not clear at all what you're actually _asking_...just what you've done wrong. – Peter Duniho Jul 19 '17 at 17:02
  • @user2410199 it is a parameter that the method will pass to your function – litelite Jul 19 '17 at 17:02
  • 2
    Try to phrase your question *as a question*, so that it can actually be answered. A list of things that confuse you is a good introduction to a question, but it's not a *question*. – Eric Lippert Jul 19 '17 at 17:12
  • So many people voted me down now I am banned from asking question, can you please reverse your vote or vote up? – Mocas Dec 16 '19 at 16:37

3 Answers3

8

There's no question in this question, so let's make one up.

Characterizing the lambda operator as "where" works when the lambda returns a bool and is used as a predicate to test a value. Is there a more general characterization of the lambda operator that makes sense in other contexts, such as projection?

Yes. Read the lambda operator as "goes to".

a.Select(x => x * 2);

"each x goes to x times two"

You can use that for predicates as well:

a.Where(x => x > 2);

"each x goes to 'is x greater than two?'"

But that's awkward. As you note, it is easier to think of this as "where" or "such that"

"each x such that x is greater than two"

Similarly

a.OrderBy(x => x.LastName)

"order each x by x goes to last name" is awkward. Just say "order each x by last name".

In short: the English language interpretation of the operator depends on the context. The formal interpretation of the operator is always the same: it simply describes a function.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
3

The => operator has exactly the same meaning in both cases: it creates a function whose parameter is the thing on the left, and whose return value is the thing on the right.

You wrote in a comment that the x in the first case is not a parameter as you understand it. That's not correct; it is a parameter in both cases here.

Here's your first example, again:

List<int> a = new List<int>(){0,1,2,1,3,4,5,6,7,8,9};
IEnumerable<int> b = a.FindAll(x => x>=5);
foreach (int x in b)
    Console.WriteLine(x);

If you wanted to write this without using lambda notation, you would define a function somewhere, like this...

static bool MyCondition(int x)
{
    return x >= 5;
}

...and then use that function as the argument to FindAll:

List<int> a = new List<int>(){0,1,2,1,3,4,5,6,7,8,9};
IEnumerable<int> b = a.FindAll(MyCondition);
foreach (int x in b)
    Console.WriteLine(x);

The lambda notation is a shorter notation which allows you to define the function right where you use it.

Likewise, if you wanted to write your second example without using lambda notation, you'd define a function elsewhere, like this...

static int MyOperation(int x)
{
    return x * 2;
}

...and pass your function as the argument to Select, like this:

List<int> a = new List<int>(){0,1,2,1,3,4,5,6,7,8,9};
IEnumerable<int> b1 = a.Select(MyOperation);
foreach (int x in b)
    Console.WriteLine(x);
Tanner Swett
  • 3,241
  • 1
  • 26
  • 32
1

Think of it this way:

  • Mathematics: f(x) = x + x

    This is a mathematical function f that takes a number x and spits out its double.

  • Lambda: f = x => x + x C#'s way of defining the same function f.

Another example:

  • Mathematics: g(x, y) = x > y

    g is a function that takes two numbers x and y and returns wether the former is greater than the latter.

  • Lambda: g = (x, y) => x > y C#'s way of defining the same function g.

Clearer now?

P.D: I've omitted talking about type inference and the type of the lambda's themselves; its an unnecessary distraction considering the context of this question.

InBetween
  • 32,319
  • 3
  • 50
  • 90