
Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Functional Programming First class functions, lambdas and closures Radu Nicolescu Department of Computer Science University of Auckland 23 July 2018 1 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java 1 Programming paradigms 2 Pure FP 3 Recursion 4 C# Delegates 5 Lambda expressions 6 Closures 7 More Lambdas 8 Quiz { Simple scenarios 9 Lambdas in Javascript 10 Lambdas in Java 2 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Programming paradigms • Object-oriented: develop complex objects starting with simple objects (using inheritance, aggregation, delegation, ...) • Functional: develop complex functions starting with simple functions (using function composition, Kleisli, ...) • Object-oriented or functional? • Object-oriented and functional! More dimensions, more tools! • Most modern languages evolve towards a multi-paradigm style • Object-first: C#, Java, C++, ... • Functional-first: F#, Javascript (Lisp in Java syntax), ... • Object-functional: Scala, ... 4 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Side-bar: functions and methods • In classical OOP, functions only appear as methods: • Static/class methods • Instance methods (cf. this pointer) • Other languages, including FP, have standalone, even top-level, functions • Problem: how to represent anonymous inline functions (such as lambdas) in OOP? • Solution: embed these in the current object, if possible, or inside hidden automatically constructed objects { more at closures 5 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Basic ingredients of FP • first-class and higher order functions (aka, functionals) • informally, you can work with functions as with any other objects { and compose them! • you can have functions that take functions as parameters and return functions (functions which may be dynamically composed) • currying or partial application of functions • memoization (or caching) of function results • no side effects and immutable values (next slide) 6 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Pure FP • Function results should only depend on parameter values • No side effects: Functions should not change the global state or any persistent state (unlike object methods which change the object's state) • Immutable values: Ideally, functions should not change any value at all! { This is possible if we use recursion instead of classical loops... • As one of the advantages, programs will be easier to prove correct, to optimize or to parallelize 8 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Pure FP • For example, if f and g don't change any global variable nor any of their parameters (i.e., a; b; c; d), the following two statements can run in parallel, on a dual-core machine: 1 x=f(a,b); | function f could be evaluated on core #1 2 3 y=g(c,d); | function g could be evaluated on core #2 • However, many practical languages, including C# (and F#), do accept side effects, although some of them will try to explicit or localize these (e.g., via so-called monads) 9 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Variables and mutability in C# • Class fields and properties : vast topic, but not much of our concern here... • var or normal declarations are mutable 1 var x=10; x=x+1; 2 i n t x=10; x=x+1; • const defines compile-time immutable values 1 const x = 1 0 ; • readonly defines run-time immutable fields { maybe differently initialised in constructors, but then is frozen 1 readonly int x ; 10 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Variables and mutability in C# • Shallow vs deep immutability • Shallow immutable complex objects such as arrays 1 c l a s s C f 2 public static readonly int []A 3 = new i n t [] f 10 , 20 , 30 , g ; 4 g 5 6 void Main ( ) f 7 var B = new i n t [] f 100, 200, 300, g ; 8 // C .A = B; // NOT allowed 9 C .A [ 1 ] = 200; // allowed! 10 C .A. Dump ( ) ; 11 g • Conclusions: flexible but porous 11 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Variables and mutability in F# • Class fields and properties : vast topic, but not much of our concern here... • let declarations are immutable { not \variables" but values 1 l e t x = 10 • x = x + 1 is legal (!) but does NOT mean what one would think: it is a boolean equality test that returns false ! • Mutable variables must be explicitly declared so 1 l e t mutable x = 10 2 x <− x + 1 • Increased awareness: the assignment to a mutable variable uses a distinct op sign <− 12 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Variables and mutability in F# • Still shallow immutable arrays (but not other objects) 1 l e t A = [ j 1 0 ; 2 0 ; 3 0 ; j ] // A itself is immutable 2 A . [ 1 ] <− 200 // allowed! 3 A. Dump ( ) • Why this exception for arrays? Because of the HUGE body of scientific algorithms, which have been developed and optimised for FORTRAN mutable arrays • F# encourages a more pure style, and promotes increased awareness of mutability { but still allows one the choice to use other styles 13 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Variables and mutability in JS • var declarations are mutable with global scope or function \global" scope 1 var x = 10 • let declarations are mutable with block local scope 1 i f ( b ) f 2 l e t x = 10 3 x = x + 1 4 g • const declarations are immutable with block local scope 1 i f ( b ) f 2 const x = 10 3 // x = x + 1 // not allowed 4 g • More in part (M) 14 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Imperative factorial • F# 1 l e t f a c t n : i n t = 2 l e t mutable m = n 3 l e t mutable f = 1 4 while (m >= 1) do 5 f <− f ∗ m 6 m <− m − 1 7 f 8 9 p r i n t f n "Imperative: %A" (fact 5) 16 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Naive recursive factorial • F# 1 l e t rec f a c t ' n = 2 i f n <= 0 then 1 3 e l s e ( f a c t ' ( n−1)) ∗ n 4 5 p r i n t f n "Naive Recursive: %A" (fact ' 5) • Performance issues, stack overflow 17 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Tail recursive factorial • F# 1 l e t f a c t ' ' n = 2 l e t rec f a c t tailrec n acc = 3 i f ( n <= 0) then acc 4 e l s e f a c t t a i l r e c ( n−1) ( n∗ acc ) 5 f a c t t a i l r e c n 1 6 7 p r i n t f n "Tail Recursive: %A" (fact '' 5) • F# : TCO = Tail Call Optimisation • NO performance issues, NO stack overflow 18 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Tail recursive factorial { reverse engineered • C# : recursion ) while loop! 1 s t a t i c i n t f a c t t a i l r e c ( i n t n , i n t acc ) f 2 while ( n > 0) f 3 acc = n ∗ acc ; 4 n = n − 1 ; 5 g 6 return acc ; 7 g 8 public static int f a c t ( i n t n ) f 9 return f a c t tailrec(n, 1); 10 g • NO performance issues, NO stack overflow 19 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java C# Delegates in a nutshell • Consider this scenario 1 c l a s s C f 2 p u b l i c i n t F( i n t x ) f return x +1; g 3 p u b l i c i n t G( i n t y ) f return y+y ; g 4 public static int H( i n t z ) f return z ∗ z ; g 5 g • What do these three methods have in common? • Their signature: int!int • Usage (assuming using static System.Console) 1 WriteLine ($"f c1 . F (3)g f c2 .G(3)g fC .H(3)g "); 2 // 4 6 9 21 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java C# Delegates in a nutshell • Same scenario 1 c l a s s C f 2 p u b l i c i n t F( i n t x ) f return x +1; g 3 p u b l i c i n t G( i n t y ) f return y+y ; g 4 public static int H( i n t z ) f return z ∗ z ; g 5 g • More flexible usage using typed function pointers! 1 Func <int , int > f = c1 . F ; 2 Func <int , int > g = c2 .G; 3 Func <int , int > h = C .H; 4 WriteLine ($"f f (3)g fg (3)g fh (3)g "); 5 // 4 6 9 • The same pointer, e.g. f, could point in turn to all these methods! 22 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java C# Delegates • A delegate is a .NET type-safe pointer to a function, i.e. to a class or instance method • To call an instance method: obj.F (...) • To call a static method: Class .H (...) • Technically, a delegate is an object with two properties • Method: a pointer to the instance or class method (F,H) • Target { for instance methods: pointer to actual object (obj) • instance method calls depend on the actual target object • Target { for static methods: null (usually) • static methods can be fully resolved by the compiler (so the actual class is not needed at runtime) 23 / 61 Paradigms Pure Rec Delegates Lambdas Closures More QuizJS Java Predefined delegate types in C# { Function types in F# 1 Func<T1,T2,..
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages51 Page
-
File Size-