02 functionalprogramming done

Upload: algorithm-hbk

Post on 14-Apr-2018

219 views

Category:

Documents


0 download

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