Functional Programming in Lisp
Total Page:16
File Type:pdf, Size:1020Kb
Functional Programming in Lisp Dr. Neil T. Dantam CSCI-561, Colorado School of Mines Fall 2020 Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 1 / 50 Alan Perlis on Programming Languages https://doi.org/10.1145%2F947955.1083808 “A language that doesn’t affect the way you think about programming is not worth knowing.” Alan J. Perlis (1922-1990) First Turing Award Recipient, 1966 Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 2 / 50 Eric Raymond and Paul Graham on Lisp Lisp is worth learning for a different reason— By induction, the only programmers in a position to see the profound enlightenment experience you will have all the differences in power between the various languages when you finally get it. That experience will make are those who understand the most powerful one. you a better programmer for the rest of your days, (This is probably what Eric Raymond meant about even if you never actually use Lisp itself a lot. Lisp making you a better programmer.) –Eric Raymond –Paul Graham http://www.catb.org/esr/faqs/hacker-howto.html http://www.paulgraham.com/avg.html Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 3 / 50 Peter Siebel on Lisp, “Blub,” and “Omega” https://youtu.be/4NO83wZVT0A?t=18m26s Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 4 / 50 Introduction Functional Programming Features Outcomes I Persistence: variables and data structures are I Review/understand concepts of immutable (constant) functional programming I Recursion: construct algorithms as recursive I Implement Lisp programs in functions (vs. loops) functional style I First-class functions: can be passed to and returned from other functions Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 5 / 50 Trade-offs of Functional Programming Pros Cons I Easy (comparatively) to reason about I Different way of thinking about (prove) correctness programs (also a pro!) I Compact (fewer LoC) I Sometimes less (constant-factor) I Immutable structures shared between efficient modules, threads, etc. Well-aligned with the algorithms and proofs in this course. Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 6 / 50 Outline Recursion First-Class Functions Higher-order Functions Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 7 / 50 Recursion Outline Recursion First-Class Functions Higher-order Functions Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 8 / 50 Recursion Definition: Recursion Review Definition (Recursion) Example (Factorial) A function or other object defined in terms of itself. ( Base Case: Terminating condition 1 if n = 0 n! = Recursive Case: Reduction towards the base case n ∗ (n − 1)! if n 6= 0 Function fact(n) 1 if 0 = n then return 1 ; 2 else return n ∗ fact(n − 1) ; Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 9 / 50 Recursion Example: Factorial “Math” ( 1 if n = 0 n! = n ∗ (n − 1)! if n 6= 0 Pseudocode Common Lisp Procedure fact(x) ( defun f a c t ( n ) 1 if 0 = x then /* Base Case */ ( i f (= n 0) 2 return 1; 1 3 else /* Recursive Case */ (∗ n 4 return x ∗ fact(x − 1); ( f a c t (− n 1 ) ) ) ) ) Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 10 / 50 Recursion Exercise: Recursive Fibonacci Sequence (1; 1; 2; 3; 5; 8; 13; 21; 34; 55;:::) 8 1 if n = 0 <> fib(n) = 1 if n = 1 :>fib(n − 1) + fib(n − 2) if n ≥ 2 Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 11 / 50 ( defun f i b ( n ) if 0 = n then return 1 ; ( cond ((= n 0) 1) 2 else if 1 = n then return 1 ; ((= n 1) 1) 3 else ( t (+ ( f i b (− n 1) ) 4 return fib(n − 1) + fib(n − 2); ( f i b (− n 2 ) ) ) ) ) ) Recursion Exercise: Recursive Fibonacci Sequence continued Pseudocode Common Lisp Procedure fib(x) 1 Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 12 / 50 Recursion Example: Recursive Accumulate in Lisp Pseudocode Recursive Accumulate in Lisp Function accum(S) ( defun accum ( l i s t ) 1 if S then // Recursive Case ( i f l i s t 2 return car(S) + accum (cdr (S)); ;; recursive case 3 else // Base Case (+ ( c a r l i s t ) 4 return 0; ( accum ( cdr l i s t ))) ;; base case 0 )) Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 13 / 50 Recursion Example: Recursive Accumulate Execution Trace (accumulate ’(1 2 3)) Recursive Accumulate in Lisp ( defun accum ( l i s t ) (+ 1 (accumulate ’(2 3))) ( i f l i s t ;; recursive case (+ 1 (+ 2 (accumulate ’(3)))) (+ ( c a r l i s t ) ( accum ( cdr l i s t ))) ;; base case (+ 1 (+ 2 (+ 3 (accumulate nil)))) 0 )) (+ 1 (+ 2 (+ 3 0))) Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 14 / 50 Recursion Example: Alternate Recursive Accumulate Accumulate Alternate Accumulate ( defun accum ( l i s t ) ( defun accum ( l i s t ) ( i f l i s t ( l a b e l s ( ( r e c ( l i s t accum ) ;; recursive case ( i f l i s t (+ ( c a r l i s t ) ;; recursive case ( accum ( cdr l i s t ))) ( r e c ( cdr l i s t ) ;; base case (+ ( c a r l i s t ) 0 )) accum ) ) ;; base case accum ) ) ) ( r e c l i s t 0 ) ) ) Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 15 / 50 Recursion Example: Alternate Accumulate Execution Trace Alternate Accumulate (accumulate ’(1 2 3)) ( defun accum ( l i s t ) ( l a b e l s ( ( r e c ( l i s t accum ) (rec ’(1 2 3) 0) ( i f l i s t ;; recursive case ( r e c ( cdr l i s t ) (rec ’(2 3) 1) (+ ( c a r l i s t ) accum ) ) ;; base case (rec ’(3) 3) accum ) ) ) ( r e c l i s t 0 ) ) ) (rec ’() 6) Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 16 / 50 ( defun r e v e r s e − r e c ( l i s t ) function h(L; r) is ( l a b e l s 2 if L then ( ( h e l p e r ( l i s t r e v e r s e d ) 3 return ( i f l i s t h(cdr(L),cons(car(L); r)); (helper (cdr l i s t ) ( cons ( c a r l i s t ) 4 else return r ; r e v e r s e d ) ) 5 return h(L, NIL); reversed))) ( h e l p e r l i s t n i l ) ) ) Recursion Exercise: Recursive Reverse reverse (a0 a1 ::: an−1 an) (an an−1 ::: a1 a0) Pseudocode Common Lisp Procedure reverse(L) 1 Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 17 / 50 Recursion DESTRUCTURING-BIND DESTRUCTURING-BIND DESTRUCTURING-BIND bind variables to corresponding values draw from a list. Example Example (destructuring − b i n d ( a b c ) (destructuring − bind (op e1 e2) ’(1 2 3) ’(+ 1 2) ( l i s t c b a ) ) (+ e1 e2 ) ) Output Output (3 2 1) 3 Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 18 / 50 Recursion Example: destructuring-bind Return S-Expression as infix string Code ( defun a r i t h − s t r i n g ( e ) "Returns −expE as an infix string." ( i f ( l i s t p e ) (destructuring − bind (op e1 e2) e ( format n i l"(~A)~A (~A)" ( a r i t h − s t r i n g e1 ) op ( a r i t h − string e2))) ( format n i l"~A" e))) Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 19 / 50 ( defun e v a l − a r i t h ( e ) ( i f ( l i s t p e ) (destructuring − bind (op e1 e2) e ( cond (( eq op ’+) (+ ( e v a l − a r i t h e1 ) ( e v a l − a r i t h e2 ) ) ) (( eq op ’−) (− ( e v a l − a r i t h e1 ) ( e v a l − arith e2))))) e ) ) Recursion Exercise: destructuring-bind Evaluate Arithmetic S-Expression Code Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 20 / 50 First-Class Functions Outline Recursion First-Class Functions Higher-order Functions Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 21 / 50 First-Class Functions First-class functions Definition: First-class functions A programming language has first-class functions when it treats functions like any other variable or object. First-class functions can be: I Bind variables to the function I Passed as arguments to other functions I Returned as the result of other functions Dantam (Mines CSCI-561) Functional Programming in Lisp Fall 2020 22 / 50 First-Class Functions Function Closure Definition (Function Closure) A function closure or lexical closure is a function and an associated set of variable definitions. Etymology: from “closed expression.” Example (C Function Pointer) Example (Java Class) /∗ D e f i n i t i o n ∗/ // Definition s t r u c t c o n t e x t { class Adder { i n t v a l ; p u b l i c i n t a ; }; public Adder( i n t a_) { a = a_ ; i n t adder ( s t r u c t c o n t e x t ∗cx , i n t x ) { } return cx−>a + x ; p u b l i c i n t c a l l ( i n t x ) { } return x+a ; } /∗ Usage ∗/ } s t r u c t c o n t e x t c ; c .