Lecture 3 Functional Programming - Engineeringwrivera/ICOM4036/Lecture3.pdf · Lecture Outline...
Transcript of Lecture 3 Functional Programming - Engineeringwrivera/ICOM4036/Lecture3.pdf · Lecture Outline...
Some slides adapted from Sebesta’s textbook
Dr. Wilson Rivera
ICOM 4036: Programming Languages
Electrical and Computer Engineering Department
University of Puerto Rico
Lecture 3 Functional Programming
ICOM 4036: Programming Languages 2
Lecture Outline
• Fundamentals of FPL • Introduction to Scheme (Dr. Racket)
– Lists – Let and lambda expressions – Map expressions – Tail recursion – Garbage collection – Performance – Libraries
ICOM 4036: Programming Languages 3
Fundamentals of FPL
• The objective of the design of a FPL is to mimic mathematical functions to the greatest extent possible
• The basic process of computation is fundamentally different in a FPL than in 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
– Restriction of types that can be returned by functions. Moreover, functions cannot return functions
ICOM 4036: Programming Languages 4
Fundamentals of FPL
• No functional Side Effects – No Assignments
• Referential Transparency – In an FPL, the evaluation of a function always produces the same result
given the same parameters
• High Order Functions – functions can accept functions as parameters and return functions as
results.
• Less and correct code ??
• 100% algorithm – Java, C: 50% algorithm and 50% memory management
ICOM 4036: Programming Languages 5
Fundamentals of PLs
• LISP (LISts Processing) • ML • Haskell • Erlang • Scheme
ICOM 4036: Programming Languages 6
Scheme
• A mid-1970s dialect of LISP
• Essentially typeless
• Uses only static scoping
• newer compiler-based implementations are fast
• A garbage collector periodically recovers the storage used by inaccessible objects. – Simple atomic values, such as small integers, characters,
booleans, and the empty list, are typically represented as immediate values and thus incur no allocation or deallocation overhead.
• Scheme environments – DrRacket ( more than simple scheme)
– MIT Scheme
– Scheme48
– Kawa
ICOM 4036: Programming Languages 7
Numeric Functions
• Functions: (+ 3 4)
• Composition of functions: (* (+ 2 3)(- 4 2))
ICOM 4036: Programming Languages 8
Defining constants and functions
• (define pi 3.14)
• (display pi)
• (define (square x) (* x x))
ICOM 4036: Programming Languages 9
Predicate Functions
• #T is true and #F is false
• =, <>, >, <, >=, <=
• even?, odd?, zero?, negative?
• number? string? symbol?
– (define x 0)
– (define pi 3.14)
– (= x pi)
• #f
– (zero? x)
• #t
ICOM 4036: Programming Languages 10
Control Flow: IF
(if predicate then_exp else_exp)
(define (factorial n)
(if (= n 0)
1
(*n (factorial(- n 1)))
)
)
ICOM 4036: Programming Languages 11
Control Flow: COND
• Multiple Selection - the special form, COND
General form:
(COND
(predicate_1 expr {expr})
(predicate_1 expr {expr})
...
(predicate_1 expr {expr})
(ELSE expr {expr}))
• Returns the value of the last expression in the first pair whose predicate evaluates to true
ICOM 4036: Programming Languages 12
Example of COND
(define (compare x y)
(cond
((> x y) (display x))
((< x y) (display y))
(else (display “equal numbers”))
)
)
ICOM 4036: Programming Languages 13
List Functions: CAR and CDR
• car takes a list parameter; returns the first element of that list
e.g., (car '(a b c)) yields a
(car '((a b) c d)) yields (a b)
• cdr takes a list parameter; returns the list after removing its first element
e.g., (cdr '(a b c)) yields (b c)
(cdr '((a b) c d)) yields (c d)
• car (first) or cdr (rest)
ICOM 4036: Programming Languages 14
List Functions: CAR and CDR
• (caar ‘((a b) c)) a
• (cadr ‘(1 2 3 4)) 2
• (cdddr ‘(1 2 3 4)) (4)
ICOM 4036: Programming Languages 15
List Functions: CONS and LIST
• the empty list is a proper list, and any pair whose cdr is a proper list is a proper list.
• cons takes two parameters
– (cons 'A ‘B) returns (A . B)
• improper list
– (cdr ‘(A . B)) return B
– (cons ‘A ‘(B)) returns (A B)
• Proper list
– (cdr ‘(A B)) returns (B)
• LIST takes any number of parameters; returns a list with the parameters as elements
– (list ‘A ‘B ‘C) returns (A B C)
– Always return a proper list
ICOM 4036: Programming Languages 16
LIST? and NULL?
• LIST? takes one parameter; it returns #T if the parameter is a list; otherwise #F
• NULL? takes one parameter; it returns #T if the parameter is the empty list; otherwise #F
– Note that NULL? returns #T if the parameter is()
ICOM 4036: Programming Languages 17
Scheme example: Sum List
(define (sumlist x)
(cond
((null? x) 0)
(else (+ (car x) (sumlist (cdr x))))
)
)
ICOM 4036: Programming Languages 18
Scheme example: reverse
(define (reverse list_x)
(cond
((null? list_x)'())
(else (append (reverse (cdr list_x))
(list (car list_x)))
)
)
)
ICOM 4036: Programming Languages 19
Scheme Memory Model
(cons ‘(1 2 3) ‘(4 5 6))
1
2 3
nil
4
5 6
nil
((1 2 3) 4 5 6) cdr car
ICOM 4036: Programming Languages 20
Scheme garbage collection
(define x ‘(1 2 3))
(define y (cdr x))
.
.
.
(define x ‘(4 5))
x
y
4 5
1
2 3
nil
nil
symbol table
ICOM 4036: Programming Languages 21
Example Scheme Function: member
• member takes an atom and a simple list; returns #T if the atom is in the list; #F otherwise
(define (member atm lis)
(cond
((null? lis) #F)
((equal? atm (car lis)) #T)
(else (member atm (cdr lis)))
))
ICOM 4036: Programming Languages 22
Scheme Function: Difference
(define (setdiff lis1 lis2)
(cond
((null? lis1) '())
((null? lis2) lis1)
((member (car lis1) lis2)
(setdiff (cdr lis1) lis2))
(else (cons (car lis1)
(setdiff (cdr lis1) lis2)))
)
)
ICOM 4036: Programming Languages 23
Scheme Function: Intersection
(define (intersection lis1 lis2)
(cond
((null? lis1) '())
((null? lis2) '())
((member (car lis1) lis2)
(cons (car lis1)
(intersection (cdr lis1) lis2)))
(else (intersection (cdr lis1) lis2))
)
)
ICOM 4036: Programming Languages 24
Scheme Function: Union
(define (union lis1 lis2)
(cond
((null? lis1) lis2)
((null? lis2) lis1)
((member (car lis1) lis2)
(cons (car lis1)
(union (cdr lis1)
(setdiff lis2 (cons (car lis1) '()
)))))
(else (cons (car lis1) (union (cdr lis1) lis2)))
)
)
ICOM 4036: Programming Languages 25
Scheme program: mergesort
(define (mergesort L)
(cond ((null? L) L)
((null? (cdr L)) L)
(else (mergelists (mergesort (oddsplit L))
(mergesort (evensplit L)) ))
)
)
ICOM 4036: Programming Languages 26
Scheme Program: Mergelists
(define (mergelists L M)
(cond ( (null? L) M)
( (null? M) L)
( (< (car L)(car M))
(cons (car L) (mergelists (cdr L) M)))
(else
(cons (car M) (mergelists L (cdr M))))
)
)
ICOM 4036: Programming Languages 27
Scheme example: oddsplit
(define (oddsplit L)
(cond
((null? L) '() )
((null? (cdr L)) (list (car L)))
(else (cons (car L) (oddsplit (cdr (cdr L)))))
)
)
ICOM 4036: Programming Languages 28
Scheme example: evensplit
(define (evensplit L)
(cond
((null? L) '() )
((null? (cdr L)) '() )
(else (cons (car (cdr L)) (evensplit (cdr (cdr L))) ))
)
)
ICOM 4036: Programming Languages 29
Let expressions
• (+ (* 3 4) (* 3 4))
• (let ( (x (* 3 4) ))
(+ x x))
• (let ((f +) (x 2))
(f x 3))
• (let ((+ *))
(+ 2 3))
• (let ((x 9))
(* x
(let ((x (/ x 3)))
(+ x x))))
Let* expressions
(let* ( (a 5) (b (+ a a)) (c (+ a b)) )
(list a b c)
)
• Produces (5 10 15)
• Let* evaluates expressions in sequence from left to right
• If let is used produce an error
– Unbound identifier
ICOM 4036: Programming Languages 30
ICOM 4036: Programming Languages 31
Lambda Expressions
• ((lambda (x) (+ x x)) (* 3 4))
• (let ((double (lambda (x) (+ x x))))
(list (double (* 3 4))
(double (/ 99 11))
(double (- 2 7))))
• (let ((double-cons (lambda (x) (cons x x))))
(double-cons 'a))
• (let ((double-any (lambda (f x) (f x x))))
(list (double-any + 13)
(double-any cons 'a)))
Lambda Expressions
(define (add x)
(lambda(y) (+ x y)))
(define f (add 1) )
(f 2)
• The function add returns a function!
ICOM 4036: Programming Languages 32
ICOM 4036: Programming Languages 33
Map Expressions
• (map abs '(1 -2 3 -4 5 -6))
• (map (lambda (x) (* x x)) ’(1 -3 -5 7)))
• (map cons '(a b c) '(1 2 3))
• (define (double x) (* x 2))
• (map double ‘(1 2 3 4))
• (map + ‘(1 2) ‘(3 4) ‘(5 6))
Apply Expressions
(define (average sequence)
(/ (apply + sequence)
(length sequence)
)
)
ICOM 4036: Programming Languages 34
ICOM 4036: Programming Languages 35
Scheme Example: power-set
Power-set ( {1,2,3} )= { }, {3},
{2}, {2,3},
{1}, {1,3}, {1,2}, {1,2,3}
(define (power-set set)
(if (null? set) '(())
(let ((power-set-of-rest (power-set (cdr set))))
(append power-set-of-rest
(map (lambda (subset) (cons (car set) subset))
power-set-of-rest)))))
Scheme Example: Binary Tree
;; Representation of a binary tree
;; (* (+ 2 3)(- 7 8))
(define treeA (make-bin-tree-node '*
(make-bin-tree-node '+
(make-bin-tree-leaf 2)
(make-bin-tree-leaf 3))
(make-bin-tree-node '-
(make-bin-tree-leaf 7)
(make-bin-tree-leaf 8))
)
)
;; See complete file example
ICOM 4036: Programming Languages 36
ICOM 4036: Programming Languages 37
Tail Recursion
• Definition: A function is tail recursive if its recursive call is the last operation in the function
– A tail recursive function can be automatically converted by a compiler to use iteration, making it faster
ICOM 4036: Programming Languages 38
Tail Recursion in Scheme
• Example of rewriting a function to make it tail recursive, using helper
Original: (define (factorial n) (if (= n 0)
1
(* n (factorial (- n 1)))
))
Tail recursive: (define (facthelper n factpartial)
(if (= n 0)
factpartial
(facthelper (- n 1) (* n factpartial)))
)
(define (factorial n)
(facthelper n 1))
Performance in Racket
• Racket automatically optimize code
• Disabling debugging and stack-trace preservation improve performance
• Generational Garbage Collector (3m)
– More efficient; default in Racket
• Conservative Garbage Collector (CGC)
– Facilitates integration with C code at the expense of both precision and speed of memory management
ICOM 4036: Programming Languages 39
Racket Libraries
• Racket Drawing Toolkit
– See Drawing file example
• Racket Graphical Interface Toolkit
ICOM 4036: Programming Languages 40
ICOM 4036: Programming Languages 41
Summary
• Functional programming languages use functional forms to control program execution instead of variables and assignments used in imperative languages
– No side effects
– Referential transparency
– High order functions
• We discussed the fundamentals of Scheme
• Practice using Dr. Racket!!
• Other FPL: LISP, Haskell, ML, Erlang