functional programming part ii - auckland · 2018. 9. 13. · comp (f#) comp (c#) comp (js) if loop...
Post on 17-Feb-2021
3 Views
Preview:
TRANSCRIPT
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Functional Programming – Part II
Radu NicolescuDepartment of Computer Science
University of Auckland
12 Sept 2018Updated 14 Sept 2018
1 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
1 Composition and Pipelining (F#)
2 Composition and Pipelining (C#)
3 Composition and Pipelining (JS)
4 Composition IF
5 Composition LOOP
6 Composition and Types
7 Currying and Partial Application
8 Extension Methods (C#)
9 Recursion
2 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Outline
1 Composition and Pipelining (F#)
2 Composition and Pipelining (C#)
3 Composition and Pipelining (JS)
4 Composition IF
5 Composition LOOP
6 Composition and Types
7 Currying and Partial Application
8 Extension Methods (C#)
9 Recursion
3 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition in a nutshell (F#)
• Forward composition (left-to-right)
1 l e t h = f 1 >> f 22 l e t h = f 1 >> f 2 >> f 3 . . .
• Function composition is associative
1 ( f 1 >> f 2 ) >> f 3 ≡ f 1 >> ( f 2 >> f 3 )
• Functions must be compatible!
1 f 1 : ’ a1 −> ’ a22 f 2 : ’ a2 −> ’ a33 f 1 >> f 2 : ’ a1 −> ’ a3
4 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition in a nutshell (F#)
• Forward composition (left-to-right)
1 l e t h = f 1 >> f 22 l e t h = f 1 >> f 2 >> f 3 . . .
• Function composition is associative
1 ( f 1 >> f 2 ) >> f 3 ≡ f 1 >> ( f 2 >> f 3 )
• Functions must be compatible!
1 f 1 : ’ a1 −> ’ a22 f 2 : ’ a2 −> ’ a33 f 1 >> f 2 : ’ a1 −> ’ a3
4 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition in a nutshell (F#)
• Forward composition (left-to-right)
1 l e t h = f 1 >> f 22 l e t h = f 1 >> f 2 >> f 3 . . .
• Function composition is associative
1 ( f 1 >> f 2 ) >> f 3 ≡ f 1 >> ( f 2 >> f 3 )
• Functions must be compatible!
1 f 1 : ’ a1 −> ’ a22 f 2 : ’ a2 −> ’ a33 f 1 >> f 2 : ’ a1 −> ’ a3
4 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipelines in a nutshell (F#)
• Forward pipeline (left-to-right)
1 l e t y = x |> f 12 l e t y = x |> f 1 |> f 2 . . .
• Forward pipelines are left-associative
1 x |> f 1 |> f 2 ≡ ( x |> f 1 ) |> f 2
• Again, compatibility required!
5 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipelines in a nutshell (F#)
• Forward pipeline (left-to-right)
1 l e t y = x |> f 12 l e t y = x |> f 1 |> f 2 . . .
• Forward pipelines are left-associative
1 x |> f 1 |> f 2 ≡ ( x |> f 1 ) |> f 2
• Again, compatibility required!
5 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipelines in a nutshell (F#)
• Forward pipeline (left-to-right)
1 l e t y = x |> f 12 l e t y = x |> f 1 |> f 2 . . .
• Forward pipelines are left-associative
1 x |> f 1 |> f 2 ≡ ( x |> f 1 ) |> f 2
• Again, compatibility required!
5 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition vs Pipelines (F#)
• Equivalent
1 l e t y = x |> f 1 |> f 223 l e t y = ( f 1 >> f 2 ) x
• Definitions?
6 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition vs Pipelines (F#)
• Equivalent
1 l e t y = x |> f 1 |> f 223 l e t y = ( f 1 >> f 2 ) x
• Definitions?
6 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Sidebar: operators (F#)
• Equivalent
1 l e t ( ∗+) x y = x∗x + y∗y23 l e t a = ( ∗+) 3 44 l e t b = 3 ∗+ 456 p r i n t f n ”%d %d” a b // 25 25
7 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition and Pipelines: Definitions (F#)
• Forward composition (left-to-right)
1 l e t (>>) f g = fun x −> g ( f x )
• Forward pipeline (left-to-right)
1 l e t ( |>) x f = f x
• Reverse composition (right-to-left) – as in maths (f ◦ g)
1 l e t (
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition and Pipelines: Definitions (F#)
• Forward composition (left-to-right)
1 l e t (>>) f g = fun x −> g ( f x )
• Forward pipeline (left-to-right)
1 l e t ( |>) x f = f x
• Reverse composition (right-to-left) – as in maths (f ◦ g)
1 l e t (
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Forward and Reverse Pipelines (F#)
• Avoiding extra parentheses
1 l e t f x y = ( x+1)∗y23 l e t y = f (2+1) (6+1)45 l e t z = 2+1 |> f
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition Samples (F#)
• Composition Samples (F#)
1 l e t (>>) f g = fun x −> g ( f x )23 l e t h2 =4 ( fun ( x : s t r i n g ) −> x . Length ) >>5 ( fun y −> ( double y ) / 2 . 0 )6 l e t r2 = h2 ” abc ” // 1 .578 l e t h3 =9 ( fun ( x : s t r i n g ) −> x . Length ) >>
10 ( fun y −> ( double y ) / 2 . 0 ) >>11 ( fun z −> z +1.0)12 l e t r3 = h3 ” abc ” // 2 .5
10 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipeline Samples (F#)
• Pipeline Samples (F#)1 l e t ( |>) x f = f x23 l e t r1 =4 ” abc ”5 |> fun x −> x . Length67 l e t r2 =8 ” abc ”9 |> fun x −> x . Length
10 |> fun y −> ( double y ) / 2 . 01112 l e t r3 =13 ” abc ”14 |> fun x −> x . Length15 |> fun y −> ( double y ) / 2 . 016 |> fun z −> z +1.0
11 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Outline
1 Composition and Pipelining (F#)
2 Composition and Pipelining (C#)
3 Composition and Pipelining (JS)
4 Composition IF
5 Composition LOOP
6 Composition and Types
7 Currying and Partial Application
8 Extension Methods (C#)
9 Recursion
12 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition as high-order function (C#)
• More complicated than in F# /• Forward composition (left-to-right) as high-order function
1 Func H ( Func f , Func g ) {2 return x => g ( f ( x ) ) ;3 }
• Sample1 Func h2 =2 H ( ( s t r i n g x ) => x . Length , y => y / 2 . 0 ) ;3 var r2 = h2 ( ” abc ” ) ; // 1 . 545 Func h3 =6 H (H ( ( s t r i n g x ) => x . Length , y => y / 2 . 0 ) ,7 z => z +1);8 var r3 = h3 ( ” abc ” ) ; // 2 . 5
13 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition as high-order function (C#)
• More complicated than in F# /• Forward composition (left-to-right) as high-order function
1 Func H ( Func f , Func g ) {2 return x => g ( f ( x ) ) ;3 }
• Sample1 Func h2 =2 H ( ( s t r i n g x ) => x . Length , y => y / 2 . 0 ) ;3 var r2 = h2 ( ” abc ” ) ; // 1 . 545 Func h3 =6 H (H ( ( s t r i n g x ) => x . Length , y => y / 2 . 0 ) ,7 z => z +1);8 var r3 = h3 ( ” abc ” ) ; // 2 . 5
13 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipeline as high-order function (C#)
• More complicated than in F# /• Forward pipeline (left-to-right)
1 B P (A x , Func f ) {2 return f ( x ) ;3 }
• Sample1 var r1 = P ( ” abc ” , x => x . Length ) ; // 323 var r2 = P (P ( ” abc ” , x => x . Length ) ,4 y => y / 2 . 0 ) ; // 1 . 556 var r3 = P (P (P ( ” abc ” , x => x . Length ) ,7 y => y / 2 . 0 ) ,8 z => z +1); // 2 . 5
14 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipeline as high-order function (C#)
• More complicated than in F# /• Forward pipeline (left-to-right)
1 B P (A x , Func f ) {2 return f ( x ) ;3 }
• Sample1 var r1 = P ( ” abc ” , x => x . Length ) ; // 323 var r2 = P (P ( ” abc ” , x => x . Length ) ,4 y => y / 2 . 0 ) ; // 1 . 556 var r3 = P (P (P ( ” abc ” , x => x . Length ) ,7 y => y / 2 . 0 ) ,8 z => z +1); // 2 . 5
14 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipelines – A Better Solution (C#)
• Extension methods!
• At the end of this handout
15 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Outline
1 Composition and Pipelining (F#)
2 Composition and Pipelining (C#)
3 Composition and Pipelining (JS)
4 Composition IF
5 Composition LOOP
6 Composition and Types
7 Currying and Partial Application
8 Extension Methods (C#)
9 Recursion
16 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition as high-order function (JS)
• Again, more complicated than in F# /
• Forward composition (left-to-right) as high-order function
1 funct ion H ( f , g ) { return x => g ( f ( x ) ) }
• Sample
1 l e t h2 =2 H ( x => x . l e n g t h , y => y / 2 . 0 )3 l e t r2 = h2 ( ” abc ” ) // 1 . 545 l e t h3 =6 H (H ( x => x . l e n g t h , y => y / 2 . 0 ) , z => z+1)7 l e t r3 = h3 ( ” abc ” ) // 2 . 5
17 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition as high-order function (JS)
• Again, more complicated than in F# /
• Forward composition (left-to-right) as high-order function
1 funct ion H ( f , g ) { return x => g ( f ( x ) ) }
• Sample
1 l e t h2 =2 H ( x => x . l e n g t h , y => y / 2 . 0 )3 l e t r2 = h2 ( ” abc ” ) // 1 . 545 l e t h3 =6 H (H ( x => x . l e n g t h , y => y / 2 . 0 ) , z => z+1)7 l e t r3 = h3 ( ” abc ” ) // 2 . 5
17 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipe/Composition as high-order function (JS)
• “Pipe” from ramda
• In fact, this “pipe” is a forward composition (left-to-right)1 var R = r e q u i r e ( ’ ramda ’ )
• Sample1 l e t p1 = R . p i p e ( x => x . l e n g t h )2 l e t r1 = p1 ( ” abc ” ) // 334 l e t p2 = R . p i p e ( x => x . l e n g t h , y => y / 2 . 0 )5 l e t r2 = p2 ( ” abc ” ) // 1 . 567 l e t p3 =8 R . p i p e ( x => x . l e n g t h , y => y / 2 . 0 , z => z+1)9 l e t r3 = p3 ( ” abc ” ) // 2 . 5
18 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipe/Composition as high-order function (JS)
• “Pipe” from ramda
• In fact, this “pipe” is a forward composition (left-to-right)1 var R = r e q u i r e ( ’ ramda ’ )
• Sample1 l e t p1 = R . p i p e ( x => x . l e n g t h )2 l e t r1 = p1 ( ” abc ” ) // 334 l e t p2 = R . p i p e ( x => x . l e n g t h , y => y / 2 . 0 )5 l e t r2 = p2 ( ” abc ” ) // 1 . 567 l e t p3 =8 R . p i p e ( x => x . l e n g t h , y => y / 2 . 0 , z => z+1)9 l e t r3 = p3 ( ” abc ” ) // 2 . 5
18 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipe/Composition as high-order function (JS)
• “Pipe” custom definition
1 const p i p e = ( . . . f u n c s ) =>2 f u n c s . r e d u c e (3 ( acc , c u r r ) => x => c u r r ( acc ( x ) ) , i => i ) ;
• Will be discussed later (Array.reduce)
• Sample
1 l e t p3 =2 p i p e ( x => x . l e n g t h , y => y / 2 . 0 , z => z+1)3 l e t r 3 = p3 ( ” abc ” ) // 2 . 5
• Mozilla experimental feature: |> !
19 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipe/Composition as high-order function (JS)
• “Pipe” custom definition
1 const p i p e = ( . . . f u n c s ) =>2 f u n c s . r e d u c e (3 ( acc , c u r r ) => x => c u r r ( acc ( x ) ) , i => i ) ;
• Will be discussed later (Array.reduce)
• Sample
1 l e t p3 =2 p i p e ( x => x . l e n g t h , y => y / 2 . 0 , z => z+1)3 l e t r 3 = p3 ( ” abc ” ) // 2 . 5
• Mozilla experimental feature: |> !
19 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Pipe/Composition as high-order function (JS)
• “Pipe” custom definition
1 const p i p e = ( . . . f u n c s ) =>2 f u n c s . r e d u c e (3 ( acc , c u r r ) => x => c u r r ( acc ( x ) ) , i => i ) ;
• Will be discussed later (Array.reduce)
• Sample
1 l e t p3 =2 p i p e ( x => x . l e n g t h , y => y / 2 . 0 , z => z+1)3 l e t r 3 = p3 ( ” abc ” ) // 2 . 5
• Mozilla experimental feature: |> !
19 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Outline
1 Composition and Pipelining (F#)
2 Composition and Pipelining (C#)
3 Composition and Pipelining (JS)
4 Composition IF
5 Composition LOOP
6 Composition and Types
7 Currying and Partial Application
8 Extension Methods (C#)
9 Recursion
20 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition IF (F#)
• IF as high-order function
1 l e t I f ( c , f , g ) =2 fun x −> i f c x then f x e l s e g x
• Sample
1 l e t h =2 I f (3 ( fun x −> x%2=1),4 ( fun x −> x +1) ,5 ( fun x −> 2∗x ) )67 l e t r10 = h 10 // 208 l e t r11 = h 11 // 12
21 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition IF (F#)
• IF as high-order function
1 l e t I f ( c , f , g ) =2 fun x −> i f c x then f x e l s e g x
• Sample
1 l e t h =2 I f (3 ( fun x −> x%2=1),4 ( fun x −> x +1) ,5 ( fun x −> 2∗x ) )67 l e t r10 = h 10 // 208 l e t r11 = h 11 // 12
21 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition IF (C#)
• IF as high-order function1 Func I f (2 Func c ,3 Func f ,4 Func g ) {5 return x => c ( x )? f ( x ) : g ( x ) ;6 }
• Sample1 var h =2 I f (3 ( i n t x ) => x%2==1,4 ( i n t x ) => x+1,5 ( i n t x ) => 2∗x ) ;67 var r10 = h ( 1 0 ) ; // 208 var r11 = h ( 1 1 ) ; // 12
22 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition IF (C#)
• IF as high-order function1 Func I f (2 Func c ,3 Func f ,4 Func g ) {5 return x => c ( x )? f ( x ) : g ( x ) ;6 }
• Sample1 var h =2 I f (3 ( i n t x ) => x%2==1,4 ( i n t x ) => x+1,5 ( i n t x ) => 2∗x ) ;67 var r10 = h ( 1 0 ) ; // 208 var r11 = h ( 1 1 ) ; // 12
22 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition IF (JS)
• IF as high-order function
1 funct ion I f ( c , f , g ) {2 return x => c ( x ) ? f ( x ) : g ( x )3 }
• Sample
1 l e t h =2 I f (3 ( x => x%2===1),4 ( x => x +1) ,5 ( x => 2∗x ) )67 l e t r10 = h ( 1 0 ) // 208 l e t r11 = h ( 1 1 ) // 11
23 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition IF (JS)
• IF as high-order function
1 funct ion I f ( c , f , g ) {2 return x => c ( x ) ? f ( x ) : g ( x )3 }
• Sample
1 l e t h =2 I f (3 ( x => x%2===1),4 ( x => x +1) ,5 ( x => 2∗x ) )67 l e t r10 = h ( 1 0 ) // 208 l e t r11 = h ( 1 1 ) // 11
23 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Outline
1 Composition and Pipelining (F#)
2 Composition and Pipelining (C#)
3 Composition and Pipelining (JS)
4 Composition IF
5 Composition LOOP
6 Composition and Types
7 Currying and Partial Application
8 Extension Methods (C#)
9 Recursion
24 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition LOOP (F#)
• LOOP as high-order function – tail recursive!1 l e t rec Loop ( c , f ) =2 fun x −> i f c ( x ) then Loop ( c , f ) ( f x ) e l s e x
• Sample1 l e t h =2 Loop (3 ( fun x −> x < 100) ,4 ( fun x −> x + x ) )5 l e t r = h 10 // 160
• Equivalent1 l e t mutable x ’ = 102 whi le ( x ’ < 100) do3 x ’
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition LOOP (F#)
• LOOP as high-order function – tail recursive!1 l e t rec Loop ( c , f ) =2 fun x −> i f c ( x ) then Loop ( c , f ) ( f x ) e l s e x
• Sample1 l e t h =2 Loop (3 ( fun x −> x < 100) ,4 ( fun x −> x + x ) )5 l e t r = h 10 // 160
• Equivalent1 l e t mutable x ’ = 102 whi le ( x ’ < 100) do3 x ’
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition LOOP (F#)
• LOOP as high-order function – tail recursive!1 l e t rec Loop ( c , f ) =2 fun x −> i f c ( x ) then Loop ( c , f ) ( f x ) e l s e x
• Sample1 l e t h =2 Loop (3 ( fun x −> x < 100) ,4 ( fun x −> x + x ) )5 l e t r = h 10 // 160
• Equivalent1 l e t mutable x ’ = 102 whi le ( x ’ < 100) do3 x ’
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition LOOP (C#)
• LOOP as high-order function
1 Func Loop (2 Func c ,3 Func f ) {4 return x => c ( x )? Loop ( c , f ) ( f ( x ) ) : x ;5 }
• Sample
1 var h = Loop (2 ( i n t x ) => x < 100 ,3 ( i n t x ) => x + x ) ;4 var r = h ( 1 0 ) ; // 160
26 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition LOOP (C#)
• LOOP as high-order function
1 Func Loop (2 Func c ,3 Func f ) {4 return x => c ( x )? Loop ( c , f ) ( f ( x ) ) : x ;5 }
• Sample
1 var h = Loop (2 ( i n t x ) => x < 100 ,3 ( i n t x ) => x + x ) ;4 var r = h ( 1 0 ) ; // 160
26 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition LOOP (JS)
• LOOP as high-order function
1 funct ion Loop ( c , f ) {2 return x => c ( x ) ? Loop ( c , f ) ( f ( x ) ) : x3 }
• Sample
1 l e t h =2 Loop (3 ( x => x < 100) ,4 ( x => x + x ) )5 l e t r = h ( 1 0 ) // 160
27 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Composition LOOP (JS)
• LOOP as high-order function
1 funct ion Loop ( c , f ) {2 return x => c ( x ) ? Loop ( c , f ) ( f ( x ) ) : x3 }
• Sample
1 l e t h =2 Loop (3 ( x => x < 100) ,4 ( x => x + x ) )5 l e t r = h ( 1 0 ) // 160
27 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Outline
1 Composition and Pipelining (F#)
2 Composition and Pipelining (C#)
3 Composition and Pipelining (JS)
4 Composition IF
5 Composition LOOP
6 Composition and Types
7 Currying and Partial Application
8 Extension Methods (C#)
9 Recursion
28 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
JS Composition is Type-less
• In JS you can get runtime type errors after inserting arbitraryobjects in a pipe
• Typical custom definition:1 const p i p e = ( . . . f u n c s ) =>2 f u n c s . r e d u c e (3 ( acc , c u r r ) => x => c u r r ( acc ( x ) ) , i => i ) ;
• Sample wrong code...1 l e t p3 = p i p e ( 7 , ” abc ” )2 l e t r 3 = p3 ( )
• ... which stops with runtime type error1 // TypeEr ror : c u r r i s not a f u n c t i o n
29 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
C# and F# Compositions are Type-aware
• NO runtime type errors: only compatible functions can becomposed
• Explicitly typed C# code:1 Func H ( Func f , Func g ) {2 return x => g ( f ( x ) ) ;3 }
• Implicitly typed F# code:1 l e t (>>) f g = fun x −> g ( f x )
• F# types are inferred and can be visualised, e.g. with FSI1 > (>>);;2 ( ( ’ a −> ’ b ) −> ( ’ b −> ’ c ) −> ’ a −> ’ c )
30 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
F# Composition with explicit types
• Implicitly typed F# code:
1 l e t (>>) f g = fun x −> g ( f x )
• Although not usual, F# types can be made explicit:
1 l e t (>>) ( f : ’ a−>’b ) ( g : ’ b−>’c ) : ’ a−>’c =2 fun x −> g ( f x )
31 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
F# Compositions – Types Summary
• Forward (LR) composition:1 l e t (>>) f g = fun x −> g ( f x )2 // ( ’ a−>’b ) −> ( ’ b−>’c ) −> ’ a −> ’ c
• Forward (LR) pipe:1 l e t ( |>) x f = f x // ’ a −> ( ’ a−>’b ) −> ’ b
• IF:1 l e t I f ( c , f , g ) =2 fun x −> i f c x then f x e l s e g x3 // c : ( ’ a−>bool )∗ f : ( ’ a−>’b )∗ g : ( ’ a−>’b ) −> x : ’ a −> ’ b
• LOOP:1 l e t rec Loop ( c , f ) =2 fun x −> i f c ( x ) then Loop ( c , f ) ( f x ) e l s e x3 // c : ( ’ a−>bool )∗ f : ( ’ a−>’a ) −> x : ’ a −> ’ a
32 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Outline
1 Composition and Pipelining (F#)
2 Composition and Pipelining (C#)
3 Composition and Pipelining (JS)
4 Composition IF
5 Composition LOOP
6 Composition and Types
7 Currying and Partial Application
8 Extension Methods (C#)
9 Recursion
33 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying
Programming technique inspired from mathematical logic,following ideas developed by Moses Schönfinkel and Haskell Curry.
Problem
Transform a function with n parameters into a chain of n functionswith one parameter each
34 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying – Benefits
• Optimizations are possible by partial evaluation of functions
• Pipelining is straightforward with functions of one parameter
• Theoretical proofs are easier with functions of one parameter
35 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of two parameters
Given p : A× B → Cdetermine q : A→ (B → C )such that p(x , y) = q(x)(y)
36 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of two parameters (C#)
• Sample (where A = B = C = int):
1 Func p = ( x , y ) => x∗x + y∗y ;2 Func q = x => y => x∗x + y∗y ;3 Func q2 = x => ( y => x∗x + y∗y ) ;
• Optimised equivalent for q(3)1 Func q ( 3 ) = y => 9 + y∗y ;2 // potentially faster than 3*3 + y*y
• Usage1 var b = q ( 3 ) ( 4 ) ; // 252 var b2 = q2 ( 3 ) ( 4 ) ; // 2534 Func r = q2 ( 3 ) ;5 var c1 = r ( 4 ) ; // 256 var c2 = r ( 5 ) ; // 34
37 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of two parameters (C#)
• Sample (where A = B = C = int):
1 Func p = ( x , y ) => x∗x + y∗y ;2 Func q = x => y => x∗x + y∗y ;3 Func q2 = x => ( y => x∗x + y∗y ) ;
• Optimised equivalent for q(3)1 Func q ( 3 ) = y => 9 + y∗y ;2 // potentially faster than 3*3 + y*y
• Usage1 var b = q ( 3 ) ( 4 ) ; // 252 var b2 = q2 ( 3 ) ( 4 ) ; // 2534 Func r = q2 ( 3 ) ;5 var c1 = r ( 4 ) ; // 256 var c2 = r ( 5 ) ; // 34
37 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of two parameters (C#)
• Sample (where A = B = C = int):
1 Func p = ( x , y ) => x∗x + y∗y ;2 Func q = x => y => x∗x + y∗y ;3 Func q2 = x => ( y => x∗x + y∗y ) ;
• Optimised equivalent for q(3)1 Func q ( 3 ) = y => 9 + y∗y ;2 // potentially faster than 3*3 + y*y
• Usage1 var b = q ( 3 ) ( 4 ) ; // 252 var b2 = q2 ( 3 ) ( 4 ) ; // 2534 Func r = q2 ( 3 ) ;5 var c1 = r ( 4 ) ; // 256 var c2 = r ( 5 ) ; // 34
37 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of two parameters (JS)
• Sample
1 l e t p = ( x , y ) => x∗x + y∗y23 l e t q = x => y => x∗x + y∗y4 l e t q2 = x => ( y => p ( x , y ) )
• Usage
1 l e t b = q ( 3 ) ( 4 )2 l e t b2 = q2 ( 3 ) ( 4 )34 l e t r = q ( 3 )5 l e t c1 = r ( 4 )6 l e t c2 = r ( 5 )
38 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of two parameters (JS)
• Sample
1 l e t p = ( x , y ) => x∗x + y∗y23 l e t q = x => y => x∗x + y∗y4 l e t q2 = x => ( y => p ( x , y ) )
• Usage
1 l e t b = q ( 3 ) ( 4 )2 l e t b2 = q2 ( 3 ) ( 4 )34 l e t r = q ( 3 )5 l e t c1 = r ( 4 )6 l e t c2 = r ( 5 )
38 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of “two” parameters (F#)
• Sample1 // p : i n t ∗ i n t −> i n t2 l e t p = fun ( x , y ) −> x∗x + y∗y34 // q : i n t −> i n t −> i n t5 l e t q = fun x −> fun y −> x∗x + y∗y6 l e t q ’ = fun x −> ( fun y −> p ( x , y ) )
• Usage1 l e t b = q 3 42 l e t b ’ = q ’ 3 434 // r : i n t −> i n t5 l e t r = q 36 l e t c1 = r 47 l e t c2 = r 5
39 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of “two” parameters (F#)
• Sample1 // p : i n t ∗ i n t −> i n t2 l e t p = fun ( x , y ) −> x∗x + y∗y34 // q : i n t −> i n t −> i n t5 l e t q = fun x −> fun y −> x∗x + y∗y6 l e t q ’ = fun x −> ( fun y −> p ( x , y ) )
• Usage1 l e t b = q 3 42 l e t b ’ = q ’ 3 434 // r : i n t −> i n t5 l e t r = q 36 l e t c1 = r 47 l e t c2 = r 5
39 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of “two” parameters (F#)?
• All F# functions have one single parameter!• This function has one single parameter, which is a tuple
1 // p : i n t ∗ i n t −> i n t2 l e t p = fun ( x , y ) −> x∗x + y∗y
• Example: function that returns a function (chained functions)
1 // q ’ ’ : i n t −> i n t −> i n t2 l e t q ’ ’ x y = x∗x + y∗y
• Equivalent function:
1 // q : i n t −> i n t −> i n t2 l e t q = fun x −> fun y −> x∗x + y∗y
40 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of “two” parameters (F#)?
• All F# functions have one single parameter!• This function has one single parameter, which is a tuple
1 // p : i n t ∗ i n t −> i n t2 l e t p = fun ( x , y ) −> x∗x + y∗y
• Example: function that returns a function (chained functions)
1 // q ’ ’ : i n t −> i n t −> i n t2 l e t q ’ ’ x y = x∗x + y∗y
• Equivalent function:
1 // q : i n t −> i n t −> i n t2 l e t q = fun x −> fun y −> x∗x + y∗y
40 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of “two” parameters (F#)?
• All F# functions have one single parameter!• This function has one single parameter, which is a tuple
1 // p : i n t ∗ i n t −> i n t2 l e t p = fun ( x , y ) −> x∗x + y∗y
• Example: function that returns a function (chained functions)
1 // q ’ ’ : i n t −> i n t −> i n t2 l e t q ’ ’ x y = x∗x + y∗y
• Equivalent function:
1 // q : i n t −> i n t −> i n t2 l e t q = fun x −> fun y −> x∗x + y∗y
40 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of three parameters (C#)
Given q : A× B × C → Ddetermine q1 : A→ (B → (C → D))such that q(x , y , z) = q1(x)(y)(z)
Example (where A = B = C = D = int):
1 Func2 q = ( x , y , z ) => x∗x + y∗y + z∗ z ;
1 Func2 q1 = x => ( y => ( z => x∗x + y∗y + z∗ z ) ) ;
1 q1 ( 1 0 ) ( 2 0 ) = z => 500 + z ;2 // potentially faster than 10*10 + 20*20 + z*z
41 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of three parameters (C#)
Given q : A× B × C → Ddetermine q1 : A→ (B → (C → D))such that q(x , y , z) = q1(x)(y)(z)
Example (where A = B = C = D = int):
1 Func2 q = ( x , y , z ) => x∗x + y∗y + z∗ z ;
1 Func2 q1 = x => ( y => ( z => x∗x + y∗y + z∗ z ) ) ;
1 q1 ( 1 0 ) ( 2 0 ) = z => 500 + z ;2 // potentially faster than 10*10 + 20*20 + z*z
41 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of three parameters (C#)
Given q : A× B × C → Ddetermine q1 : A→ (B → (C → D))such that q(x , y , z) = q1(x)(y)(z)
Example (where A = B = C = D = int):
1 Func2 q = ( x , y , z ) => x∗x + y∗y + z∗ z ;
1 Func2 q1 = x => ( y => ( z => x∗x + y∗y + z∗ z ) ) ;
1 q1 ( 1 0 ) ( 2 0 ) = z => 500 + z ;2 // potentially faster than 10*10 + 20*20 + z*z
41 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Currying a function of three parameters (C#)
Given q : A× B × C → Ddetermine q1 : A→ (B → (C → D))such that q(x , y , z) = q1(x)(y)(z)
Example (where A = B = C = D = int):
1 Func2 q = ( x , y , z ) => x∗x + y∗y + z∗ z ;
1 Func2 q1 = x => ( y => ( z => x∗x + y∗y + z∗ z ) ) ;
1 q1 ( 1 0 ) ( 2 0 ) = z => 500 + z ;2 // potentially faster than 10*10 + 20*20 + z*z
41 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Outline
1 Composition and Pipelining (F#)
2 Composition and Pipelining (C#)
3 Composition and Pipelining (JS)
4 Composition IF
5 Composition LOOP
6 Composition and Types
7 Currying and Partial Application
8 Extension Methods (C#)
9 Recursion
42 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension Methods in a Nutshell (C#)
• Retrofitting F#-style pipes in C#, an initially OO language
• F# pipeline of functions
1 s |> Foo |> Goo |> Hoo
• C# simulation via cascading/fluent method chaining
1 s . Foo ( ) . Goo ( ) . Hoo ( )
• It seems that we have to extend existing classes...but these may be sealed ( final in Java) /
• Extension methods come to the rescue ,
43 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension Methods in a Nutshell (C#)
• Retrofitting F#-style pipes in C#, an initially OO language
• F# pipeline of functions
1 s |> Foo |> Goo |> Hoo
• C# simulation via cascading/fluent method chaining
1 s . Foo ( ) . Goo ( ) . Hoo ( )
• It seems that we have to extend existing classes...but these may be sealed ( final in Java) /
• Extension methods come to the rescue ,
43 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension Methods in a Nutshell (C#)
• Retrofitting F#-style pipes in C#, an initially OO language
• F# pipeline of functions
1 s |> Foo |> Goo |> Hoo
• C# simulation via cascading/fluent method chaining
1 s . Foo ( ) . Goo ( ) . Hoo ( )
• It seems that we have to extend existing classes...but these may be sealed ( final in Java) /
• Extension methods come to the rescue ,
43 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension Methods in a Nutshell (C#)
• Retrofitting F#-style pipes in C#, an initially OO language
• F# pipeline of functions
1 s |> Foo |> Goo |> Hoo
• C# simulation via cascading/fluent method chaining
1 s . Foo ( ) . Goo ( ) . Hoo ( )
• It seems that we have to extend existing classes...but these may be sealed ( final in Java) /
• Extension methods come to the rescue ,
43 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension Methods (C#)
An extension method:
• Is defined as a static method
• appears in a class decorated as static (see below)
• its first parameter is decorated with this
• despite being static, can also be can be called in instancenotation, where its first parameter appears as its target
A static class is equivalent to a sealed class with a privateconstructor: therefore, you can’t subclass it and you can’tinstantiate it! Its only purpose is to define extension methods.
44 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension Methods (C#)
An extension method:
• Is defined as a static method
• appears in a class decorated as static (see below)
• its first parameter is decorated with this
• despite being static, can also be can be called in instancenotation, where its first parameter appears as its target
A static class is equivalent to a sealed class with a privateconstructor: therefore, you can’t subclass it and you can’tinstantiate it! Its only purpose is to define extension methods.
44 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension Methods (C#)
An extension method:
• Is defined as a static method
• appears in a class decorated as static (see below)
• its first parameter is decorated with this
• despite being static, can also be can be called in instancenotation, where its first parameter appears as its target
A static class is equivalent to a sealed class with a privateconstructor: therefore, you can’t subclass it and you can’tinstantiate it! Its only purpose is to define extension methods.
44 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension Methods (C#)
An extension method:
• Is defined as a static method
• appears in a class decorated as static (see below)
• its first parameter is decorated with this
• despite being static, can also be can be called in instancenotation, where its first parameter appears as its target
A static class is equivalent to a sealed class with a privateconstructor: therefore, you can’t subclass it and you can’tinstantiate it! Its only purpose is to define extension methods.
44 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension Methods (C#)
An extension method:
• Is defined as a static method
• appears in a class decorated as static (see below)
• its first parameter is decorated with this
• despite being static, can also be can be called in instancenotation, where its first parameter appears as its target
A static class is equivalent to a sealed class with a privateconstructor: therefore, you can’t subclass it and you can’tinstantiate it! Its only purpose is to define extension methods.
44 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension method (C#) – sample
Consider that we want to “extend” the (already sealed) Systemclass string with a new method bool Foo(int).
1 var b = ” abc ” . Foo ( 7 ) ; // ???
We cannot really extend class string, because it is sealed (whichcorresponds to final in Java)...
However, we can “emulate” such an extension as a static methodin a static class:
1 static c l a s s MyExtens ions {2 static bool Foo (this s t r i n g s , i n t i ) {3 . . .4 }5 }
45 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension method (C#) – sample
Consider that we want to “extend” the (already sealed) Systemclass string with a new method bool Foo(int).
1 var b = ” abc ” . Foo ( 7 ) ; // ???
We cannot really extend class string, because it is sealed (whichcorresponds to final in Java)...
However, we can “emulate” such an extension as a static methodin a static class:
1 static c l a s s MyExtens ions {2 static bool Foo (this s t r i n g s , i n t i ) {3 . . .4 }5 }
45 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension method (C#) – sample
Consider that we want to “extend” the (already sealed) Systemclass string with a new method bool Foo(int).
1 var b = ” abc ” . Foo ( 7 ) ; // ???
We cannot really extend class string, because it is sealed (whichcorresponds to final in Java)...
However, we can “emulate” such an extension as a static methodin a static class:
1 static c l a s s MyExtens ions {2 static bool Foo (this s t r i n g s , i n t i ) {3 . . .4 }5 }
45 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension method (C#) – sample
We can invoke Foo either as a static method, or as an instancemethod for a string object!
1 s t r i n g s = ” abc ” ;23 var b1 = MyExtens ions . Foo ( s , 7 ) ; // static call45 var b2 = s . Foo ( 7 ) ; // ”instance”-like call
For the second version (instance-like call), the compiler will searchfor an appropriate method in all available static classes (this limitsthe scope of the search)
46 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension method (C#) – sample
We can invoke Foo either as a static method, or as an instancemethod for a string object!
1 s t r i n g s = ” abc ” ;23 var b1 = MyExtens ions . Foo ( s , 7 ) ; // static call45 var b2 = s . Foo ( 7 ) ; // ”instance”-like call
For the second version (instance-like call), the compiler will searchfor an appropriate method in all available static classes (this limitsthe scope of the search)
46 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension method (C#) – sample
The instance notation is convenient for composing functions in afluent method chaining, i.e. cascading transformations (whichleads to crisp expressions) – similar to Unix-like pipelines
For example, besides Foo, assume a couple of other similarmethods, Goo and Hoo. Contrast the following two equivalentcalls, comparing them for expressiveness:
1 var b1 =2 MyExtens ions . Hoo (3 MyExtens ions . Goo (4 MyExtens ions . Foo ( s , 1 ) , 2 ) , 3 ) ;56 var b2 = s . Foo ( 1 ) . Goo ( 2 ) . Hoo ( 3 ) ;
Most functional elements in C# and LINQ are actually defined asextension methods!
47 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension method (C#) – sample
The instance notation is convenient for composing functions in afluent method chaining, i.e. cascading transformations (whichleads to crisp expressions) – similar to Unix-like pipelines
For example, besides Foo, assume a couple of other similarmethods, Goo and Hoo. Contrast the following two equivalentcalls, comparing them for expressiveness:
1 var b1 =2 MyExtens ions . Hoo (3 MyExtens ions . Goo (4 MyExtens ions . Foo ( s , 1 ) , 2 ) , 3 ) ;56 var b2 = s . Foo ( 1 ) . Goo ( 2 ) . Hoo ( 3 ) ;
Most functional elements in C# and LINQ are actually defined asextension methods!
47 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension method (C#) – sample
The instance notation is convenient for composing functions in afluent method chaining, i.e. cascading transformations (whichleads to crisp expressions) – similar to Unix-like pipelines
For example, besides Foo, assume a couple of other similarmethods, Goo and Hoo. Contrast the following two equivalentcalls, comparing them for expressiveness:
1 var b1 =2 MyExtens ions . Hoo (3 MyExtens ions . Goo (4 MyExtens ions . Foo ( s , 1 ) , 2 ) , 3 ) ;56 var b2 = s . Foo ( 1 ) . Goo ( 2 ) . Hoo ( 3 ) ;
Most functional elements in C# and LINQ are actually defined asextension methods!
47 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Extension method (C#) – caveat
Caveat: in C#, extensions methods, such as Foo, are not realinstance methods:
• Cannot access private members
• Cannot be polymorphically overridden
48 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Outline
1 Composition and Pipelining (F#)
2 Composition and Pipelining (C#)
3 Composition and Pipelining (JS)
4 Composition IF
5 Composition LOOP
6 Composition and Types
7 Currying and Partial Application
8 Extension Methods (C#)
9 Recursion
49 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Recursion in FP
Non-tail recursive factorial in F#:
1 l e t rec f a c t ( n : i n t ) =2 i f ( n
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Recursion in FP
Non-tail recursive factorial in F#:
1 l e t rec f a c t ( n : i n t ) =2 i f ( n
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Recursion in FP
Tail recursive factorial in F# – efficient! immutable values!
1 l e t rec f a c t t a i l r e c ( n : int , acc : i n t ) =2 i f ( n 0) {3 i n t n1 = n − 1 ;4 acc = n ∗ acc ;5 n = n1 ;6 }7 return acc ;8 }
51 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Recursion in FP
Tail recursive factorial in F# – efficient! immutable values!
1 l e t rec f a c t t a i l r e c ( n : int , acc : i n t ) =2 i f ( n 0) {3 i n t n1 = n − 1 ;4 acc = n ∗ acc ;5 n = n1 ;6 }7 return acc ;8 }
51 / 53
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Recursion in FP
Why avoid recursion?
• Easy to define correct but inefficient algorithms (unless we usememoization or other optimisations)
1 // combinatorial explosion2 i n t Fib ( i n t n ) {3 i f ( n
-
Comp (F#) Comp (C#) Comp (JS) IF LOOP Types Curry Ext (C#) Recursion
Recursion in FP
Why use recursion in FP?
• To define correct and efficient algorithms (via memoization orother optimisations)
• To use immutable values only (avoid changing the values ofvariables)
• Efficient implementation of tail calls, which are automaticallytransformed into loops
53 / 53
Composition and Pipelining (F#)Composition and Pipelining (C#)Composition and Pipelining (JS)Composition IFComposition LOOPComposition and TypesCurrying and Partial ApplicationExtension Methods (C#)Recursion
top related