Functional Programming with Common Lisp Kamen Tomov ktomov@hotmail.com July 03, 2015
Table of Contents What is This About? Functional Programming Specifics Is Lisp a Functional Language? Lisp Says Hi Functional Programming Features Functional Processing of Sequences Beyond the Functional Paradigm Summary
What is This About? What is FP?
What is This About? What is FP? In computer science, FP is a programming paradigm a style of building the structure and elements of computer programs that treats computation as the evaluation of mathematical functions It is a declarative programming paradigm (not describing the control flow) which means programming is done with expressions What is expression?
What is This About? What is FP? In computer science, FP is a programming paradigm a style of building the structure and elements of computer programs that treats computation as the evaluation of mathematical functions It is a declarative programming paradigm (not describing the control flow) which means programming is done with expressions What is expression? A combination of stuff that according to some rules evaluates to a value What is a functional language made up from?
What is This About? What is FP? In computer science, FP is a programming paradigm a style of building the structure and elements of computer programs that treats computation as the evaluation of mathematical functions It is a declarative programming paradigm (not describing the control flow) which means programming is done with expressions What is expression? A combination of stuff that according to some rules evaluates to a value What is a functional language made up from? Functions What is a function?
What is This About? What is FP? In computer science, FP is a programming paradigm a style of building the structure and elements of computer programs that treats computation as the evaluation of mathematical functions It is a declarative programming paradigm (not describing the control flow) which means programming is done with expressions What is expression? A combination of stuff that according to some rules evaluates to a value What is a functional language made up from? Functions What is a function? A function is a concept from math that has been with us for centuries: A function is a static, well-defined mapping from input values to output values. For example: f (ax) = 2x + 1
What is This About? Functional is the new object-oriented What is the value of Functional Programming? Powerful Paradigm (brings simplicity, clarity, and quality all resulting in shorter development time) Growing availability of features in mainstream languages Growing popularity of functional languages
Lisp is a Dinosaur First Appearance: 1958 Invented by John McCarthy at MIT. Steve Russell invents the fundamental eval function Based on Alonzo Church s lambda calculus Influenced by IPL - a bit younger and lower-level language created at RAND Corporation and the Carnegie Institute of Technology First implementation - Steve Russell on an IBM 704 computer
What is This About? It wasn t me! When it comes to Lisp, I am: Not a Hacker...
What is This About? It wasn t me! When it comes to Lisp, I am: Not a Hacker... Perhaps not yet..
What is This About? It wasn t me! When it comes to Lisp, I am: Not a Hacker... Perhaps not yet.. Not a Scientist...
What is This About? It wasn t me! When it comes to Lisp, I am: Not a Hacker... Perhaps not yet.. Not a Scientist... It would have been great
What is This About? It wasn t me! When it comes to Lisp, I am: Not a Hacker... Perhaps not yet.. Not a Scientist... It would have been great Not a McCarthy contemporary...
What is This About? It wasn t me! When it comes to Lisp, I am: Not a Hacker... Perhaps not yet.. Not a Scientist... It would have been great Not a McCarthy contemporary... Believe it or not
What is This About? It wasn t me! When it comes to Lisp, I am: Not a Hacker... Perhaps not yet.. Not a Scientist... It would have been great Not a McCarthy contemporary... Believe it or not My only qualification is...
What is This About? It wasn t me! When it comes to Lisp, I am: Not a Hacker... Perhaps not yet.. Not a Scientist... It would have been great Not a McCarthy contemporary... Believe it or not My only qualification is... I m extremely good looking
Functional Programming Specifics Can you enumerate functional programming languages?
Functional Programming Specifics Can you enumerate functional programming languages? What is a must to be able to program functionally?
Functional Programming Specifics Can you enumerate functional programming languages? What is a must to be able to program functionally? First-class functions.
Functional Programming Specifics Can you enumerate functional programming languages? What is a must to be able to program functionally? First-class functions. What is good to have?
Functional Programming Specifics Can you enumerate functional programming languages? What is a must to be able to program functionally? First-class functions. What is good to have? Anonymous functions Recursion Immutability Closures (for optimization) GC Currying Lazy evaluation
Functional Programming Specifics Can you enumerate functional programming languages? What is a must to be able to program functionally? First-class functions. What is good to have? Anonymous functions Recursion Immutability Closures (for optimization) GC Currying Lazy evaluation How much of this is needed for a language to qualify for a functional?
Is Lisp a Functional Language? defun keyword in Lisp actually creates a funcallable instance, not a static mapping input to output Lisp being functional - origin: (1) an abstraction for locally naming arguments in a piece of re-usable code - manual register and stacks manipulation; (2) procedures being values themselves Back to the definition of a mathematical function and pure functional languages creation Observation: Pure functional is not practical real-world problems solver. Applicable to closed systems. The takeaway: isolation of functional and non-functional parts. What should happen vs how does it happen
How does Lisp fit in? Functions are first-class citizens Anything returns value. No statements concept to support horrible infix syntax Lots of the good to have s of the functional languages. Lisp introduced most of them. The rest - via macroses Functional languages vs functional style Not a functional language but a software factory for languages or other code Conclusion
What Do Others Say? Lisp has jokingly been called the most intelligent way to misuse a computer. I think that description is a great compliment because it transmits the full flavor of liberation: it has assisted a number of our most gifted fellow humans in thinking previously impossible thoughts. - Edsger Dijkstra, CACM, 15:10 Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot. - Eric Raymond, How to Become a Hacker
Common Lisp Overview The Lisp Family: Arc, AutoLISP, Clojure, Common Lisp, Emacs Lisp, EuLisp, Franz Lisp, Hy, Interlisp, ISLISP, LeLisp, LFE, Maclisp, MDL, Newlisp, NIL, Picolisp, Portable Standard Lisp, Racket, Scheme, SKILL, Spice Lisp, T, XLISP, Zetalisp Major Lisp dialect: Common Lisp Designed by Scott Fahlman, Richard P. Gabriel, Dave Moon, Guy Steele, Dan Weinreb First appeared in 1984 1994 ANSI standard, Kent Pitman Typing: Dynamic, Strong Hardware: General Purpose and Lisp Machines OS: Cross-platform Drop Common
Lisp Syntax Calculate 32/2(1 + 3)
Lisp Syntax Calculate 32/2(1 + 3) 64
Lisp Syntax Calculate 32/2(1 + 3) 64 Calculate (* (/ 16 4) (+ 2 6))
Lisp Syntax Calculate 32/2(1 + 3) 64 Calculate (* (/ 16 4) (+ 2 6)) 32
Lisp Syntax This is MathML excerpt: <math> <apply> <plus/> <apply> <times/> <ci>a</ci> <apply> <power/> <ci>x</ci> <cn>2</cn> </apply> </apply> <ci>c</ci> </apply> </math>
Lisp Syntax This is MathML excerpt: <math> <apply> <plus/> <apply> <times/> <ci>a</ci> <apply> <power/> <ci>x</ci> <cn>2</cn> </apply> </apply> <ci>c</ci> </apply> </math> It is equivalent to: ax 2 + c
Lisp Syntax This is MathML excerpt: <math> <apply> <plus/> <apply> <times/> <ci>a</ci> <apply> <power/> <ci>x</ci> <cn>2</cn> </apply> </apply> <ci>c</ci> </apply> </math> It is equivalent to: ax 2 + c How about this: (+ (* a (expt x 2)) c))
Lisp Syntax This is MathML excerpt: <math> <apply> <plus/> <apply> <times/> <ci>a</ci> <apply> <power/> <ci>x</ci> <cn>2</cn> </apply> </apply> <ci>c</ci> </apply> </math> It is equivalent to: ax 2 + c How about this: (+ (* a (expt x 2)) c)) And they call parentheses stupid!?
Basics x ; the symbol X () ; the empty list (1 2 3) ; a list of three numbers ("foo" "bar") ; a list of two strings (x y z) ; a list of three symbols (x 1 "foo") ; a list of a symbol, a number, and a string (+ (* 2 3) 4) ; a list of a symbol, a list, and a number. (format t "hello, world") (list a b c) (cons a nil) (cons a (list b c)) (car (list a b)) (cdr (list a b)) (car (cons a b)) (cdr (cons a b))
Functional Programming Features Functional Programming Features Functions Recursive Functions Higher-order Functions Anonymous Functions Closures Currying Pure Functional vs Destructive Operations
Functions (string-upcase "Guess my return value?") (list 6 7 8) (append (list 1 2 3) (4 5 6)) (defun hello-world () "An awesome hello, world" (format t "hello, world")) (defun foo (a b) (values a b)) (multiple-value-bind (a1 a2) (foo 1 2) (list a1 a2)) (defun bar (a &key b c) (+ a b c))
Recursive Functions Fibonacci sequence F n = F n 1 + F n 2 F 1 = 1, F 2 = 1 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,...
Recursive Functions Fibonacci sequence F n = F n 1 + F n 2 F 1 = 1, F 2 = 1 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,... (defun fib-ntl (n) (if (or (= n 1) (= n 2)) 1 (+ (fib-ntl (- n 1)) (fib-ntl (- n 2))))) Can we do better?
Recursive Functions Fibonacci sequence F n = F n 1 + F n 2 F 1 = 1, F 2 = 1 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144,... (defun fib-ntl (n) (if (or (= n 1) (= n 2)) 1 (+ (fib-ntl (- n 1)) (fib-ntl (- n 2))))) Can we do better? (defun fib (n &optional (F[n-1] 1) (F[n-2] 0)) (if (= n 1) F[n-1] (fib (1- n) (+ F[n-1] F[n-2]) F[n-1])))
Higher-order Functions (count-if # upper-case-p "Functional Programming With Common Lisp") (funcall # + 1 2 3) (apply # + (list 1 2 3)) (defun ex-1 (fn1 fn2 fn3) (or fn1 fn2 fn3)) ; Invoking returned function ; boundp, fboundp, setf, symbol-function (let ((* 3)) (* * *)) (defun ex-2 (fn &rest some-stuff) (apply fn some-stuff))
Anonymous Functions (lambda (parameters) body) (lambda (x) (* x 2)) ; invocation (funcall (lambda (x) (* x 2)) 3) ((lambda (x) (* x 2)) 3) ; usage (mapcar # (lambda (x) (* x 2)) (1 2 3))
Closures (let ((a 1)) (defun my-closure () a)) (let ((a 1)) (defun my-closure-1 () a) (setq a 7) (defun my-closure-2 () a)) (defun two-funs (x) (list (function (lambda () x)) (function (lambda (y) (setq x y))))) (setq funs (two-funs 6)) (funcall (car funs)) (funcall (cadr funs) 43) (funcall (car funs))
Currying
Currying Definition The technique of translating the evaluation of a function that takes multiple args (or a tuple) into a sequence of functions, each with a single argument. (defun curry (fn &rest args) (lambda (&rest more-args) (apply fn (append args more-args)))) (funcall (curry # + 3) 5) (+ 1 2 3 4 5) (funcall (curry (curry (curry (curry # + 1) 2) 3) 4)) (defun currying (fn lst) (if (null lst) (funcall fn) (currying (curry fn (car lst)) (cdr lst)))) (currying # + (1 2 3 4)) (setf (symbol-function power-of-ten) (curry # expt 10)) (power-of-ten 3)
Pure Functional vs Destructive Operations ; Pure functional code: (append (list 1 2) (list 3 4)) ; How does that work internally? Nondestructive Destructive -------------- ----------- SUBST NSUBST SUBST-IF NSUBST-IF APPEND NCONC BUTLAST NBUTLAST INTERSECTION NINTERSECTION UNION NUNION REVERSE NREVERSE REMOVE DELETE SUBSTITUTE NSUBSTITUTE SUBSTITUTE-IF NSUBSTITUTE-IF REMOVE-DUPLICATES DELETE-DUPLICATES
Destructive Operations What is a destructive operation and why would one want to use it?
Destructive Operations What is a destructive operation and why would one want to use it? Definition Operations that modify existing objects are called destructive. Two types of destructive operations in Lisp: For-side-effect operations Recycling operations Guess the type? (let ((v (cons a b))) (setf (car v) e) v) (nreverse (1 2 3 4)) One can separate the functional code from the rest.
Avoiding Dangerous Operations (defparameter *my-list* (list 1 2 3 4))
Avoiding Dangerous Operations (defparameter *my-list* (list 1 2 3 4)) (defun nil-nth (n l) "Set nth element of list to nil and return modified list. (setf (nth n l) nil) l)
Avoiding Dangerous Operations (defparameter *my-list* (list 1 2 3 4)) (defun nil-nth (n l) "Set nth element of list to nil and return modified list. (setf (nth n l) nil) l) (defun nil-nth (n l) "Return list with nth element set to nil." (if (zerop n) (cons nil (rest l)) (cons (car l) (nil-nth (1- n) (rest l)))))
Functional Processing of Sequences Functional Processing of Sequences Sequences Map Reduce Take Filter
Sequences
Sequences Definition Sequences are ordered collections of objects, called the elements of the sequence.
Map
Map Definition The mapping operation involves applying a function to successive sets of arguments in which one argument is obtained from each sequence. (map list # car ((1 a) (2 b) (3 c))) (mapcar # car ((1 a) (2 b) (3 c))) (map string # (lambda (x y) (char "01234567890ABCDEF" (mod (+ x y) 16))) (1 2 3 4) (10 9 8 7)) (map list # - (1 2 3 4)) (map string # (lambda (x) (if (oddp x) #\1 #\0)) (1 2 3 4))
Reduce
Reduce Definition reduce uses a binary operation, FUNCTION, to combine the elements of SEQUENCE bounded by START and END. (reduce # * (1 2 3 4 5)) (reduce # append ((1) (2)) :initial-value (i n i t)) (reduce # append ((1) (2)) :from-end t :initial-value (i n i t)) (reduce # - (1 2 3 4 1 3 5) :start 1 :end 5) (reduce # - (1 2 3 4) :from-end t) (reduce # + ()) (reduce # + (3)) (reduce # list (1 2 3 4)) (reduce # list (1 2 3 4) :from-end t) (reduce # list (1 2 3 4) :initial-value foo) (reduce # list (1 2 3 4) :from-end t :initial-value foo)
Take
Take Definition Search a sequence for an element that satisfies a test. If found - indicate with the return value. (find-if # oddp (1 2 3 4 5) :end 3 :from-end t) (position #\a "baobab" :from-end t) (position-if # oddp ((1) (2) (3) (4)) :start 1 :key # car) (position-if (complement # oddp) ((1) (2) (3) (4)) :start (search "dog" "it s a dog s life") (mismatch "abcd" "ABCDE" :test # char-equal)
Filter
Filter Definition Filter is a higher-order function that processes a sequence in some order to produce a new sequence containing exactly those elements of the original sequence for which a given predicate returns the boolean value true. (remove-if # oddp #(1 21 2 4 1 3 4 5)) (remove 4 (1 3 4 5 9)) (remove 4 (1 2 4 1 3 4 5) :count 1) (mapcan # (lambda (x) (and (numberp x) (list x))) (a 1 b c 3 4 d 5)) (remove 3 (1 2 4 1 3 4 5) :test # >) delete and delete-if are like remove and remove-if respectively, but they may modify the sequence. Possible side effect
The Powerful Macro System (setq a 1)
The Powerful Macro System (setq a 1) (resetq 1 a)
The Powerful Macro System (setq a 1) (resetq 1 a) (defmacro resetq (val var) (setq,var,val))
The Powerful Macro System (setq a 1) (resetq 1 a) (defmacro resetq (val var) (setq,var,val)) However, SETQ is more than that..
Yet Another SETQ - the List Resetter I (defun resetify1 1 (lst) (do ((result) (fst (first lst) (first lst)) (snd (second lst) (second lst))) ((null lst) (nreverse result)) (push snd result) (push fst result) (pop lst) (pop lst)))
Yet Another SETQ - the List Resetter II (defun resetify2 (lst &optional result) (if (null lst) result (resetify2 (cddr lst) (append result (list (second lst) (first lst))))))
Yet Another SETQ - the Macro (defmacro resetq (&body args) (setq,@(resetify args)))
Yet Another SETQ - Local Function (defmacro resetq (&body args) (labels ((resetify (lst &optional result) (print "ran") (if (null lst) result (resetify (cddr lst) (append result (list (second lst) (first lst))))))) (setq,@(resetify args))))
Summary Functional Programming Lisp
Becoming a Lisp Hacker Play Read & Discuss Web Site: http://cliki.net Newsgroup: comp.lang.lisp IRC channel: #lisp
The End Further Questions?
Acknowledgments To those who gave us Lisp, its libraries and tools The Common Lisp HyperSpec by Kent M. Pitman Practical Common Lisp - Peter Seibel On Lisp - Paul Graham The Common Lisp Cookbook Project Let Over Lambda by Doug Hoyte Successful Lisp by David B. Lamkins Wikipedia, Linux, Emacs, Texinfo, Beamer, etc.