CSE583: Programming Languages Functional Programming
Total Page:16
File Type:pdf, Size:1020Kb
Functional programming: two weeks G Scheme – Gives a strong, language-based foundation CSE583: for functional programming Programming Languages – May be mostly review for some of you G Some theory David Notkin – Theoretical foundations and issues in 11 January 2000 functional programming [email protected] G ML http://www.cs.washington.edu/education/courses/583 – A modern basis for discussing key issues in functional programming University of Washington • CSE583 • D. Notkin © 2000 2 Scheme: a Lisp descendant Statically scoped (review) G A statically scoped and properly tail-recursive G A free variable in a proc fork(x,y:int){ function definition is proc snork(a:int){ dialect of the Lisp programming language proc cork() { bound to the variable developed by Steele and Sussman in the mid a := x + y; of the same name in 1970s } the closest enclosing x : int; – Embodies an executable version of the lamda block a := x + y; } calculus G Dynamically scoped: } G Intended to have an exceptionally clear and free variable bound to simple semantics with few different ways to nearest match on the form expressions call stack University of Washington • CSE583 • D. Notkin © 2000 3 University of Washington • CSE583 • D. Notkin © 2000 4 Tail recursive Scheme G The top level call (define member(e l) G Dynamically typed, strongly typed (cond returns a value G identical to that of (null l) #f Expression-oriented, largely side-effect- the bottom level (equal e (car l)) #t free call (member e (cdr l)) – Functional languages are expression, not G Who cares? )) statement-oriented, since the expression – Performance! G Once an element is a member, define the function computation it’s always a member – Scheme requires G List-oriented, garbage-collected heap- G tail recursion to be Once you start returning true, based implemented as you keep on returning true until efficiently as you unwind the whole recursive G Good compilers exist iteration call stack University of Washington • CSE583 • D. Notkin © 2000 5 University of Washington • CSE583 • D. Notkin © 2000 6 1 read-eval-print loop Scheme syntax G Programming language equivalent of Program ::= ( Definition | Expr ) Definition ::= fetch-increment-execute structure of (define id Expr) computer architectures | (define (idfn idformal1 … idformalN) Expr) G Heart of most interpreted languages Expr ::= id | Literal | SpecialForm | (Exprfn Exprarg1 … ExprargN) G Helps in rapid development of small Literal ::= int | string | symbol | … (if programs; simplifies debugging SpecialForm ::= Exprtest Exprthen Exprelse) | ... University of Washington • CSE583 • D. Notkin © 2000 7 University of Washington • CSE583 • D. Notkin © 2000 8 Ex: Definitions, expressions and Examples evaluation results G (+ 3 4) G Identifiers G Literals (self-evaluating 7 – x expressions) – 3 G (define seven (+ 3 4)) – x1_2 seven – 0.34 – is-string? G seven – -5.6e-7 7 – make-string! – “hello world!” G (+ seven 8) – <= 15 – “” G (define (square n) (* n n)) – #t square – #f G (square 7) 49 University of Washington • CSE583 • D. Notkin © 2000 9 University of Washington • CSE583 • D. Notkin © 2000 10 Another example Special forms G Everything is G (define x 0) G (define (fact n) an expression, G Standard rule: (if (<= n 0) G (define y 5) including what evaluate all 1 G (if (= x 0) we usually (* n (fact (- n 1))))) arguments before 0 (/ y x)) fact think of as invocation 0 control G (define (my-if c t e) G – This is called eager (fact 20) structures (if c t e)) 2432902008176640000 evaluation G Prefix G (my-if (= x 0) G G (fact 1) operators and Can cause 0 (/ y x)) 1 functions calls computational (and error! G (fact “xyz”) are regular, performance) ??? although not problems G (fact 3) traditional G Can define your own University of Washington • CSE583 • D. Notkin © 2000 11 University of Washington • CSE583 • D. Notkin © 2000 12 2 Other special forms Two more special forms G cond: like if-elseif-…else chain G Local variable bindings – (define x 1) (define y 2) (define z 3) – (cond ((> x 0) 1) (let ((x 5) (= x 0) 0) (y (+ 3 4)) (else -1))) (z (+ x y z))) (+ x y z) G short-circuit booleans 18 – (or (= x 0) (> (/ y x) 5) …) G Sequentially evaluated local variable bindings – Replace let by let* – The same expression evaluates to 27 University of Washington • CSE583 • D. Notkin © 2000 13 University of Washington • CSE583 • D. Notkin © 2000 14 Lists List creation G Standard data structure for aggregates G cons adds a cell at the beginning of a list, non- destructively G cons A list is a singly-linked chain of - – Remember, in the functional world, we don’t destroy cells (i.e., pairs) things (which would be a side-effect) G G (define snork (5 6 7 8)) (define fork (cons 4 snork)) – fork → (4 5 6 7 8) – snork → (5 6 7 8) () snork () [nil] snork () 5 6 7 8 fork [nil] 4 5 6 7 8 University of Washington • CSE583 • D. Notkin © 2000 15 University of Washington • CSE583 • D. Notkin © 2000 16 List accessors Why the names car and cdr? G car (head) returns the first element in a list – (+ (car snork) (car fork)) → 9 G cdr (tail) non-destructively returns the rest of the elements in the list after the first – (define dork (cdr fork)) – fork → (4 5 6 7 8) snork → (5 6 7 8) dork → (6 7 8) snork dork () fork [nil] 4 5 6 7 8 University of Washington • CSE583 • D. Notkin © 2000 17 University of Washington • CSE583 • D. Notkin © 2000 18 3 The empty list Lists: heterogeneous and nested G () is the empty list literal G (define foo (5 6.7 “I am not a wuss”)) G – In Lisp, this is the same as nil; in some (define bar (5 (6 7) “wuss” (“a” 4))) Scheme implementations, it is the same as bar () #f as well 5 "wuss" G (cons 6 ()) → (6) "wuss" () – The second argument to cons must be a list "a" 4 G (cdr (cons 6 ()) → () () G (cdr 6) → ??? 6 7 University of Washington • CSE583 • D. Notkin © 2000 19 University of Washington • CSE583 • D. Notkin © 2000 20 Quoting Programs and data G How can we distinguish list literals from G It should now be obvious that programs function invocations? and data share the same syntax in – (cdr (cons 6 ()) → () Scheme (Lisp) – (cdr (cons (7 8) ()) G To come full circle in this, there is a eval → error [function 7 not known] form that takes a list and evaluates it – (cdr (cons (quote (7 8)) ()) – (eval ‘(+ 2 3 4)) → 9 → () G Among other things, this makes it quite – quote (‘) and list are special forms easy to write a Scheme interpreter in – (cdr (cons ‘ (7 8) ()) Scheme – (list 7 8) University of Washington • CSE583 • D. Notkin © 2000 21 University of Washington • CSE583 • D. Notkin © 2000 22 Equality Other predicates G There are (more G (eqv? 3 3) → #t G Numeric comparisons than) two different G (eqv? ’(3 4) ‘(3 4)) notions of equality → #f G Type-testing predicates, available in Scheme (and G (let ((x ‘(3 4))) → most other (eqv? x x) #t due to the use of dynamic typing programming G (equal? ’(3 4) ‘(3 4)) – null? pair? symbol? boolean? → #t languages) G (eqv? “hi” “hi”) → #f number? integer? string? … – Are the two entities G → isomorphic? (equal? “hi” “hi”) #t G The use of the ? is a convention (equal?) G (eqv? ‘hi ‘hi) → #t – Are they the exact G (eqv? () ()) → #t same entity? (eqv?) University of Washington • CSE583 • D. Notkin © 2000 23 University of Washington • CSE583 • D. Notkin © 2000 24 4 A note about binding and Global heap parameter passing G All variables refer to data values, yielding a G All data structures are implicitly allocated simple, regular model in the global heap G let binding and parameter passing do not copy G Gives data structures unlimited lifetime – They introduce a new name that refers to and shares the right-hand-side value (indefinite extent) – “call by pointer value” or “call by sharing” – Simple and expressive G (define snork ‘(3 4 5)) G Allows all data to be passed around and (define (f fork) (let ((dork fork)) returned from functions and stored in (and (eqv? snork fork) other data structures (eqv? dork fork)))) (f snork) → #t University of Washington • CSE583 • D. Notkin © 2000 25 University of Washington • CSE583 • D. Notkin © 2000 26 Garbage collection Recursion over lists G System automatically reclaims memory G Lists are a recursive (define (f x …) for unused data structures data type (if (null? x) – A list is either () [base …base case on – Programmer needn’t worry about freeing case] unused memory – Or a pair of a value (car x) and another list …inductive – Avoids freeing too early (dangling pointer [inductive case] case on (cdr x) bugs) and freeing too late (storage leak bugs) G Good for )) – System can sometimes be more efficient than manipulation by programming recursive functions that share this structure University of Washington • CSE583 • D. Notkin © 2000 27 University of Washington • CSE583 • D. Notkin © 2000 28 Recursive examples Another example (define (length x) G Find a value associated with a given key in an association list (if (null? x) 0 (alist), a list of key-value pairs G (define (assoc key alist) (+ 1 (length (cdr x))))) (if (null? alist) #f (let* ((pair (car alist)) (define (sum x) (k (car pair)) (if (null? x) 0 (v (cdr pair))) (+ (car x) (sum (cdr x))))) (if (equal? key k) v (assoc key (cdr alist)))))) (define Zips (list ‘(98195 Seattle) ‘(15213 Pittsburgh))) (assoc 98195 Zips) → #t (assoc 98103 Zips) → #f University of Washington • CSE583 • D. Notkin © 2000 29 University of Washington • CSE583 • D. Notkin © 2000 30 5 Yet another example Append: in list form fork () G Append two lists non-destructively 4 5 – Requires a copy of the first list but not snork () the second one () – Sharing of list substructures is 6 7 8 common and safe with no side-effects dork G (define (append x1 x2) (if (null? x1) x2 4 5 (cons (car x1) G (define snork ‘(6 7 8)) (append (cdr x1) G (define fork ‘(4 5)) x2)))) G (define dork (append fork snork)) University of Washington • CSE583 • D.