aAbrEBAreBX-~C| 564}FW~~ 6565656565656668884V~~XBPZZZ~BCZ~ 74VB~ZWCP5F5FZ 568V~BW~X

Lambda.` From a branch a leaf grows. From a trunk a branch grows. A single function could make each leaf, each branch—what makes one makes many. An earthworm crawls among the tree's roots.`A lambda expression` describes a pattern. From mathematics, the lambda calculus describes the world in patterns. In C# a lambda is a function that uses clear and short syntax.`An example.` A common place to use lambdas is with List. Here we use FindIndex, which receives a Predicate method. We specify this as a lambda expression. `Left, right: `To the left, we have arguments. The "x" is just a name—we can use any valid name. The result is on the right.`Often: `We pass lambda expressions as arguments, for sorting or for searching. We use them in queries.`Detailed examples.` We take a closer look at lambdas and anonymous functions. The => operator separates the parameters to a method from its statements in the method's body. `Lambda expressions use the token => in an expression context. In this context, the token is not a comparison operator.`Goes to: `The => operator can be read as "goes to." It is always used when declaring a lambda expression.`Invoke: `With Invoke, a method on Func and Action, we execute the methods in the lambdas.`A syntax review.` Above we see many usages of lambda expressions. Sorry for the long example. The => operator separates arguments from methods. It does not compare numbers. `Left side: `This is the parameters. It can be empty. Sometimes it can be implicit (derived from the right).`Right side: `This is a statement list inside curly brackets with a return statement, or an expression.`Func1 through func8.` Above, func1 through func8 denote anonymous function instances. The C# compiler often turns different syntax forms into the same code.`Func.` The key part of Func is that it returns a value. It can have zero, or many, arguments. But its invariant is a return value, indicated by the TResult parametric type. `Func `func`Action.` This class indicates a function that receives no parameter and returns no value. It matches a void method with no arguments. This guy is a solitary character. `Action `action`Delegate.` The delegate keyword denotes an anonymous function. After this keyword, we use a formal parameter list. We can omit the list if there are no parameters. `Delegate `delegate`Anonymous functions.` This term includes both delegates and lambda syntaxes. An anonymous function has no name. Perhaps it is running from the law. `Anonymous Functions `anonymous-function`Overloading: `Because it has no name, method overloading is not possible for anonymous functions.`Overload `overload`Many developers regard lambda expressions as a complete improvement over (and replacement for) the delegate syntax.`Predicate.` Here we use this type with an int parameter. With a lambda expression, we specify that the function returns true if the argument is equal to 5. `Predicate `predicate`Invoke: `In this program, the Invoke method is used to show that the Predicate works as expected.`Comparison.` This type is specifically used to compare objects. It is useful when calling the List.Sort or Array.Sort methods. It can be used with any object type. `Comparison `comparison`Performance: `Using methods such as List.Sort or Array.Sort (with a Comparison) is often faster than using LINQ to sort on a property.`Events.` Like any other method, events can be specified as lambda expressions. With events, many event handlers are called when a certain thing happens. This can simplify some programs. `Event `event`Performance.` I benchmarked a lambda against an anonymous method, one using the delegate keyword. I used the functions as arguments to the Count() extension. `Result: `I found no differences. The lambda expression performed the same as the explicit Func instance.`Thus: `Lambda expressions cause no excess performance hit beyond other delegate syntaxes.`Expression-bodied methods.` A method can be specified with lambda expression syntax. We provide a method name, and the method is compiled like a lambda. A "return" statement is implicit. `Return: Expression-Bodied `return`Expressive power.` Lambdas advance a language. We can achieve the same thing with regular, non-lambda methods. But they make a language easier to use, more "expressive." `Quote: `Higher-order procedures can serve as powerful abstraction mechanisms, vastly increasing the expressive power of our language.`Structure and Interpretation of Computer Programs: MIT `https://mitpress.mit.edu/sicp/full-text/book/book.html`Specification.` The C# language specification describes anonymous function types. The annotated edition of The C# Programming Language (3rd Edition) covers all syntaxes available. `We can find more detail on this topic using the precise technical terminology on page 314 of this book.`Boring: `This is pretty boring. Proceed at your own risk. Unless you are thinking about making a C# website, it may not be worth the effort.`Some help.` Lambdas have unique syntactic rules. We had some help from the C# specification itself. We used lambdas with zero, one or many arguments, and with a return value.`Anonymous functions.` These have no names, but we learned lots of their details. With the delegate keyword, we also specify method objects.

EONYVNNODOQ;NO NOJOAN{NEO%E{NEEOo<Oz> O8sOyOqOo<Oz>() { 10, 20, V31V, 40 };VNEEO9Find index of first odd O8.NEEVOioddOTOyO8s.FindOT(Vx => x % 2 != 0V);NEEO'oddOT);NE}N}NNVNN2NNVLambda detailsVNNxEE The argument name.N=>EE Separates argument On from OM expression.Nx % 2 !=0 Returns true if x is not even.VNNODOQObOJOAN{NEO%E{VNEE//NEEO{Use implicitly-typed lambda expression.NEEO9Assign itOja Func instance.NEE//NEEVFunc<Oz, Oz> func1Oyx V=>V xO}1;VNEE//NEEO{Use lambda expression with statement body.NEE//NEEVFunc<Oz, Oz> func2Oyx V=>V { OK xO}1; };VNEE//NEEO{Use O|mal parameters with expression body.NEE//NEEVFunc<Oz, Oz> func3Oy(Oix) V=>V xO}1;VNEE//NEEO{Use parameters with a statement body.NEE//NEEVFunc<Oz, Oz> func4Oy(Oix) V=>V { OK xO}1; };VNEE//NEEO{Use multiple parameters.NEE//NEEVFunc<Oz, Oz, Oz> func5Oy(x, y) V=>V x * y;VNEE//NEEO{Use no parametersOpa lambda expression.NEE//NEEVAction func6Oy() V=>V O');VNEE//NEEO{Use delegate mOg expression.NEE//NEEVFunc<Oz, Oz> func7Oydelegate(Oix) { OK xO}1; };VNEE//NEEO{Use delegate expression with no parameter On.NEE//NEEVFunc<Oz> func8Oydelegate { OK 1O}1; };VNEE//NEEO{Invoke each of the lambda expressionsOVdelegates we cO_d.NEEO9The mOgs above are executed.NEE//NEEVO'func1.Invoke(V1V));NEEO'func2.Invoke(V1V));NEEO'func3.Invoke(V1V));NEEO'func4.Invoke(V1V));NEEO'func5.Invoke(V2V, V2V));NEEfunc6.Invoke();NEEO'func7.Invoke(V1V));NEEO'func8.Invoke());NE}N}NNVNN2N2N2N2N4NN2N2VFunc eOFsVNNFunc<TResult>EEE Has one OM Oh, no parameter.NFunc<T, TResult>EE Has one OM Oh, one parameter.NFunc<T1, T2, TResult>E Has one OM Oh, two parameters.NFunc<T1, T2, T3, TResult> ....VNNODOQObOJOAN{NEO%E{NEEVPredicateV<Oz> predicateOyOh => VOhOx5V;NEEO'predicate.Invoke(4));NEEO'predicate.Invoke(5));NE}N}NNVNNFalseNTrueVLocals usedOpbenchmark: C#VNNOz[] OUOy{ 1 };NFunc<Oz, bool> fOyVdelegateV(Oix)N{NEOK xOx1;N}ObVLambda expression tested: C#VNNOicOyOU.O](O8 V=>V O8Ox1)ObVDelegate tested: C#VNNOicOyOU.O](f);VNNOJOAN{NEO?OiTreeBranches(Oibranches, Oitrunks) V=>V (branches * trunks)ObEO%E{VNEEO{Call the expression-bodied mOg.NEEVOQ.O'TreeBranches(V10V, V2V));NE}N}NNVNN20V

$\bYelambda, Listlambda expressionsPredicatelambda syntax, method