100 likes | 130 Views
Functional Programming. “When I code in C, I feel I'm on a knife-edge of ‘state’ — I focus on statements and what they do. I'm worried about the behaviour of a machine.” - Richard A. O'Keefe. What is Functional Programming?. Programs work by returning values instead of modifying data
E N D
Functional Programming “When I code in C, I feel I'm on a knife-edge of ‘state’ — I focus on statements and what they do. I'm worried about the behaviour of a machine.” - Richard A. O'Keefe
What is Functional Programming? • Programs work by returning values instead of modifying data • Side-effect free • No variables, no destructive modification of data, no state • LISP is a functional programming language, but it is not pure; it has many imperative features
A Programming Discipline • A description of functional programming reads as a list of things I can’t do! • By restricting code to stateless computations, you make it impossible for certain types of errors to occur • Functional programming methodology will make you a better imperative programmer (Java, C++) • For those times when you absolutely can’t do without state, LISP lets you cheat (I’m about to show you how) • Don’t cheat if you don’t have to
Local Bindings: Variables? (let ((name value)*) body) • Assigns values to names in parallel >(let ((a 5) (b 25)) (+ a b)) 30 • Names with no value default to nil >(let (x y (z 6)) (cons x (cons y z))) (NIL NIL . 6)
Let • Saves you from repeating code/computation (defun profit (volume unit-price unit-cost tax-rate) (let ((revenue (* unit-price volume)) (overhead (* unit-cost volume))) (- revenue (+ overhead (* tax-rate revenue))) )) • Using functional programming style, you should think of these values as immutable (only assigned once) • We’ll learn the truth in a moment…
Let* • The following code has an error: >(let ((a 5) (b (+ a 10))) (* a b)) Error: The variable A is unbound. • Because assignments are in parallel, names in a single let don’t have access to other names in the same let • let* fixes this; it assigns serially: >(let* ((a 5) (b (+ a 10))) (* a b)) 75
Global Bindings • Constants and variables • Global constants cannot have their values changed (defconstant symbol S-expression string-comment) • Global variables can have their values changed, therefore I recommend never using them (defvar symbol S-expression string-comment) • defvar is used to assign an initial value only, not to change a variable value
Boundp • boundp determines if a given name is already assigned >(boundp 'pi) T >(boundp 'Jacob) NIL
Changing State With Setf • This is how you change the value of a variable (setf place value) • The place must be preexisting • Defined using defvar • Defined locally in a let • Place can even be a specific reference in a list, or other structure >(defvar h '(4 5 6 7 8 9)) H >(setf (caddr h) 'NEW) NEW >h (4 5 NEW 7 8 9)
Final Words on Variables • setf is an imperative feature • It’s what you’re used to, so you’ll feel tempted to use it • Go outside your comfort zone: • Every time you feel like using variables, ask yourself if it’s really necessary • Sometimes it is (homework assignments will usually make this clear)