Let Us Learn Lambda Using C# 3.0 - Presentation Transcript
M Sheik Uduman Ali Technical Lead iSOFT Plc [email_address] Let Us Learn
Procedural Programming
int i = 0;
i = i + 10;
Output is deterministic σ ΄ = f( σ )
Modifying the values of variables – state
σ = σ 0 σ 1 σ 2 … σ n = σ
Sequential, conditional and repeated
expression
Functional Programming
Recursive functions – sequence is meaningless
Variables are actually values
// Procedural
int Sum(int from, int to)
{
int result = 0;
for(int i = from; i <= to; i++)
result += i;
return result;
}
// Recursive
int Sum(int from, int to)
{
if(from > to) return 0;
int result = Sum(from + 1, to);
return from + result;
}
Functional Programming
Functions as values
Treated as simple objects like “Integer”
can be passed as arguments, returned as results and calculated with others
High order functions
Curried functions
Immutable data structure
MyList l0 = new MyList();
MyList l1 = l0.Add(100);
MyList l2 = l1.Add(101);
MyList result = l2.Add(102);
MyList result = new MyList().Add(100).Add(101).Add(102);
No assignments
Procedural: So What?
No side-effect on expression evaluation
More corresponds to mathematics
Code can be more general
problem solving by denotational semantics
sub expression can be evaluated in any order
parameterized
Code Comparison
C
int factorial(n) { int x = 1; while (n > 0) { x = x * n; n = n - 1; } return x; }
F#
let rec factorial num = match num with | n when n <= 1 -> 1 | n -> n * (factorial (n - 1)) fact(n) = n! if n 0, otherwise
A Debate Procedural: I can use function pointers to treat “function as objects” Functional: but you can’t create functions dynamically, and your function pointers are very limited. Procedural: Me too support recursive..! Functional: agreed. but everything is command driven as like as human approaches the computer.
A Debate Procedural: What's in denotational semantics?
Functional:
for you, state based. It is changed from input to output.
may fail to terminate, for example,
while(true) {x=x;}. alternative predicate transformers are goto, break and continue
Procedural: What's the benefit of “any order expression evaluation”? Functional: I can do parallel programming simpler way
FP: Advantages
Shorter order of magnitude O(n)
No assignments. Procedural programs consists 90% assignment statement
Real modular programming
Divide and conquer
No goto and break .
Need for Lambda Calculus
But in high order functions, insistence on naming is rather inconsistent, for example
Define x and y by x = 2 and y = 4.
Then xx = y
Lambda notation allows to denote functions without naming λx.t[x]
for example,
λ x.x + 1
λ x.x 2
function argument fn. body
Lambda Calculus: Basic
t is a lambda expression, if
t = x where x Var
t = λ x. M where x Var and M is lambda expression
t = MN where M and N are lambda expression
Three types of lambda expression:
variables (referencing lambda expression)
lambda abstractions (defining functions)
applications (invoking functions)
Lambda Calculus: Basic
In the expression λ x.xy,
x is bound variable (fall within the scope of λ )
y is free variable (take the value from expression)
Using lambda notation, traditional f(x) can be written as f x . i.e. left association
f x y means ( f ( x ) ) ( y )
λ x. λ y.t[x,y] can be written as
λ x y.t[x,y]
currying
Lambda Calculus Adoption
Anonymous function name
Type inference
Parameterized types
High order functions
Immutability
Recursion
Currying
Lazy evaluation
Lambda Calculus in .NET
Delegates
Introduced in C# 1.0, much improved in C# 2.0
Dynamically wire up a method caller to its target method
Two aspects: type and instance.
delegate int Transformer(int x); static void Main(string[] args) { Transformer t = Square; int result = t(3); Console.WriteLine(result); Console.ReadLine(); } static int Square(int x) {return x * x;} type instance actually Transformer t = new Transformer(Square)
Anonymous Methods
Introduced in C# 2.0
Define methods without name by delegate
Compiler does closure-conversion
delegate int Transformer(int x); static void Main(string[] args) { Transformer t = delegate(int x) { return x * x; }; int result = t(3); Console.WriteLine(result); Console.ReadLine(); } LC1: Anonymous Function Name private static Transformer CS$<>9__CachedAnonymousMethodDelegate1; private static int <Main>b__0(int x) { return (x * x); } Compiler generated
Generics
Introduced in C# 2.0, emphasized in C# 3.0
Way of reusability with a template
Improved type safety
Reduce casting and boxing
IEnumerable<int> myints = new List<int> { 1, 1, 2, 3, 5, 8, 11 }; foreach (int i in myints) Console.Write("{0} ", i);
Lambda Expression
C# 3.0’s anonymous method
Anonymous method written in place of a delegate instance.
delegate int Transformer(int x); static void Main(string[] args) { Transformer t = x => return x * x; int result = t(3); Console.WriteLine(result); Console.ReadLine(); }
Lighter syntax
Implicit typed parameters
LC2: Type inference
Generic Lambda Expression
Very lighter syntax
For methods of any return type and any reasonable number of arguments.
delegate TResult X <T> ( ); delegate TResult X <T,TResult> (T1 arg1); delegate TResult X <T1,T2,TResult> (T1 arg1, T2 arg2); delegate TResult X <T1,T2,T3,..Tn,TResult> (T1 arg1, T2 arg2, T3 arg3,...,Tn argn); Func<int, int> t = x => x * x; int result = t(4); Console.WriteLine(result); Console.ReadLine(); LC3: Parameterized type Func | Action
Generic Lambda Expression List<int> primes = new List<int>(); List<int> primeCubes = new List<int>(); primes.Add(2); primes.Add(3); primes.Add(5); primes.Add(7); primes.ForEach(x => primeCubes.Add(x * x * x)); foreach (int i in primeCubes) { Console.WriteLine(i); } LC4: High Order Function LC5: Immutability
First part of this presentation explains basics and more
First part of this presentation explains basics and advantages of using functional programming approaches with lambda calculus.
Second part of this presentation explains how can we use lambda calculus in C# 3.0 less
0 comments
Post a comment