DQ JA%oz8yqoz98iTy8T'TnMDQbJA%{9jzzy}{zzyK}{|zzyi}{zzyiK}{zzzy{py'{gzzyiK}{nzyK}{V_9g'''''''FMhMhMhDQbJA%zyhhx''pzUyzyiKxbiyU]88xbiyU]JA?iiib%{gQ'aABbrEBAreBX-~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.

JKN KK; K KK { JKJ{ JJK<K> KsKKK<K>() { 10, 20, N31N, 40 };N JJKFind index of first odd K. JJNKoddKKKs.FindK(Nx => x % 2 != 0N); JJKoddK); J} } N 2 NLambda detailsN xJJ The argument name. =>JJ Separates argument K from K expression. x % 2 !=0 Returns true if x is not even.N KKKKK { JKJ{N JJ// JJKUse implicitly-typed lambda expression. JJKAssign itKa Func instance. JJ// JJNFunc<K, K> func1Kx N=>N xK1;N JJ// JJKUse lambda expression with statement body. JJ// JJNFunc<K, K> func2Kx N=>N { K xK1; };N JJ// JJKUse Kmal parameters with expression body. JJ// JJNFunc<K, K> func3K(Kx) N=>N xK1;N JJ// JJKUse parameters with a statement body. JJ// JJNFunc<K, K> func4K(Kx) N=>N { K xK1; };N JJ// JJKUse multiple parameters. JJ// JJNFunc<K, K, K> func5K(x, y) N=>N x * y;N JJ// JJKUse no parametersKa lambda expression. JJ// JJNAction func6K() N=>N K);N JJ// JJKUse delegate mK expression. JJ// JJNFunc<K, K> func7Kdelegate(Kx) { K xK1; };N JJ// JJKUse delegate expression with no parameter K. JJ// JJNFunc<K> func8Kdelegate { K 1K1; };N JJ// JJKInvoke each of the lambda expressionsKdelegates we cKd. JJKThe mKs above are executed. JJ// JJNKfunc1.Invoke(N1N)); JJKfunc2.Invoke(N1N)); JJKfunc3.Invoke(N1N)); JJKfunc4.Invoke(N1N)); JJKfunc5.Invoke(N2N, N2N)); JJfunc6.Invoke(); JJKfunc7.Invoke(N1N)); JJKfunc8.Invoke()); J} } N 2 2 2 2 4 2 2NFunc eKsN Func<TResult>JJJ Has one K K, no parameter. Func<T, TResult>JJ Has one K K, one parameter. Func<T1, T2, TResult>J Has one K K, two parameters. Func<T1, T2, T3, TResult> ....N KKKKK { JKJ{ JJNPredicateN<K> predicateKK => NKK5N; JJKpredicate.Invoke(4)); JJKpredicate.Invoke(5)); J} } N False TrueNLocals usedKbenchmark: C#N K[] KK{ 1 }; Func<K, bool> fKNdelegateN(Kx) { JK xK1; }KNLambda expression tested: C#N KcKK.K(K N=>N KK1)KNDelegate tested: C#N KcKK.K(f);N KK { JKKTreeBranches(Kbranches, Ktrunks) N=>N (branches * trunks)KJKJ{N JJKCall the expression-bodied mK. JJNK.KTreeBranches(N10N, N2N)); J} } N 20N

$\bYelambda, Listlambda expressionsPredicatelambda syntax, method