02 functionalprogramming done
TRANSCRIPT
-
7/27/2019 02 FunctionalProgramming Done
1/42
1
Functional Programming
with Scala
Cay Horstman & Nguyen Hua Phung
2012
-
7/27/2019 02 FunctionalProgramming Done
2/42
Scala PhD.Nguyen Hua Phung 2
Outline
Functional Programming
Scala Basics
Control and data structures Higher order functions and closures
-
7/27/2019 02 FunctionalProgramming Done
3/42
Scala PhD.Nguyen Hua Phung 3
Functional Programming
Functional programming: Functions are values In C++, values are
Primitive types int, double, etc. Structure/class values Pointers
A function is not a first class value in C++ Cannot create new functions in a running program
In a functional programming language, functions arefirst-class values Can have variables that hold functions Can create new functions
-
7/27/2019 02 FunctionalProgramming Done
4/42
Scala PhD.Nguyen Hua Phung 4
Introduction
The design of the imperative languages is based
directly on the von Neumann architecture Efficiency is the primary concern, rather than the suitability
of the language for software development
The design of the functional languages is based on
mathematical functions A solid theoretical basis that is also closer to the user, but
relatively unconcerned with the architecture of themachines on which programs will run
-
7/27/2019 02 FunctionalProgramming Done
5/42
Scala PhD.Nguyen Hua Phung 5
Mathematical Functions
A mathematical function is a mapping of members of one set, called the domain set,
to another set, called the range set
A lambda expression specifies the parameter(s) and
the mapping of a function in the following form(x) x * x * xfor the function cube cube(x) = x * x * x
Lambda expressions describe nameless functions
Lambda expressions are applied to parameter(s) byplacing the parameter(s) after the expression
((x) x * x * x)(2) which evaluates to 8
-
7/27/2019 02 FunctionalProgramming Done
6/42
Scala PhD.Nguyen Hua Phung 6
Higher-order Function
A higher-order function is one that eithertakes functions as parameters or yields afunction as its result, or both
For example, Function composition
Apply-to-all
Insert-left | Insert-right
-
7/27/2019 02 FunctionalProgramming Done
7/42
Scala PhD.Nguyen Hua Phung 7
Function Composition
A function that takes two functions as parameters and
yields a function whose value is the firstactual parameter function applied to theapplication of the second
f g : x = f : (g : x)Forf (x) = x + 2, g (x) = 3 * x => f g : x = (3 * x)+ 2
Example in Scala:def f(x:Double) = x + 2def g(x:Double) = x * 3def h(x:Double) = f(g(x))
-
7/27/2019 02 FunctionalProgramming Done
8/42
Scala PhD.Nguyen Hua Phung 8
Apply-to-all
A functional form that takes a single function as a parameter and
yields a list of values obtained by applying the
given function to each element of a list ofparameters
f: =
Forh (x) = x * x => h: (2, 3, 4) yields (4, 9, 16)
Example in Scala,List(2,3,4).map((x:Int) => x * x)
List(2.0,3.0,4.0).map(f)
-
7/27/2019 02 FunctionalProgramming Done
9/42
Scala PhD.Nguyen Hua Phung 9
Insert Left / Insert Right
/f:, = f: ,
\ f: , = f: ,
Example in Scala,
List(2,3,4).foldLeft(0)((a,b) => a+b) yield 9List(2,3,4).foldLeft(1)((a,b) => a*b) yield 24
List(2,3,4).foldLeft(A)((a,b) => a + b)
yield A123
List(2,3,4).foldRight(A)((a,b) => a + b)
yield 123A
-
7/27/2019 02 FunctionalProgramming Done
10/42
Scala PhD.Nguyen Hua Phung 10
Functional Programming Languages
mimic mathematical functions to the greatest extentpossible
An imperative language In an imperative language, operations are done and the results
are stored in variables for later use Management of variables is a constant concern and source of
complexity for imperative programming
In an FPL, variables are not necessary, as the case inmathematics
Referential Transparency: the evaluation of a functionalways produces the same result given the sameparameters
-
7/27/2019 02 FunctionalProgramming Done
11/42
Scala PhD.Nguyen Hua Phung 11
Functional Programming in Scala
Functions can be values
val num = 3.14val fun = math.ceil _fun(num)// prints 4
Functions can be anonymous...
(x : Int) => x * x ...just like numbers 3.14 Of course, can put function values into variables and then use
them
val square = (x : Int) => x * xsquare(10)// prints 100
...again, just like numbers
val pi = 3.14pi * 10// prints 31.4
-
7/27/2019 02 FunctionalProgramming Done
12/42
Scala PhD.Nguyen Hua Phung 12
Why Scala
Multi-paradigm language
Invented by Martin Odersky at EPFL,
Lausanne, Switzerland
Similar to Java
Work with Java tools/libraries/etc
Including lexer and parser generator
Fewer things to learn => Can get deeper
where we want to go
-
7/27/2019 02 FunctionalProgramming Done
13/42
Scala PhD.Nguyen Hua Phung 13
Why Functional Programming?
Simpler and clearer programming style Often useful to pass functions as parameters
val numbers = Vector(1, 2, 3, 4, 5)
numbers.map((x : Int) => x * x)// prints Vector(1, 4, 9, 16, 25)
In C++, you can also do this, but there are noanonymous functions
vector map(vector values, int (*f)(int) )
{ vector result;
for (int i=0;i
-
7/27/2019 02 FunctionalProgramming Done
14/42
Scala PhD.Nguyen Hua Phung 14
Scala Basics
Primitive types: Int, Double, Boolean, String
Arithmetic like in C++: + - * /
Variable type is inferred:
val luckyNumber = 13// luckyNumber is an Int
Function type:
val square = (x : Int) => x * x// square is anInt => Int
Semicolons at the end of a line are optional
-
7/27/2019 02 FunctionalProgramming Done
15/42
Scala PhD.Nguyen Hua Phung 15
Scala Basics
Everything is an object
1.to(5)// Applytomethod to 1, returnsRange(1, 2, 3, 4, 5)
Collection List(more in next lecture), Vector(similar to C++), Range
mapworks on any collection
1.to(5).map(x => x * x) // Type is inferred
-
7/27/2019 02 FunctionalProgramming Done
16/42
Scala PhD.Nguyen Hua Phung 16
Immutability
Immutable: Cannot change
In Java, strings are immutable
"Hello".toUpper() doesn't change "Hello" but returns a newstring "HELLO"
In Scala, val is immutableval num = 3.14
num = 1.42// Error Pure functional programming: No mutations
Don't mutatealways return the result as a new value Functions that don't mutate state are inherently parallelizable
-
7/27/2019 02 FunctionalProgramming Done
17/42
Scala PhD.Nguyen Hua Phung 17
If/Else
if (booleanExpression)expression1 else
expression2
if/else is an expression, not a statement. Can
be used in other expressions:
val x = (if (true) 2 else 4) * 3 Like ? : in C++
Expression 1 and expression 2 must be in the
same type
-
7/27/2019 02 FunctionalProgramming Done
18/42
Scala PhD.Nguyen Hua Phung 18
Pattern Matching
match {
case => expr1
case => expr2
def mathTest(x : Int): String = x match {
case 1 => one
case 2 => two
case _ => many
}
-
7/27/2019 02 FunctionalProgramming Done
19/42
Scala PhD.Nguyen Hua Phung 19
Recursion
def syntax for functiondef tripple (x : Int) = 3 * x
// same as val tripple (x : Int) = 3 * x With recursive functions, also need to specify return type
def fact (x : Int) : Int = if (x == 0) 1 else x * fact(x 1) Need def because the name is used on the rightval fac(x : Int) : Int = if (x == 0) 1 else x * fac(x 1)//fac not
defined yet Iteration (while, for) can always be expressed as recursion
To iterate is human; to recurse, divine (L.Peter Deutsch)
-
7/27/2019 02 FunctionalProgramming Done
20/42
Scala PhD.Nguyen Hua Phung 20
Functions as Parameters
Consider the map function:val triple = (x : Int) => 3 * x
1.to(5).map(triple) // yields List(3, 6, 9, 12, 15)
Let's implement this function. For simplicity,we only use sets and functions of Int
-
7/27/2019 02 FunctionalProgramming Done
21/42
Scala PhD.Nguyen Hua Phung 21
map function
Two parameter: List[Int] and function: (Int) => Int
Return type: List[Int]
def map (lst:List[Int],fun:(Int)=>Int): List[Int] =
Map of an empty list is Nil, otherwise, apply fun to the
head of the list and use recursionif (lst.isEmpty)
Nil else fun(lst.head)::map(lst.tail,fun)
Sample call
map(List(1,3,5),(x:Int)=>4*x) // yields List(4,12,20)
The function describes a piece of behaviour, such as,
what should map do with each element of the list
-
7/27/2019 02 FunctionalProgramming Done
22/42
Scala PhD.Nguyen Hua Phung 22
Capturing the Enclosing Environment
Consider this function:val n = 3val fun = (x:Int) => n * x // What is fun(2)? n is not defined in fun => any variable in the
enclosing environment
However, n is immutable, so it is always 3. Butconsider this
def mulBy n = (x:Int) => n * x Huh? Let's call itval quadruple = mulBy(4)// the function (x -> 4 * x)quadruple(5) // yields 20 Each call to mulBy yields a different function which
has a different value of n . Closure = function + binding of its free variables
-
7/27/2019 02 FunctionalProgramming Done
23/42
Scala PhD.Nguyen Hua Phung 23
Tuples
A pair is an example of a tuple
If S, T, U are any types, then we have tuple types
(S, T), (S, T, U)
Ex. ("Hello", 1729) is an instance of(String, Int) Use methods _1 _2 etc. to access members (not 0-
based!)
(Hello,1729)._2 is 1729
Convenient if a method returns more than one piece
of information
-
7/27/2019 02 FunctionalProgramming Done
24/42
Scala PhD.Nguyen Hua Phung 24
Lists
Very different from C++ linked lists. No iterators Three primitives: head tail :: (pronounced cons) A list is either empty (Nil) or has a head and tail
val lst = List(1, 4, 7)lst.head // 1lst.tail // List(4, 7)lst.tail.tail.tail // Nil
Use :: to build a list
0 :: lst // List(0, 1, 4, 7)
-
7/27/2019 02 FunctionalProgramming Done
25/42
Scala PhD.Nguyen Hua Phung 25
List functions
Use recursion for list functions
def sum(lst : List[Int]) : Int =
if (lst.isEmpty)
0 else // Note: ELSE must be on this linelst.head + sum(lst.tail)
Use :: to recursively build lists
def square(n : Int) : List[Int] =
if (n == 0)
List(0) else
n * n :: square( n 1 )
-
7/27/2019 02 FunctionalProgramming Done
26/42
Scala PhD.Nguyen Hua Phung 26
Type Inference
Scala is strongly typed. Any value has a type guarantee Just like C++:
char* greeting = "Hello";greeting = 42; // Error
But without having to declare types:val greeting = Hello Contrast with scripting languages such as JavaScript
var greeting = 'Hello' // This is JavaScriptgreeting = 42 // Okalert(greeting.length) // Runtime error: 42 doesn't have a length
member
-
7/27/2019 02 FunctionalProgramming Done
27/42
Scala PhD.Nguyen Hua Phung 27
Type Inference (2)
Can override inferred type (only to a supertype, of course).
var greeting : Any = Hellogreeting = 42 // Ok Parameter type must be declared
def mistery (x) = 42 * x // Errordef mistery (x : Int) = 42 * x // Ok Return type can be inferred
If x is Int, then 42 * x is also Int Exception, recursive function
def fac (x : Int) : Int =
if (x == 0) 1 else x * fac(x - 1)
-
7/27/2019 02 FunctionalProgramming Done
28/42
Scala PhD.Nguyen Hua Phung 28
Parameter Inference from Context
When a function parameter type is known, you cansupply an anonymous function without specifying its
parameter types
def twice(f: (Int)=>Int,x:Int) = f(f(x))
twice(x=>42*x, 3)// Ok, x:Int is inferred from context
Very useful when calling library functions
List(1,2,3).filter(x=> x%2==0)
List[A].filter(p:(A)=>Boolean) : List[A] A is Int since List(1,2,3) is a List[Int]
p: must be (Int) => Boolean
X must be Int
-
7/27/2019 02 FunctionalProgramming Done
29/42
Scala PhD.Nguyen Hua Phung 29
Parameter Simplification
Ok to omit () around a single inferred
parameterList(1, 2, 3).filter(x => x % 2 == 0)
List(1, 2, 3).sortWith((x,y) => x > y)// need () with 2 or more parameters
Use _ for a parameter that occurs only once
in a bodyList(1, 2, 3).filter( _ % 2 == 0)
List(1, 2, 3).sortWith( _ > _)
-
7/27/2019 02 FunctionalProgramming Done
30/42
Scala PhD.Nguyen Hua Phung 30
Control Abstraction
Methods such as map or filter have as argument a function(i.e. code)
A while loop has two arguments: condition (code), body(code)
Could we implement a while loop in Scala?def While(cond: () => Boolean,body: () => unit) {
if (cond()) { body(); While(cond,body); }}
But calling is a bit ugly:
var x = 1
While(() => x < 10,
() => {print(x);x = x + 1;})
-
7/27/2019 02 FunctionalProgramming Done
31/42
Scala PhD.Nguyen Hua Phung 31
By-name parameters
Control abstraction = User or library function that looks to
programmers like a language mechanism
Want nice syntax, eg. {} for blocks without ()=>
Use by-name parameter
def While(cond: => Boolean,body: => unit) { // Not ()
if (cond) { // Not () in calling
body; While(cond,body); }}
Now, the unsightly () => are gone from the call:While ({ x < 10},
{x+=1; println(x) })
-
7/27/2019 02 FunctionalProgramming Done
32/42
Scala PhD.Nguyen Hua Phung 32
Currying
Currying = Turning a function that takes two
arguments into a function that takes one argument.
That function returns a function that consumes the
second argument. (Named after the logician Haskell
Brooks Curry)
def mul (x : Int, y : Int) = x * y
mul(2, 3) is 6
def mul2 (x : Int) (y : Int) = x * y
mul2(2)(3) is 6
What is mul2(2)? A function that is eating 4, yields 8
(y : Int) => 2 * y
-
7/27/2019 02 FunctionalProgramming Done
33/42
Scala PhD.Nguyen Hua Phung 33
The while control abstraction
def While (cond: =>Boolean)(body: =>unit) {
if (cond) { body; While (cond,body)}
}
While (x < 10) { x += 1; println(x) }# Trick 1: By-name parameters
# Trick 2: Currying
Note While {x < 10} also works
-
7/27/2019 02 FunctionalProgramming Done
34/42
Scala PhD.Nguyen Hua Phung 34
Scala Documentation
Online at http://scala-lang.org/
Be smart: Download and install it locally
Be smart: Bookmark it
Use text field in upper left corner to filter classes
http://d/My%20Documents/PhungUser/File%20Sharing/important/Monhoc/KS-NNLT/2013CQ/Lectures/week2/http://d/My%20Documents/PhungUser/File%20Sharing/important/Monhoc/KS-NNLT/2013CQ/Lectures/week2/ -
7/27/2019 02 FunctionalProgramming Done
35/42
Scala PhD.Nguyen Hua Phung 35
Categories ofList Methods
Basic methods length head tail isEmpty
Operators :: :+ ++ == != /: :\
Access by position (n) take drop dropRight slice indexOflastIndexOf
Methods with unary predicates count exists dropWhilefilter find findIndexOf forall partition remove span takeWhile
Methods with unary function map reverseMap flatMapforeach
Methods with binary predicate sort
Methods with binary function reduceLeft reduceRightfoldLeft foldRight
Otherintersection union zip zipAll xipWithIndex mkString
-
7/27/2019 02 FunctionalProgramming Done
36/42
Scala PhD.Nguyen Hua Phung 36
List operators
:: appends in front, :+ in back
3 :: List(1, 2) is a List (3, 1, 2)
List(1, 2) :+ 3 is List(1, 2, 3)
++ concatenate listsList(1, 2) ++ List(3, 4) is List(1, 2, 3, 4) // same as :::
== and != compare lists
List(Hello,World) == List(He+llo,Wor + ld) /: and :\ later
-
7/27/2019 02 FunctionalProgramming Done
37/42
Scala PhD.Nguyen Hua Phung 37
Operator Precedence and Associativity
On a calculator, what do you get when you type 1 + 2 * 3?
What do you get in C++?
Precedence: Which operator is executed first?
(1 + 2) * 3
1 + (2 * 3) Associativity: If the same operator occurs twice, is the left or right
one executed first? Does 1 2 3 mean?
(1 2) 31 ( 2 3)
In C++, most operators are left-associative.Exception:Assignment
a = b = c
-
7/27/2019 02 FunctionalProgramming Done
38/42
Scala PhD.Nguyen Hua Phung 38
Scala Operators
Function names can be any sequence ofopchars: characters other thanwhitespace, A-Z0-9()[]{}`.,;
Operator precedence depends on first character
(all letters)|
&< >= !:+ -
* / %(all other special characters)
Operators ending in :are right associative; all others are left associative
a :: b :: Nil is a :: (b :: Nil)
-
7/27/2019 02 FunctionalProgramming Done
39/42
Scala PhD.Nguyen Hua Phung 39
Lists: Access by Position
Not every effcient for linked lists
Index value are 0-based
( ) are used for indexed access- not [ ]
List(17,29)(1) is 29 slice takes sublist
List(2, 3, 5, 7).slice(1, 3) is List(3, 5)
Arguments to slice are
first index to include first index to exclude
drop take ?
-
7/27/2019 02 FunctionalProgramming Done
40/42
Scala PhD.Nguyen Hua Phung 40
Methods with Function Parameters
Workhorse functions of the library
You already saw filter, sort, map
Instead of looping, build a function and pass it to
one of these methodsdef randList(len: Int, n: Int) =
(1 to len).map((x: Int) => gen.nextInt(n))
Predicate = function return Boolean
Some methods return a pair
List(2, 3, 5, 7).partition(isEven) is (List(2),List(3,5,7))
-
7/27/2019 02 FunctionalProgramming Done
41/42
Scala PhD.Nguyen Hua Phung 41
Comparing Functional and Imperative
Languages Imperative Languages:
Efficient execution Complex semantics
Complex syntax Concurrency is programmer designed
Functional Languages Simple semantics Simple syntax Inefficient execution Programs can automatically be made concurrent
-
7/27/2019 02 FunctionalProgramming Done
42/42
Summary
Functional programming languages usefunction application, conditional expressions,recursion, and functional forms to control
program execution instead of imperativefeatures such as variables and assignments Purely functional languages have advantages
over imperative alternatives, but their lower
efficiency on existing machine architectureshas prevented them from enjoyingwidespread use