 Download Download Presentation COMP313A Functional Programming (1)

# COMP313A Functional Programming (1)

Download Presentation ## COMP313A Functional Programming (1)

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
##### Presentation Transcript

1. COMP313AFunctional Programming (1)

2. Main Differences with Imperative Languages • Say more about what is computed as opposed to how • Pure functional languages have no • variables • assignments • other side effects • Means no loops

3. Differences… • Imperative languages have an implicit state (state of variables)that ismodified (side effect). • Sequencing is important to gain precise, deterministic control over the state • assignment statement needed to change the binding for a particular variable (alter the implicit state)

4. Imperative factorialn:=x; a:=1;while n > 0 do begin a:= a * n; n := n-1; end;

5. Differences • Declarative languages have no implicitstate • Program with expressions • The state is carried around explicitly • e.g. the formal parameter n in factorial • Looping is accomplished with recursion rather than sequencing

6. Haskell fac ::Int -> Int fac n | n == 0 = 1 | n > 0 = fac(n-1) * n | otherwise = 0 Scheme (define fac (lambda (n) (if (= n 0) 1 (* n (fac (- n 1))))))

7. Advantages • similar to traditional mathematics • referential transparency makes programs more readable • higher order functions give great flexibility • concise programs

8. Referential Transparency • the value of a function depends only on the values of its parameters for example Haskell …x + x… where x = f a

9. Evolution of Functional languagesLambda Calculus • Alonzo Church • Captures the essence of functional programming • Formalism for expressing computation by functions • Lambda abstraction • In Scheme • In Haskell (lx. + 1 x) (lambda(x) (+ 1 x))) add1 :: Int -> Int add1 x = 1 + x

10. Lambda Calculus… • application of expressions • reduction rule that substitutes 2 for x in the lambda (beta reduction) (lx. + 1 x) 2 (lx. + 1 x) 2 Þ (+ 1 2) Þ 3 (lx. * x x) (+ 2 3) i.e. (+ 2 3) / x)

11. Lambda Calculus… • (lx.E) • variable x is bound by the lambda • the scope of the binding is the expression E • (lx. + y x) • (lx. + y x)2 Þ (+ y 2) • (lx. + ((ly. ((lx. * x y) 2)) x) y) Þ

12. Lambda Calculus… • Each lambda abstraction binds only one variable • Need to bind each variable with its own lambda. (lx. (ly. + x y))

13. Lisp • McCarthy late 1950s • Used Lambda Calculus for anonymous functions • List processing language • First attempt built on top of FORTRAN

14. LISP… • McCarthy’s main contributions were • the conditional expression and its use in writing recursive functions Scheme (define fac (lambda (n) (if (= n 0) 1 (if (> n 0) (* n (fac (- n 1))) 0)))) Scheme (define fac2 (lambda (n) (cond ((= n 0) 1) ((> n 0) (* n (fac2 (- n 1)))) (else 0)))) Haskell fac ::Int -> Int fac n | n == 0 = 1 | n > 0 = fac(n-1) * n | otherwise = 0 Haskell fac :: Int -> Int fac n = if n == 0 then 1 else if n > 0 then fac(n-1) * n else 0

15. Lisp… 2. the use of lists and higher order operations over lists such as mapcar Scheme (define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (rest a) (rest b))))))) Haskell mymap :: (Int -> Int-> Int) -> [Int] -> [Int] ->[Int] mymap f [] [] = [] mymap f (x:xs) (y:ys) = f x y : mymap f xs ys add :: Int -> Int -> Int add x y = x + y Scheme (mymap + ’(3 4 6) ’(5 7 8)) Haskell mymap add [3, 4, 6] [5, 7, 8]

16. Lisp • cons cell and garbage collection of unused cons cells Scheme (cons ’1 ’(3 4 5 7)) (1 3 4 5 7) Haskell cons :: Int -> [Int] -> [Int] cons x xs = x:xs Scheme (define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (first a) (first b)))))))

17. Lisp… • use of S-expressions to represent both program and data An expression is an atom or a list But a list can hold anything…

18. Scheme (cons ’1 ’(3 4 5 7)) (1 3 4 5 7) Scheme (define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (first a) (first b)))))))

19. ISWIM • Peter Landin – mid 1960s • If You See What I Mean Landon wrote “…can be looked upon as an attempt to deliver Lisp from its eponymous commitment to lists, its reputation for hand-to-mouth storage allocation, the hardware dependent flavour of its pedagogy, its heavy bracketing, and its compromises with tradition”

20. Iswim… • Contributions • Infix syntax • let and where clauses, including a notion of simultaneous and mutually recursive definitions • the off side rule based on indentation • layout used to specify beginning and end of definitions • Emphasis on generality • small but expressive core language

21. let in Scheme • let* - the bindings are performed sequentially (let* ((x 2) (y 3)) (let* ((x 7) (z (+ x y))) Þ ? (* z x))) (let* ((x 2) (y 3)) Þ ? (* x y))

22. let in Scheme • let - the bindings are performed in parallel, i.e. the initial values are computed before any of the variables are bound (let ((x 2) (y 3)) (let ((x 7) (z (+ x y))) Þ ? (* z x))) (let ((x 2) (y 3)) Þ ? (* x y))

23. letrec in Scheme • letrec – all the bindings are in effect while their initial values are being computed, allows mutually recursive definitions (letrec ((even? (lambda (n) (if (zero? n) #t (odd? (- n 1))))) (odd? (lambda (n) (if (zero? n) #f (even? (- n 1)))))) (even? 88))

24. ML • Gordon et al 1979 • Served as the command language for a proof generating system called LCF • LCF reasoned about recursive functions • Comprised a deductive calculus and an interactive programming language – Meta Language (ML) • Has notion of references much like locations in memory • I/O – side effects • But encourages functional style of programming

25. ML • Type System • it is strongly and statically typed • uses type inference to determine the type of every expression • allows polymorphic functions • Has user defined ADTs

26. SASL, KRC, and Miranda add x y = + x y add 1 • Used guards • Higher Order Functions • Lazy Evaluation • Currying switch :: Int -> a -> a -> a switch n x y | n > 0 = x | otherwise = y SASL fac n = 1, n = 0 = n * fac (n-1), n>0 multiplyC :: Int -> Int -> Int Versus multiplyUC :: (Int, Int) -> Int Haskell fac n | n ==0 = 1 | n >0 = n * ( fac(n-1)

27. SASL, KRC and Miranda • KRC introduced list comprehension • Miranda borrowed strong data typing and user defined ADTs from ML comprehension :: [Int] -> [Int] comprehension ex = [2 * n | n <- ex]

28. COMP313AFunctional Programming (1)

29. LISP… • McCarthy’s main contributions were • the conditional expression and its use in writing recursive functions Scheme (define fac (lambda (n) (if (= n 0) 1 (if (> n 0) (* n (fac (- n 1))) 0)))) Scheme (define fac2 (lambda (n) (cond ((= n 0) 1) ((> n 0) (* n (fac2 (- n 1)))) (else 0)))) Haskell fac ::Int -> Int fac n | n == 0 = 1 | n > 0 = fac(n-1) * n | otherwise = 0 Haskell fac :: Int -> Int fac n = if n == 0 then 1 else if n > 0 then fac(n-1) * n else 0

30. Lisp… 2. the use of lists and higher order operations over lists such as mapcar Scheme (define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (rest a) (rest b))))))) Haskell mymap :: (Int -> Int-> Int) -> [Int] -> [Int] ->[Int] mymap f [] [] = [] mymap f (x:xs) (y:ys) = f x y : mymap f xs ys add :: Int -> Int -> Int add x y = x + y Scheme (mymap + ’(3 4 6) ’(5 7 8)) Haskell mymap add [3, 4, 6] [5, 7, 8]

31. Lisp • cons cell and garbage collection of unused cons cells Scheme (cons ’1 ’(3 4 5 7)) (1 3 4 5 7) Haskell cons :: Int -> [Int] -> [Int] cons x xs = x:xs Scheme (define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (first a) (first b)))))))

32. Lisp… • use of S-expressions to represent both program and data An expression is an atom or a list But a list can hold anything…

33. Scheme (cons ’1 ’(3 4 5 7)) (1 3 4 5 7) Scheme (define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (first a) (first b)))))))

34. ISWIM • Peter Landin – mid 1960s • If You See What I Mean Landon wrote “…can be looked upon as an attempt to deliver Lisp from its eponymous commitment to lists, its reputation for hand-to-mouth storage allocation, the hardware dependent flavour of its pedagogy, its heavy bracketing, and its compromises with tradition”

35. Iswim… • Contributions • Infix syntax • let and where clauses, including a notion of simultaneous and mutually recursive definitions • the off side rule based on indentation • layout used to specify beginning and end of definitions • Emphasis on generality • small but expressive core language

36. let in Scheme • let* - the bindings are performed sequentially (let* ((x 2) (y 3)) (let* ((x 7) (z (+ x y))) Þ ? (* z x))) (let* ((x 2) (y 3)) Þ ? (* x y))

37. let in Scheme • let - the bindings are performed in parallel, i.e. the initial values are computed before any of the variables are bound (let ((x 2) (y 3)) (let ((x 7) (z (+ x y))) Þ ? (* z x))) (let ((x 2) (y 3)) Þ ? (* x y))

38. letrec in Scheme • letrec – all the bindings are in effect while their initial values are being computed, allows mutually recursive definitions (letrec ((even? (lambda (n) (if (zero? n) #t (odd? (- n 1))))) (odd? (lambda (n) (if (zero? n) #f (even? (- n 1)))))) (even? 88))

39. Emacs was/is written in LISP • Very popular in AI research

40. ML • Gordon et al 1979 • Served as the command language for a proof generating system called LCF • LCF reasoned about recursive functions • Comprised a deductive calculus and an interactive programming language – Meta Language (ML) • Has notion of references much like locations in memory • I/O – side effects • But encourages functional style of programming

41. ML • Type System • it is strongly and statically typed • uses type inference to determine the type of every expression • allows polymorphic functions • Has user defined ADTs

42. SASL, KRC, and Miranda add x y = + x y silly_add x y = x add 4 (3 * a) • Used guards • Higher Order Functions • Lazy Evaluation • Currying switch :: Int -> a -> a -> a switch n x y | n > 0 = x | otherwise = y SASL fac n = 1, n = 0 = n * fac (n-1), n>0 multiplyC :: Int -> Int -> Int Versus multiplyUC :: (Int, Int) -> Int Haskell fac n | n ==0 = 1 | n >0 = n * fac(n-1)

43. SASL, KRC and Miranda • KRC introduced list comprehension • Miranda borrowed strong data typing and user defined ADTs from ML comp_example :: [Int] -> [Int] comp_example ex = [2 * n | n <- ex]

44. The Move to Haskell • Lots of functional languages in late 1970’s and 1980’s • Tower of Babel • Among these was Hope • strongly typed • polymorphism but explicit type declarations as part of all function definitions • simple module facility • user-defined concrete data types with pattern matching

45. The Move to Haskell • 1987 – considered lack of common language was hampering the adoption of functional languages • Haskell was born • higher order functions • lazy evaluation • static polymorphic typing • user-defined datatypes • pattern matching • list comprehensions

46. Haskell… • as well • module facility • well defined I/O system • rich set of primitive data types

47. Higher Order Functions • Functions as first class values • stored as data structures, passed as arguments, returned as results • Function is the primary abstraction mechanism • increase the use of this abstraction • Higher order functions are the “guts” of functional programming

48. Higher Order FunctionsComputations over lists • Mapping • add 5 to every element of a list. • add the corresponding elements of 2 lists • Filtering • Selecting the elements with a certain property • Folding • Combine the items in a list in some way

49. List Comprehension Double all the elements in a list Using primitive recursion doubleAll :: [Int] -> [Int] doubleAll [] = [] doubleAll x:xs = 2 * x : doubleAll xs Using list comprehension doubleAll :: [Int] -> [Int] doubleAll xs :: [ 2 * x | x <- xs ]

50. Primitive RecursionversusGeneral Recursion sum :: [Int] -> Int sum [] = 0 sum (x:xs) = x + sum xs qsort :: [Int] -> [Int] qsort [] = [] qsort (x : xs) = qsort [ y | y<-xs , y<=x] ++ [x] ++ qsort [ y | y <- xs , y>x]