Technical Q&A [C#]

Solarion

Honorary Master
Joined
Nov 14, 2012
Messages
21,885
A good article this

Expression API Cookbook

Lambda expressions should be short. A complex definition makes the calling code difficult to read.
Lambda basic definition: Parameters => Executed code
What is a Lambda Expression?
Why do we need lambda expressions? (Why would we need to write a method without a name?)
Reduced typing. No need to specify the name of the function, its return type, and its access modifier.
When reading the code, you don't need to look elsewhere for the method's definition.
How do we define a lambda expression?
 

[)roi(]

Executive Member
Joined
Apr 15, 2005
Messages
6,282
Lamba vs. standard Functions Summary
Lambdas are simply what C# and Java call first class functions.For historical reasons neither Java or C# treat standard functions as first class ones; however they can fairly easily be linked to Lambda syntax. "First class" simply means that functions are treated no different to variables, which means that we can :
  • pass a function as arguments to other functions
  • return a function as a value from other functions
  • assign a function to variable
  • store functions in a data structure e.g. List
There are 3 major delegate types that are used to define a Lambda:
  • Action: a function that returns void
  • Func: a function that returns a value, e.g. int, string, ...
  • Predicate: a function that returns a bool

Action function comparison (same functionality):
PHP:
// C# standard function
static void Print(string message)
{
  Console.WriteLine(message);
}

// C# lambda function
static Action<string> Print1 = message => {
  Console.WriteLine(message);
};

// C# lambda shorter version
static Action<string> Print2 = message => Console.WriteLine(message);

Action function usage example (same functionality):
PHP:
Print("Hello"); // Hello
Print1("Hello1"); // Hello1
Print2("Hello2"); // Hello2

Func(value) function comparison (same functionality):
PHP:
// C# standard function
static string Hello(string message)
{
  return "Hello, " + message;
}

// C# lambda function
static Func<string, string> Hello1 = message => {
  return "Hello, " + message;
};

// C# lambda shorter version
static Func<string, string> Hello2 = message => "Hello, " + message;

Func(value) function usage example:
PHP:
Console.WriteLine(Hello("World")); // Hello, World
Console.WriteLine(Hello1("World1")); // Hello, World1
Console.WriteLine(Hello2("World2")); // Hello, World2

Predicate(bool) function comparison (same functionality):
PHP:
// C# standard function
static bool IsEven(int value)
{
  return value % 2 == 0;
}

// C# lambda function
static Predicate<int> IsEven1 = value => {
  return value % 2 == 0;
};

// C# lambda shorter version
static Predicate<int> IsEven2 = value => value % 2 == 0;

// Using Func, instead of  Predicate
static Func<int, bool> IsEven3 = value => value % 2 == 0;

Predicate(bool) function usage example:
PHP:
Console.WriteLine(IsEven(14)); // true
Console.WriteLine(IsEven1(14)); // true
Console.WriteLine(IsEven2(14)); // true
Console.WriteLine(IsEven3(14)); // true

C# Delegate Inconsistency
Whilst we can define a Predicate with the Func delegate we cannot define an Action (void); this e.g. will not work, because for some reason C# classifies void differently from the other types . :wtf:
PHP:
static Func<string, void> Print3 = message => Console.WriteLine(message);

Function composition example, using a List and Extension Methods:
Here's an example of first class functions in a List:
PHP:
var list = new List<Func<double, double>>() { Math.Log, Math.Cos, Math.Sin, Math.Tan };
Then to compose a result from this I can e.g. define a Compose extension method on IEnumerable:
PHP:
public static T Identity<T>(T value) => value;

public static Func<T, T> Compose<T>(Func<T, T> function1, Func<T, T> function2)
      => arg1 => function2(function1(arg1));

public static Func<T, T> Compose<T>(this IEnumerable<Func<T, T>> elements) 
  => elements.Aggregate<Func<T, T>, Func<T, T>>(Identity<T>, Compose<T>);
This then allows me call it up on the 'list' we defined:
PHP:
Console.WriteLine(list.Compose()(10)); // -0,713268027987389
This is basically the same as this:
PHP:
Console.WriteLine(Math.Tan(Math.Sin(Math.Cos(Math.Log(10))))); // -0,713268027987389
...basically our extensions methods created this function composition, by using Linq Aggregate, with an initial value of the Identity function, and the Compose function for the aggregation.
 

Solarion

Honorary Master
Joined
Nov 14, 2012
Messages
21,885
Very helpful thanks roi. Doing this course all this week and this weekend coming and they're on lambda's, delegates etc but they don't explain it too well, just briefly then it's up to the student to go and research it.
 

[)roi(]

Executive Member
Joined
Apr 15, 2005
Messages
6,282
Very helpful thanks roi. Doing this course all this week and this weekend coming and they're on lambda's, delegates etc but they don't explain it too well, just briefly then it's up to the student to go and research it.
Here's a good article on Functional Programming in C# written by a Microsoft PM;

He also did another great one on Linq:
 

Solarion

Honorary Master
Joined
Nov 14, 2012
Messages
21,885
Thanks roi! I will get cracking on those when I get home later. I have tomorrow off and all weekend.
 

[)roi(]

Executive Member
Joined
Apr 15, 2005
Messages
6,282
Thanks roi! I will get cracking on those when I get home later. I have tomorrow off and all weekend.
He covers a lot in those articles, so you probably need far more time than just a weekend and lots of practice. He assumes quite a bit as in terms of prior theorectical understanding, because the article touches on parts of type & category theory.

So just a caution: Lambdas are just a border case solution in Functional Programming, FP overall has a far greater complexity than OOP, so don't be concerned when this seems like highly technical gobbledygook... In the beginning it's going to feel like you're not understanding anything; a way around this is to take a small section,and play with it in code. Btw PM if you get stuck on anything and either need help with use cases or even some easier examples to understand.

Note: if you make it as far as Partial functions and Function Currying; these are practical FP ways to accomodate Dependency Injection higher up the call stack.
 
Last edited:
Top