1 comp313a functional programming (1). 2 lisp… mccarthy’s main contributions were 1.the...
TRANSCRIPT
2
LISP…• McCarthy’s main contributions were
1. 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))))
Haskellfac ::Int -> Intfac n | n == 0 = 1 | n > 0 = fac(n-1) * n | otherwise = 0
Haskellfac :: Int -> Intfac n = if n == 0 then 1 else if n > 0 then fac(n-1) * n else 0
3
2.the use of lists and higher order operations over lists such as mapcar
Lisp…
Scheme(mymap + ’(3 4 6) ’(5 7 8))
Haskellmymap :: (Int -> Int-> Int) -> [Int] -> [Int] ->[Int]mymap f [] [] = []mymap f (x:xs) (y:ys) = f x y : mymap f xs ys
add :: Int -> Int -> Intadd x y = x + y
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)))))))
Haskellmymap add [3, 4, 6] [5, 7, 8]
4
Lisp
3. cons cell and garbage collection of unused cons cells
Scheme (cons ’1 ’(3 4 5 7))
(1 3 4 5 7)
Haskellcons :: 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)))))))
5
Lisp…
4. use of S-expressions to represent both program and data
An expression is an atom or a listBut a list can hold anything…
6
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)))))))
7
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”
8
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
9
let in Scheme
• let* - the bindings are performed sequentially
(let* ((x 2) (y 3))
(* x y))
(let* ((x 2) (y 3))
(let* ((x 7) (z (+ x y)))
(* z x)))
10
let in Scheme
(let ((x 2) (y 3)) ?
(* x y))
• 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)))
11
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))
13
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
14
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
15
SASL, KRC, and Miranda
• Used guards • Higher Order Functions• Lazy Evaluation• Currying
SASLfac n = 1, n = 0 = n * fac (n-1), n>0
Haskellfac n | n ==0 = 1 | n >0 = n * fac(n-1)
add x y = + x y
silly_add x y = x
add 4 (3 * a)
switch :: Int -> a -> a -> aswitch n x y| n > 0 = x| otherwise = y
multiplyC :: Int -> Int -> Int VersusmultiplyUC :: (Int, Int) -> Int
16
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]
17
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
18
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
20
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
21
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
22
List Comprehension
Double all the elements in a list
Using primitive recursiondoubleAll :: [Int] -> [Int]doubleAll [] = []doubleAll x:xs = 2 * x : doubleAll xs
Using list comprehensiondoubleAll :: [Int] -> [Int]doubleAll xs :: [ 2 * x | x <- xs ]