SlideShare une entreprise Scribd logo
1  sur  54
Télécharger pour lire hors ligne
Programming in Scala
Lecture Two
Angelo Corsaro
5 December 2017
Chief Technology Officer, ADLINK Technology Inc.
Table of contents i
1. Functional Programming Recap
2. Haskell Quick Start
3. Functions in Haskell
4. Functions in Scala
5. Exploring Inner Functions and Tail Recursion
6. Functions in Haskell
1
Table of contents ii
7. First Class Functions
8. Currying
9. Lambda and Closures
10. Lists
11. Homeworks
2
Functional Programming Recap
Functional Programming
Functional Programming is a method of program construction that:
• Emphasises functions and their applications as opposed to commands and
their execution.
• Uses simple mathematical notation that allows problems to be described
clearly and concisely.
• Has a simple mathematical bases that supports equational reasoning about
the properties of a program.
A functional programming languages is guided by two main ideas, functions as
first-class values and no side-effects.
3
Functions as First-Class Values
In a functional programming language:
• A function is a value as an Integer or a String.
• Functions can be passed as arguments, returned as values as well as stored
into variables.
• Functions can be named or anonymous and can be defined inside other
functions.
4
No Side-Effects
• In a functional programming language, the result of applying some
arguments to a functions should only depend on the input. In other terms,
applying the same input to a given function always gives the same output.
• Functions that satisfy this property are know to be referentially transparent.
• Functional programming languages ecnourage the use of immutable data
structures and referentually transparent functions.
Note: it is worth comparing the functional approach with the imperative style
programming were everything is based on mutable data and side-effects.
5
Haskell Quick Start
The Haskell Programming Language
Haskell is a pure, lazy, functional programming language first defined in 1990.
The programming language was named after Haskell B. Curry, who was one of
the pioneers of λ-calculus, a mathematical theory of functions that has been an
inspiration to designers of a number of functional programming languages.
The latest version of the language is Haskell-2010 and a working group was
established in 2016 to define Haskell-2020.
The Haskell’s home is http://www.haskell.org
6
Functions in Haskell
Functions in Haskell
Haskell’s notation to denotate a function f that takes an argument of type X
and returns a result of type Y is:
1 f :: X -> Y
Example
For example:
1 sin :: Float -> Float
2 add :: Integer -> Integer -> Integer
3 reverse :: String -> String
4 sum :: [Integer] -> Integer
Notice how Haskell’s functions declaration is extremely close to that used in
mathematics. This is not accidental, and we will see the analogy goes quite far.
7
Getting Started with Haskell
The best way to get started with Haskell is to unstall stack from
https://docs.haskellstack.org/en/stable/README/.
Once installed you can start Haskell’s REPL and experiment a bit:
1 > stack repl
2 Prelude> let xs = [1..10]
3 Prelude> :t xs
4 xs :: (Num t, Enum t) => [t]
5 Prelude> :t sum
6 sum :: (Num a, Foldable t) => t a -> a
7 Prelude> sum xs
8 55
9 Prelude> :t foldl
10 foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
11 Prelude> foldl (+) 0 xs
12 55
13 Prelude> foldl (*) 1 xs
14 3628800
8
Functions in Scala
Functions in Scala
Scala’s notation to denotate a function f that takes an argument of type X and
returns a result of type Y is:
1 def f(x: X): Y
Example
For example:
1 def sin(x: Float): Float
2 def add(a: Integer, b: Integer): Integer
3 def reverse(s: String): String
4 def sum(xs: Array[Integer]): Integer
Notice how Haskell’s functions declaration is extremely close to that used in
mathematics. This is not accidental, and we will see the analogy goes quite far.
9
Functions are Objects
In Scala function a function:
def f (t1 : T1, t2 : T2, ..., tn : Tn) : R
is are represented at runtime as objects whose type is:
trait Fun[−T1, −T2, ..., −Tn, +R] extends AnyRef
10
Local Functions
Some times, it is useful to define named functions that don’t pollute the global
namespace but instead are available only within a given function scope.
Scala makes this possible by defining local functions, in other terms, functions
that are defined inside another function.
1 def outer(x: X): Y = {
2 def inner(a: A): B = {
3 // function body
4 }
5 // ...
6 val b = inner(a)
7 // ...
8 }
11
Exploring Inner Functions and
Tail Recursion
Factorial Exercise
Last lecture I had asked you to look into finding a tail recursive definition of the
factorial. Let’s see how to get there and how inner function can help out.
Anybody wants to show his/her solution?
12
Factorial Definition
The mathematical definition of factorial is as follows:
factorial(n) =



1 if n is 0
n ∗ factoriak(n − 1) otherwise
13
Factorial Definition in Scala – Take 1
If you’d tried to write the factorial, you probably ended up writing something like
this:
1 def factorial(n: Int): Int = if (n == 0) 1 else n * factorial(n-1)
Please notice that for clarity sake I am not asserting n >= 0. This should be
checked for production code.
14
Factorial Definition in Scala – Take 2
If you’d tried to write the factorial, you probably ended up writing something like
this:
1 def factorial(n: Int): Int = n match {
2 case 0 => 1
3 case _ if n > 0 => n*factorial(n-1)
4 }
This version looks a bit more like the mathematical definition, which is nice.
15
Functions in Haskell
Factorial Definition in Haskell – Take 1
If you’d tried to write the factorial, you probably ended up writing something like
this:
1 factorial :: Integer -> Integer
2 factorial 0 = 1
3 factorial n = n * (factorial n-1)
This version looks a bit more like the mathematical definition, which is nice.
16
Factorial Definition in Haskell – Take 2
If you’d tried to write the factorial, you probably ended up writing something like
this:
1 factorial :: Integer -> Integer
2 factorial n = case n of
3 0 -> 1
4 _ -> n* (factorial (n-1))
This version looks a bit more like the mathematical definition, which is nice.
17
Evaluating the Factorial
Below is the equational substitution for factorial 3 as well as its evaluation
stack.
factorial 3 = 3∗(factorial 2) = 3∗2∗(factorial 1) =
3 ∗ 2 ∗ 1 ∗ (factorial 0) = 3 ∗ 2 ∗ 1 ∗ 1 = 6
...
1
1*(factorial 0)
2*(factorial 1)
3*(factorial 2)
factorial 3
...
18
Tail Recursion
The implementations of the factorial we have seen thus far take a linear number
of stack frames to evaluate.
This is not desirable. A recursive functions that does not evaluate with a bound
the stack size may fail at run-time because of stack overflows.
For efficiency and run-time robustness, whenever possible, is is best to write
recursive functions so that they are tail recursive.
Definition
Tail-recursive functions are functions in which all recursive calls are tail calls and
hence do not build up any deferred operations.
19
Tail Recursive Factorial
1 def factorial(n: Int): Int = {
2 @tailrec
3 def afact(a: Int, n: Int): Int =
4 if (n == 0) a else afact(a * n, n - 1)
5
6 afact(1, n)
7 }
As you can see from the fragment above we are carrying state along calls through
an accumulator. This is a technique used often to transform a function into tail
recursive.
The @tailrec annotation is used to tell the Scala compiler that this call is
supposed to be tail-recursive. If this is not the case, the compiler will raise a
warning.
20
First Class Functions
First-Class Functions
Scala has first-class functions. Beside being able to define named functions, it is
possible to write functions as unnamed literals and to pass them as values.
Example
1 val iadd = (a: Int, b: Int) => a + b
2 val isub = (a: Int, b: Int) => a - b
3
4 val i = iadd(1,2)
5
6 val ibinOp = (op: (Int, Int) => Int, a: Int, b:Int) => op(a,b)
7
8 ibinOp(iadd, 1, 2)
9 ibinOp(isub, 1, 2)
21
Currying
Do we need multiple-arguments functions?
Those with an imperative programming background are lend to think that a
function in general can have n-arguments.
Thus they think of a generic function as: def fun(a : A, b : B, c : C, ...) : X
But is this really needed? Is this the right abstraction?
22
Currying
Definition
Let f : X → Y denote a function f from X to Y . The notation X → Y then
denotes all functions from X to Y . Here X and Y may be sets, types or other
kind of mathematical objects.
Given a function f : (X × Y ) → Z, where X × Y denotes the Cartesian products
of X and Y , currying constructs, or makes a new function,
curr(f ) : X → (Y → Z).
That is, curry(f ) takes an argument of type X and returns a function of type
Y → Z. uncurrying is the opposite transformation.
23
Looking again at Haskell’s function declaration
Let’s look again at the add function defined earlier:
1 add :: Integer -> Integer -> Integer
This function can be re-written as follows, to make more explicit the currying:
1 add :: Integer -> (Integer -> Integer)
In other terms, Haskell functions are single-parameters functions.
Technically, the add function above takes an Integer parameter and returns a
function that Integer and returns and Integer. The function add can be
applied as follows:
1 Prelude> add 1 2
2 3
3 Prelude> (add 1) 2
4 3
24
Looking again at Haskell’s function declaration – cont.
Also notice that the function:
1 add :: (Integer, Integer) -> Integer
Is a single parameter functions that takes a tuple of two Integer and returns an
Integer.
The function add can be applied as follows:
1 Prelude> add (1, 2)
2 3
25
Haskell’s function declarations – again
In general a Haskell function has the following form:
f :: A → B → C → ... → Z
When seeing this declaration, you should think as if it was parenthesized as
follows:
f :: A → (B → (C → ...(Y → Z)
Also notice that:
f :: (A → B)− > C
Is a function that takes single parameter of type A → B (a function from A in B)
and returns a C
26
Currying in Scala
Scala provides support for curryed functions, but these have to be explicitly
declared as such.
In general, given a function of n arguments:
1 def fun(a: A, b: B, c: C, ...) : X
The curryed function is delcared as follows:
1 def fun(a: A)(b: B)(c: C) ... : X
Thus, in Scala, differently from Haskell, you have to decide at declaration time if
a function is curryed or not.
The syntax is a bit cluttered when compared to Haskell, but the semantics is the
same.
27
Be Patient...
Now you may starting thinking that functional programmers are eccentric, or
even a bit insane... But be patient and in a few slides you’ll find out the power
and elegance of curryed functions.
28
Partial Application
Definition
Given a function:
f :: T1 → T2 → T3 → ...Tn → T
If we apply this function to arguments:
e1 :: T1, e2 :: T2, ..., ek :: Tk, (k < n)
the result type is given by canceling the k types T1 to Tk, which give the type:
g :: Tk + 1 → Tk + 2... → Tn → T
The resulting function g is obtained by partially applying k < n arguments to f .
29
Partial Application in Haskell
Partial application in Haskell extremely straightforward, you just have to provide
(k < n) parameters to the function application.
Example
1 iadd :: Integer -> Integer -> Integer
2 iadd a b = a + b
3 iadd 1 2
4 3
5 iinc = iadd 1
6 :t iinc
7 iinc :: Num a => a -> a
8 iinc 10
9 11
30
Partial Application in Haskell
Example
1 ibinOp :: (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
2 ibinOp op a b = op a b
3
4 isum = ibinOp iadd
5 imul = ibinOp (*)
6 inc = ibinOp (+) 1
7 double = imul 2
31
Partial Application in Scala
Partial application in Scala quite similar to Haskell, with the difference that you
have to add a placeholder to indicate the fact that other parameters are missing.
Thus given a curryed function: deffun(t1 : T1)(t2 : T2)(t3 : T3)...(tn : Tn) : T
The partial application of the first k < n parameters is done as follows:
fun(t1)(t2)(t3)...(tk)T
This evaluates to a function with the following signature:
defafun(tk + 1 : Tk + 1)(tk + 2 : Tk + 2)...(tn : Tn) : T
32
Partial Application in Scala: Example
Example
1 def cadd(a: Int)(b:Int): Int = a + b
2 cadd(1)(2)
3
4 def csub(a: Int)(b:Int): Int = a - b
5 val cinc = cadd(1)_
6 cinc (10)
7
8 val ibinOp = (op: (Int, Int) => Int, a: Int, b:Int) => op(a,b)
9
10 ibinOp(cadd, 1, 2)
11 ibinOp(isub, 1, 2)
12
13
14 def cbinOp(op: (Int, Int) => Int)(a: Int)(b:Int) = op(a,b)
15
16 val inc = cbinOp (iadd) (1) _
17
18 inc(1)
33
Reflections on Partial Applications and Currying
Currying is instrumental for Partial Application, but it also has other uses in
Scala to introduce high level abstractions, such as new control flow that seem as
if they were built-in the language.
Partial application is extremely useful in library design and in higher-order
programming. You can use partially-applied higher-order functions to easily
customize behaviour of your code and of libraries.
34
looping in Scala
Let’s assume that we wanted to add a loop construct to scala.
Recall that Scala’s for construct should not be used for looping since as we will
see, it translates to map and flatmap and can be quite expensive as an iterative
construct.
Let’s use what we’ve learned thus far to implement a looping construct.
We would wont the looping construct to look like this:
1 loop (3) { println("Looping...") }
This should produce:
1 Looping...
2 Looping...
3 Looping...
35
looping in Scala
The loop function should be defined as the following curried function:
1 @tailrec
2 def loop(n: Int)(body: => Unit): Unit = {
3 if (n > 0) {
4 body
5 loop(n-1)(body)
6 }
7 }
36
Lambda and Closures
Lambdas
Definition
A lambda function is an anonymous function, in other terms a function
definition that is not bound to an identifier.
Example
1 val timesTwo = (a: Int) => 2*a
37
Closure
Definition
A closure is an anonymous function, in other terms a function definition that is
not bound to an identifier, which captures free variables from the environment.
Example
1 val x = 10
2 val plusX = (a: Int) => a + x
Notice that a as a closure resolves free variables from the environment, is a good
state to carry around context.
38
Lists
Working with Lists
List are one of the canonical functional data structures.
Let’s explore Scala’s List (see https://www.scala-lang.org/api/current/
scala/collection/immutable/List.html) and let’s see how higher order
programming makes list processing extremely elegant.
39
Computing on Lists with Pattern Matching
1 val xs = List(1,2,3,4)
2
3 def sum(xs: List[Int]): Int = xs match {
4 case y::ys => y+sum(ys)
5 case List() => 0
6 }
7
8 def mul(xs: List[Int]): Int = xs match {
9 case y::ys => y*mul(ys)
10 case List() => 1
11 }
12
13 def reverse(xs: List[Int]): List[Int] = xs match {
14 case List() => List()
15 case y::ys => reverse(ys) ::: List(y)
16 }
40
Folding Lists
The functions we just wrote for lists can all be expressed in terms of fold
operator.
1 def sum(xs: List[Int]): Int = xs.foldRight(0)(_ + _)
2
3 def sum(xs: List[Int]): Int = xs.foldLeft(0)(_ + _)
4
5 def reversel(ys: List[Int])= ys.foldLeft(List[Int]())((xs: List[Int], x: Int) => x :: xs)
6
7 def reverser(ys: List[Int]) = zs.foldRight(List[Int]())((x: Int, xs: List[Int]) => xs ::: List(x) )
41
Homeworks
Reading
From the Programming in Scala book you should read:
• Chapter 8
• Chapter 9
• Chapter 16
42

Contenu connexe

Tendances

Python Programming - VII. Customizing Classes and Operator Overloading
Python Programming - VII. Customizing Classes and Operator OverloadingPython Programming - VII. Customizing Classes and Operator Overloading
Python Programming - VII. Customizing Classes and Operator Overloading
Ranel Padon
 
Python Programming - IX. On Randomness
Python Programming - IX. On RandomnessPython Programming - IX. On Randomness
Python Programming - IX. On Randomness
Ranel Padon
 

Tendances (20)

Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
 
Python Programming - II. The Basics
Python Programming - II. The BasicsPython Programming - II. The Basics
Python Programming - II. The Basics
 
Functional programming
Functional programmingFunctional programming
Functional programming
 
Pattern Matching - at a glance
Pattern Matching - at a glancePattern Matching - at a glance
Pattern Matching - at a glance
 
Python Programming - VII. Customizing Classes and Operator Overloading
Python Programming - VII. Customizing Classes and Operator OverloadingPython Programming - VII. Customizing Classes and Operator Overloading
Python Programming - VII. Customizing Classes and Operator Overloading
 
Python Programming - IX. On Randomness
Python Programming - IX. On RandomnessPython Programming - IX. On Randomness
Python Programming - IX. On Randomness
 
Tokens expressionsin C++
Tokens expressionsin C++Tokens expressionsin C++
Tokens expressionsin C++
 
Getting Started With Scala
Getting Started With ScalaGetting Started With Scala
Getting Started With Scala
 
Programming in Scala: Notes
Programming in Scala: NotesProgramming in Scala: Notes
Programming in Scala: Notes
 
Functional object
Functional objectFunctional object
Functional object
 
Introduction to programming in scala
Introduction to programming in scalaIntroduction to programming in scala
Introduction to programming in scala
 
Introduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScriptIntroduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScript
 
Scala: functional programming for the imperative mind
Scala: functional programming for the imperative mindScala: functional programming for the imperative mind
Scala: functional programming for the imperative mind
 
Chapter 2.datatypes and operators
Chapter 2.datatypes and operatorsChapter 2.datatypes and operators
Chapter 2.datatypes and operators
 
Knolx session
Knolx sessionKnolx session
Knolx session
 
LISP: Data types in lisp
LISP: Data types in lispLISP: Data types in lisp
LISP: Data types in lisp
 
LISP: Input And Output
LISP: Input And OutputLISP: Input And Output
LISP: Input And Output
 
Getting started with c++
Getting started with c++Getting started with c++
Getting started with c++
 
Templates
TemplatesTemplates
Templates
 
Linq Introduction
Linq IntroductionLinq Introduction
Linq Introduction
 

Similaire à Programming in Scala - Lecture Two

Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
pramode_ce
 
Real World Haskell: Lecture 6
Real World Haskell: Lecture 6Real World Haskell: Lecture 6
Real World Haskell: Lecture 6
Bryan O'Sullivan
 
High-Performance Haskell
High-Performance HaskellHigh-Performance Haskell
High-Performance Haskell
Johan Tibell
 

Similaire à Programming in Scala - Lecture Two (20)

Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
 
Functional programming using haskell notes iitk
Functional programming using haskell notes iitkFunctional programming using haskell notes iitk
Functional programming using haskell notes iitk
 
Lecture 3
Lecture 3Lecture 3
Lecture 3
 
Functional Programming Concepts for Imperative Programmers
Functional Programming Concepts for Imperative ProgrammersFunctional Programming Concepts for Imperative Programmers
Functional Programming Concepts for Imperative Programmers
 
Real World Haskell: Lecture 6
Real World Haskell: Lecture 6Real World Haskell: Lecture 6
Real World Haskell: Lecture 6
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with Scala
 
Inroduction to r
Inroduction to rInroduction to r
Inroduction to r
 
Scala google
Scala google Scala google
Scala google
 
Functional Programming in JavaScript
Functional Programming in JavaScriptFunctional Programming in JavaScript
Functional Programming in JavaScript
 
Scala qq
Scala qqScala qq
Scala qq
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala Part 2 ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala Part 2 ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala Part 2 ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala Part 2 ...
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 2
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 2Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 2
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part 2
 
High-Performance Haskell
High-Performance HaskellHigh-Performance Haskell
High-Performance Haskell
 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scala
 
Functions & Closures in Scala
Functions & Closures in ScalaFunctions & Closures in Scala
Functions & Closures in Scala
 
Functions & Closures in Scala
Functions & Closures in ScalaFunctions & Closures in Scala
Functions & Closures in Scala
 
Functions & closures
Functions & closuresFunctions & closures
Functions & closures
 
Functional Programming - Past, Present and Future
Functional Programming - Past, Present and FutureFunctional Programming - Past, Present and Future
Functional Programming - Past, Present and Future
 
Functional Programming Past Present Future
Functional Programming Past Present FutureFunctional Programming Past Present Future
Functional Programming Past Present Future
 
Advance python programming
Advance python programming Advance python programming
Advance python programming
 

Plus de Angelo Corsaro

Plus de Angelo Corsaro (20)

Zenoh: The Genesis
Zenoh: The GenesisZenoh: The Genesis
Zenoh: The Genesis
 
zenoh: The Edge Data Fabric
zenoh: The Edge Data Fabriczenoh: The Edge Data Fabric
zenoh: The Edge Data Fabric
 
Zenoh Tutorial
Zenoh TutorialZenoh Tutorial
Zenoh Tutorial
 
Data Decentralisation: Efficiency, Privacy and Fair Monetisation
Data Decentralisation: Efficiency, Privacy and Fair MonetisationData Decentralisation: Efficiency, Privacy and Fair Monetisation
Data Decentralisation: Efficiency, Privacy and Fair Monetisation
 
zenoh: zero overhead pub/sub store/query compute
zenoh: zero overhead pub/sub store/query computezenoh: zero overhead pub/sub store/query compute
zenoh: zero overhead pub/sub store/query compute
 
zenoh -- the ZEro Network OverHead protocol
zenoh -- the ZEro Network OverHead protocolzenoh -- the ZEro Network OverHead protocol
zenoh -- the ZEro Network OverHead protocol
 
zenoh -- the ZEro Network OverHead protocol
zenoh -- the ZEro Network OverHead protocolzenoh -- the ZEro Network OverHead protocol
zenoh -- the ZEro Network OverHead protocol
 
Breaking the Edge -- A Journey Through Cloud, Edge and Fog Computing
Breaking the Edge -- A Journey Through Cloud, Edge and Fog ComputingBreaking the Edge -- A Journey Through Cloud, Edge and Fog Computing
Breaking the Edge -- A Journey Through Cloud, Edge and Fog Computing
 
Eastern Sicily
Eastern SicilyEastern Sicily
Eastern Sicily
 
fog05: The Fog Computing Infrastructure
fog05: The Fog Computing Infrastructurefog05: The Fog Computing Infrastructure
fog05: The Fog Computing Infrastructure
 
Cyclone DDS: Sharing Data in the IoT Age
Cyclone DDS: Sharing Data in the IoT AgeCyclone DDS: Sharing Data in the IoT Age
Cyclone DDS: Sharing Data in the IoT Age
 
fog05: The Fog Computing Platform
fog05: The Fog Computing Platformfog05: The Fog Computing Platform
fog05: The Fog Computing Platform
 
Data Sharing in Extremely Resource Constrained Envionrments
Data Sharing in Extremely Resource Constrained EnvionrmentsData Sharing in Extremely Resource Constrained Envionrments
Data Sharing in Extremely Resource Constrained Envionrments
 
The DDS Security Standard
The DDS Security StandardThe DDS Security Standard
The DDS Security Standard
 
The Data Distribution Service
The Data Distribution ServiceThe Data Distribution Service
The Data Distribution Service
 
RUSTing -- Partially Ordered Rust Programming Ruminations
RUSTing -- Partially Ordered Rust Programming RuminationsRUSTing -- Partially Ordered Rust Programming Ruminations
RUSTing -- Partially Ordered Rust Programming Ruminations
 
Vortex II -- The Industrial IoT Connectivity Standard
Vortex II -- The  Industrial IoT  Connectivity StandardVortex II -- The  Industrial IoT  Connectivity Standard
Vortex II -- The Industrial IoT Connectivity Standard
 
Fog Computing Defined
Fog Computing DefinedFog Computing Defined
Fog Computing Defined
 
DDS In Action Part II
DDS In Action Part IIDDS In Action Part II
DDS In Action Part II
 
DDS in Action -- Part I
DDS in Action -- Part IDDS in Action -- Part I
DDS in Action -- Part I
 

Dernier

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Dernier (20)

The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 

Programming in Scala - Lecture Two

  • 1. Programming in Scala Lecture Two Angelo Corsaro 5 December 2017 Chief Technology Officer, ADLINK Technology Inc.
  • 2. Table of contents i 1. Functional Programming Recap 2. Haskell Quick Start 3. Functions in Haskell 4. Functions in Scala 5. Exploring Inner Functions and Tail Recursion 6. Functions in Haskell 1
  • 3. Table of contents ii 7. First Class Functions 8. Currying 9. Lambda and Closures 10. Lists 11. Homeworks 2
  • 5. Functional Programming Functional Programming is a method of program construction that: • Emphasises functions and their applications as opposed to commands and their execution. • Uses simple mathematical notation that allows problems to be described clearly and concisely. • Has a simple mathematical bases that supports equational reasoning about the properties of a program. A functional programming languages is guided by two main ideas, functions as first-class values and no side-effects. 3
  • 6. Functions as First-Class Values In a functional programming language: • A function is a value as an Integer or a String. • Functions can be passed as arguments, returned as values as well as stored into variables. • Functions can be named or anonymous and can be defined inside other functions. 4
  • 7. No Side-Effects • In a functional programming language, the result of applying some arguments to a functions should only depend on the input. In other terms, applying the same input to a given function always gives the same output. • Functions that satisfy this property are know to be referentially transparent. • Functional programming languages ecnourage the use of immutable data structures and referentually transparent functions. Note: it is worth comparing the functional approach with the imperative style programming were everything is based on mutable data and side-effects. 5
  • 9. The Haskell Programming Language Haskell is a pure, lazy, functional programming language first defined in 1990. The programming language was named after Haskell B. Curry, who was one of the pioneers of λ-calculus, a mathematical theory of functions that has been an inspiration to designers of a number of functional programming languages. The latest version of the language is Haskell-2010 and a working group was established in 2016 to define Haskell-2020. The Haskell’s home is http://www.haskell.org 6
  • 11. Functions in Haskell Haskell’s notation to denotate a function f that takes an argument of type X and returns a result of type Y is: 1 f :: X -> Y Example For example: 1 sin :: Float -> Float 2 add :: Integer -> Integer -> Integer 3 reverse :: String -> String 4 sum :: [Integer] -> Integer Notice how Haskell’s functions declaration is extremely close to that used in mathematics. This is not accidental, and we will see the analogy goes quite far. 7
  • 12. Getting Started with Haskell The best way to get started with Haskell is to unstall stack from https://docs.haskellstack.org/en/stable/README/. Once installed you can start Haskell’s REPL and experiment a bit: 1 > stack repl 2 Prelude> let xs = [1..10] 3 Prelude> :t xs 4 xs :: (Num t, Enum t) => [t] 5 Prelude> :t sum 6 sum :: (Num a, Foldable t) => t a -> a 7 Prelude> sum xs 8 55 9 Prelude> :t foldl 10 foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b 11 Prelude> foldl (+) 0 xs 12 55 13 Prelude> foldl (*) 1 xs 14 3628800 8
  • 14. Functions in Scala Scala’s notation to denotate a function f that takes an argument of type X and returns a result of type Y is: 1 def f(x: X): Y Example For example: 1 def sin(x: Float): Float 2 def add(a: Integer, b: Integer): Integer 3 def reverse(s: String): String 4 def sum(xs: Array[Integer]): Integer Notice how Haskell’s functions declaration is extremely close to that used in mathematics. This is not accidental, and we will see the analogy goes quite far. 9
  • 15. Functions are Objects In Scala function a function: def f (t1 : T1, t2 : T2, ..., tn : Tn) : R is are represented at runtime as objects whose type is: trait Fun[−T1, −T2, ..., −Tn, +R] extends AnyRef 10
  • 16. Local Functions Some times, it is useful to define named functions that don’t pollute the global namespace but instead are available only within a given function scope. Scala makes this possible by defining local functions, in other terms, functions that are defined inside another function. 1 def outer(x: X): Y = { 2 def inner(a: A): B = { 3 // function body 4 } 5 // ... 6 val b = inner(a) 7 // ... 8 } 11
  • 17. Exploring Inner Functions and Tail Recursion
  • 18. Factorial Exercise Last lecture I had asked you to look into finding a tail recursive definition of the factorial. Let’s see how to get there and how inner function can help out. Anybody wants to show his/her solution? 12
  • 19. Factorial Definition The mathematical definition of factorial is as follows: factorial(n) =    1 if n is 0 n ∗ factoriak(n − 1) otherwise 13
  • 20. Factorial Definition in Scala – Take 1 If you’d tried to write the factorial, you probably ended up writing something like this: 1 def factorial(n: Int): Int = if (n == 0) 1 else n * factorial(n-1) Please notice that for clarity sake I am not asserting n >= 0. This should be checked for production code. 14
  • 21. Factorial Definition in Scala – Take 2 If you’d tried to write the factorial, you probably ended up writing something like this: 1 def factorial(n: Int): Int = n match { 2 case 0 => 1 3 case _ if n > 0 => n*factorial(n-1) 4 } This version looks a bit more like the mathematical definition, which is nice. 15
  • 23. Factorial Definition in Haskell – Take 1 If you’d tried to write the factorial, you probably ended up writing something like this: 1 factorial :: Integer -> Integer 2 factorial 0 = 1 3 factorial n = n * (factorial n-1) This version looks a bit more like the mathematical definition, which is nice. 16
  • 24. Factorial Definition in Haskell – Take 2 If you’d tried to write the factorial, you probably ended up writing something like this: 1 factorial :: Integer -> Integer 2 factorial n = case n of 3 0 -> 1 4 _ -> n* (factorial (n-1)) This version looks a bit more like the mathematical definition, which is nice. 17
  • 25. Evaluating the Factorial Below is the equational substitution for factorial 3 as well as its evaluation stack. factorial 3 = 3∗(factorial 2) = 3∗2∗(factorial 1) = 3 ∗ 2 ∗ 1 ∗ (factorial 0) = 3 ∗ 2 ∗ 1 ∗ 1 = 6 ... 1 1*(factorial 0) 2*(factorial 1) 3*(factorial 2) factorial 3 ... 18
  • 26. Tail Recursion The implementations of the factorial we have seen thus far take a linear number of stack frames to evaluate. This is not desirable. A recursive functions that does not evaluate with a bound the stack size may fail at run-time because of stack overflows. For efficiency and run-time robustness, whenever possible, is is best to write recursive functions so that they are tail recursive. Definition Tail-recursive functions are functions in which all recursive calls are tail calls and hence do not build up any deferred operations. 19
  • 27. Tail Recursive Factorial 1 def factorial(n: Int): Int = { 2 @tailrec 3 def afact(a: Int, n: Int): Int = 4 if (n == 0) a else afact(a * n, n - 1) 5 6 afact(1, n) 7 } As you can see from the fragment above we are carrying state along calls through an accumulator. This is a technique used often to transform a function into tail recursive. The @tailrec annotation is used to tell the Scala compiler that this call is supposed to be tail-recursive. If this is not the case, the compiler will raise a warning. 20
  • 29. First-Class Functions Scala has first-class functions. Beside being able to define named functions, it is possible to write functions as unnamed literals and to pass them as values. Example 1 val iadd = (a: Int, b: Int) => a + b 2 val isub = (a: Int, b: Int) => a - b 3 4 val i = iadd(1,2) 5 6 val ibinOp = (op: (Int, Int) => Int, a: Int, b:Int) => op(a,b) 7 8 ibinOp(iadd, 1, 2) 9 ibinOp(isub, 1, 2) 21
  • 31. Do we need multiple-arguments functions? Those with an imperative programming background are lend to think that a function in general can have n-arguments. Thus they think of a generic function as: def fun(a : A, b : B, c : C, ...) : X But is this really needed? Is this the right abstraction? 22
  • 32. Currying Definition Let f : X → Y denote a function f from X to Y . The notation X → Y then denotes all functions from X to Y . Here X and Y may be sets, types or other kind of mathematical objects. Given a function f : (X × Y ) → Z, where X × Y denotes the Cartesian products of X and Y , currying constructs, or makes a new function, curr(f ) : X → (Y → Z). That is, curry(f ) takes an argument of type X and returns a function of type Y → Z. uncurrying is the opposite transformation. 23
  • 33. Looking again at Haskell’s function declaration Let’s look again at the add function defined earlier: 1 add :: Integer -> Integer -> Integer This function can be re-written as follows, to make more explicit the currying: 1 add :: Integer -> (Integer -> Integer) In other terms, Haskell functions are single-parameters functions. Technically, the add function above takes an Integer parameter and returns a function that Integer and returns and Integer. The function add can be applied as follows: 1 Prelude> add 1 2 2 3 3 Prelude> (add 1) 2 4 3 24
  • 34. Looking again at Haskell’s function declaration – cont. Also notice that the function: 1 add :: (Integer, Integer) -> Integer Is a single parameter functions that takes a tuple of two Integer and returns an Integer. The function add can be applied as follows: 1 Prelude> add (1, 2) 2 3 25
  • 35. Haskell’s function declarations – again In general a Haskell function has the following form: f :: A → B → C → ... → Z When seeing this declaration, you should think as if it was parenthesized as follows: f :: A → (B → (C → ...(Y → Z) Also notice that: f :: (A → B)− > C Is a function that takes single parameter of type A → B (a function from A in B) and returns a C 26
  • 36. Currying in Scala Scala provides support for curryed functions, but these have to be explicitly declared as such. In general, given a function of n arguments: 1 def fun(a: A, b: B, c: C, ...) : X The curryed function is delcared as follows: 1 def fun(a: A)(b: B)(c: C) ... : X Thus, in Scala, differently from Haskell, you have to decide at declaration time if a function is curryed or not. The syntax is a bit cluttered when compared to Haskell, but the semantics is the same. 27
  • 37. Be Patient... Now you may starting thinking that functional programmers are eccentric, or even a bit insane... But be patient and in a few slides you’ll find out the power and elegance of curryed functions. 28
  • 38. Partial Application Definition Given a function: f :: T1 → T2 → T3 → ...Tn → T If we apply this function to arguments: e1 :: T1, e2 :: T2, ..., ek :: Tk, (k < n) the result type is given by canceling the k types T1 to Tk, which give the type: g :: Tk + 1 → Tk + 2... → Tn → T The resulting function g is obtained by partially applying k < n arguments to f . 29
  • 39. Partial Application in Haskell Partial application in Haskell extremely straightforward, you just have to provide (k < n) parameters to the function application. Example 1 iadd :: Integer -> Integer -> Integer 2 iadd a b = a + b 3 iadd 1 2 4 3 5 iinc = iadd 1 6 :t iinc 7 iinc :: Num a => a -> a 8 iinc 10 9 11 30
  • 40. Partial Application in Haskell Example 1 ibinOp :: (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer 2 ibinOp op a b = op a b 3 4 isum = ibinOp iadd 5 imul = ibinOp (*) 6 inc = ibinOp (+) 1 7 double = imul 2 31
  • 41. Partial Application in Scala Partial application in Scala quite similar to Haskell, with the difference that you have to add a placeholder to indicate the fact that other parameters are missing. Thus given a curryed function: deffun(t1 : T1)(t2 : T2)(t3 : T3)...(tn : Tn) : T The partial application of the first k < n parameters is done as follows: fun(t1)(t2)(t3)...(tk)T This evaluates to a function with the following signature: defafun(tk + 1 : Tk + 1)(tk + 2 : Tk + 2)...(tn : Tn) : T 32
  • 42. Partial Application in Scala: Example Example 1 def cadd(a: Int)(b:Int): Int = a + b 2 cadd(1)(2) 3 4 def csub(a: Int)(b:Int): Int = a - b 5 val cinc = cadd(1)_ 6 cinc (10) 7 8 val ibinOp = (op: (Int, Int) => Int, a: Int, b:Int) => op(a,b) 9 10 ibinOp(cadd, 1, 2) 11 ibinOp(isub, 1, 2) 12 13 14 def cbinOp(op: (Int, Int) => Int)(a: Int)(b:Int) = op(a,b) 15 16 val inc = cbinOp (iadd) (1) _ 17 18 inc(1) 33
  • 43. Reflections on Partial Applications and Currying Currying is instrumental for Partial Application, but it also has other uses in Scala to introduce high level abstractions, such as new control flow that seem as if they were built-in the language. Partial application is extremely useful in library design and in higher-order programming. You can use partially-applied higher-order functions to easily customize behaviour of your code and of libraries. 34
  • 44. looping in Scala Let’s assume that we wanted to add a loop construct to scala. Recall that Scala’s for construct should not be used for looping since as we will see, it translates to map and flatmap and can be quite expensive as an iterative construct. Let’s use what we’ve learned thus far to implement a looping construct. We would wont the looping construct to look like this: 1 loop (3) { println("Looping...") } This should produce: 1 Looping... 2 Looping... 3 Looping... 35
  • 45. looping in Scala The loop function should be defined as the following curried function: 1 @tailrec 2 def loop(n: Int)(body: => Unit): Unit = { 3 if (n > 0) { 4 body 5 loop(n-1)(body) 6 } 7 } 36
  • 47. Lambdas Definition A lambda function is an anonymous function, in other terms a function definition that is not bound to an identifier. Example 1 val timesTwo = (a: Int) => 2*a 37
  • 48. Closure Definition A closure is an anonymous function, in other terms a function definition that is not bound to an identifier, which captures free variables from the environment. Example 1 val x = 10 2 val plusX = (a: Int) => a + x Notice that a as a closure resolves free variables from the environment, is a good state to carry around context. 38
  • 49. Lists
  • 50. Working with Lists List are one of the canonical functional data structures. Let’s explore Scala’s List (see https://www.scala-lang.org/api/current/ scala/collection/immutable/List.html) and let’s see how higher order programming makes list processing extremely elegant. 39
  • 51. Computing on Lists with Pattern Matching 1 val xs = List(1,2,3,4) 2 3 def sum(xs: List[Int]): Int = xs match { 4 case y::ys => y+sum(ys) 5 case List() => 0 6 } 7 8 def mul(xs: List[Int]): Int = xs match { 9 case y::ys => y*mul(ys) 10 case List() => 1 11 } 12 13 def reverse(xs: List[Int]): List[Int] = xs match { 14 case List() => List() 15 case y::ys => reverse(ys) ::: List(y) 16 } 40
  • 52. Folding Lists The functions we just wrote for lists can all be expressed in terms of fold operator. 1 def sum(xs: List[Int]): Int = xs.foldRight(0)(_ + _) 2 3 def sum(xs: List[Int]): Int = xs.foldLeft(0)(_ + _) 4 5 def reversel(ys: List[Int])= ys.foldLeft(List[Int]())((xs: List[Int], x: Int) => x :: xs) 6 7 def reverser(ys: List[Int]) = zs.foldRight(List[Int]())((x: Int, xs: List[Int]) => xs ::: List(x) ) 41
  • 54. Reading From the Programming in Scala book you should read: • Chapter 8 • Chapter 9 • Chapter 16 42