INF4820 Algorithms for AI and NLP Common Lisp Essentials Erik - - PowerPoint PPT Presentation

inf4820 algorithms for ai and nlp common lisp essentials
SMART_READER_LITE
LIVE PREVIEW

INF4820 Algorithms for AI and NLP Common Lisp Essentials Erik - - PowerPoint PPT Presentation

INF4820 Algorithms for AI and NLP Common Lisp Essentials Erik Velldal & Stephan Oepen Language Technology Group (LTG) August 26, 2015 Topic of the day Lisp 2 Lisp Conceived in the late 1950s by John McCarthy one of the


slide-1
SLIDE 1 — INF4820 — Algorithms for AI and NLP Common Lisp Essentials Erik Velldal & Stephan Oepen Language Technology Group (LTG) August 26, 2015
slide-2
SLIDE 2 Topic of the day

Lisp

2
slide-3
SLIDE 3 Lisp ◮ Conceived in the late 1950s by John McCarthy – one of the founding fathers of AI. ◮ Originally intended as a mathematical formalism. ◮ A family of high-level languages. ◮ Several dialects, e.g. Scheme, Clojure, Emacs Lisp, and Common Lisp. ◮ Although a multi-paradigm language, functional style prevalent. 3
slide-4
SLIDE 4 Basic common lisp in a couple of minutes ◮ Testing a few expressions at the REPL; ◮ the read–eval–print loop. ◮ (= the interactive Lisp-environment) ◮ ‘?’ represents the REPL prompt and ‘→’ what an expression evaluates to. Examples 4
slide-5
SLIDE 5 Basic common lisp in a couple of minutes ◮ Testing a few expressions at the REPL; ◮ the read–eval–print loop. ◮ (= the interactive Lisp-environment) ◮ ‘?’ represents the REPL prompt and ‘→’ what an expression evaluates to. ◮ Atomic data types like numbers, booleans, and strings are self evaluating. Examples 4
slide-6
SLIDE 6 Basic common lisp in a couple of minutes ◮ Testing a few expressions at the REPL; ◮ the read–eval–print loop. ◮ (= the interactive Lisp-environment) ◮ ‘?’ represents the REPL prompt and ‘→’ what an expression evaluates to. ◮ Atomic data types like numbers, booleans, and strings are self evaluating. Examples ? "this is a string" → "this is a string" 4
slide-7
SLIDE 7 Basic common lisp in a couple of minutes ◮ Testing a few expressions at the REPL; ◮ the read–eval–print loop. ◮ (= the interactive Lisp-environment) ◮ ‘?’ represents the REPL prompt and ‘→’ what an expression evaluates to. ◮ Atomic data types like numbers, booleans, and strings are self evaluating. Examples ? "this is a string" → "this is a string" ? 42 → 42 4
slide-8
SLIDE 8 Basic common lisp in a couple of minutes ◮ Testing a few expressions at the REPL; ◮ the read–eval–print loop. ◮ (= the interactive Lisp-environment) ◮ ‘?’ represents the REPL prompt and ‘→’ what an expression evaluates to. ◮ Atomic data types like numbers, booleans, and strings are self evaluating. Examples ? "this is a string" → "this is a string" ? 42 → 42 ? t → t 4
slide-9
SLIDE 9 Basic common lisp in a couple of minutes ◮ Testing a few expressions at the REPL; ◮ the read–eval–print loop. ◮ (= the interactive Lisp-environment) ◮ ‘?’ represents the REPL prompt and ‘→’ what an expression evaluates to. ◮ Atomic data types like numbers, booleans, and strings are self evaluating. Examples ? "this is a string" → "this is a string" ? 42 → 42 ? t → t ? nil → nil 4
slide-10
SLIDE 10 Basic common lisp in a couple of minutes ◮ Testing a few expressions at the REPL; ◮ the read–eval–print loop. ◮ (= the interactive Lisp-environment) ◮ ‘?’ represents the REPL prompt and ‘→’ what an expression evaluates to. ◮ Atomic data types like numbers, booleans, and strings are self evaluating. ◮ Symbols evaluate to whatever value they are bound to. Examples ? "this is a string" → "this is a string" ? 42 → 42 ? t → t ? nil → nil 4
slide-11
SLIDE 11 Basic common lisp in a couple of minutes ◮ Testing a few expressions at the REPL; ◮ the read–eval–print loop. ◮ (= the interactive Lisp-environment) ◮ ‘?’ represents the REPL prompt and ‘→’ what an expression evaluates to. ◮ Atomic data types like numbers, booleans, and strings are self evaluating. ◮ Symbols evaluate to whatever value they are bound to. Examples ? "this is a string" → "this is a string" ? 42 → 42 ? t → t ? nil → nil ? pi → 3.141592653589793d0 4
slide-12
SLIDE 12 Basic common lisp in a couple of minutes ◮ Testing a few expressions at the REPL; ◮ the read–eval–print loop. ◮ (= the interactive Lisp-environment) ◮ ‘?’ represents the REPL prompt and ‘→’ what an expression evaluates to. ◮ Atomic data types like numbers, booleans, and strings are self evaluating. ◮ Symbols evaluate to whatever value they are bound to. Examples ? "this is a string" → "this is a string" ? 42 → 42 ? t → t ? nil → nil ? pi → 3.141592653589793d0 ? foo → error; unbound 4
slide-13
SLIDE 13 A note on terminology ◮ Lisp manipulates so-called symbolic expressions. ◮ AKA s-expressions or sexps. ◮ Two fundamental types of sexps;
  • 1. atoms (e.g., nil, t, numbers, strings, symbols)
  • 2. lists containing other sexps.
◮ Sexps are used to represent both data and code. 5
slide-14
SLIDE 14 Function calls ◮ “Parenthesized prefix notation” ◮ First element (prefix) = operator (i.e. the procedure or function). ◮ The rest of the list is the operands (i.e. the arguments or parameters). ◮ Use nesting (of lists) to build compound expressions. ◮ Expressions can span multiple lines; indentation for readability. Examples ? (+ 1 2) → 3 6
slide-15
SLIDE 15 Function calls ◮ “Parenthesized prefix notation” ◮ First element (prefix) = operator (i.e. the procedure or function). ◮ The rest of the list is the operands (i.e. the arguments or parameters). ◮ Use nesting (of lists) to build compound expressions. ◮ Expressions can span multiple lines; indentation for readability. Examples ? (+ 1 2) → 3 ? (+ 1 2 10 7 5) → 25 6
slide-16
SLIDE 16 Function calls ◮ “Parenthesized prefix notation” ◮ First element (prefix) = operator (i.e. the procedure or function). ◮ The rest of the list is the operands (i.e. the arguments or parameters). ◮ Use nesting (of lists) to build compound expressions. ◮ Expressions can span multiple lines; indentation for readability. Examples ? (+ 1 2) → 3 ? (+ 1 2 10 7 5) → 25 ? (/ (+ 10 20) 2) → 15 6
slide-17
SLIDE 17 Function calls ◮ “Parenthesized prefix notation” ◮ First element (prefix) = operator (i.e. the procedure or function). ◮ The rest of the list is the operands (i.e. the arguments or parameters). ◮ Use nesting (of lists) to build compound expressions. ◮ Expressions can span multiple lines; indentation for readability. Examples ? (+ 1 2) → 3 ? (+ 1 2 10 7 5) → 25 ? (/ (+ 10 20) 2) → 15 ? (* (+ 42 58) (- (/ 8 2) 2)) → 200 6
slide-18
SLIDE 18 The syntax and semantics of CL ? (expt (- 8 4) 2) → 16 ◮ You now know (almost) all there is to know about the rules of CL. ◮ The first element of a list names a function that is invoked with the values of all remaining elements as its arguments. ◮ A few exceptions, called special forms, with their own evaluation rules. 7
slide-19
SLIDE 19 Creating our own functions ◮ The special form defun associates a function definition with a symbol: General form (defun name (parameter1 . . . parametern) body) 8
slide-20
SLIDE 20 Creating our own functions ◮ The special form defun associates a function definition with a symbol: General form (defun name (parameter1 . . . parametern) body) Example ? (defun average (x y) (/ (+ x y) 2)) 8
slide-21
SLIDE 21 Creating our own functions ◮ The special form defun associates a function definition with a symbol: General form (defun name (parameter1 . . . parametern) body) Example ? (defun average (x y) (/ (+ x y) 2)) ? (average 10 20) →15 8
slide-22
SLIDE 22 Some other special forms ◮ defparameter declares a ‘global variable’ and assigns a value: ? (defparameter *foo* 42) ? *foo* → 42 ◮ Conditional evaluation with if and cond: Examples ? (if (numberp *foo*) "number" "something else") → "number" General form (if predicate then clause else clause) 9
slide-23
SLIDE 23 Some other special forms ◮ defparameter declares a ‘global variable’ and assigns a value: ? (defparameter *foo* 42) ? *foo* → 42 ◮ Conditional evaluation with if and cond: Examples ? (if (numberp *foo*) "number" "something else") → "number" ? (cond ((< *foo* 3) "less") ((> *foo* 3) "more") (t "equal")) → "more" General form (if predicate then clause else clause) (cond (predicate1 clause1) (predicate2 clause2) (predicatei clausei) (t default clause)) 9
slide-24
SLIDE 24 The ‘Hello World!’ of functional programming ◮ Classic example: the factorial function. n! =
  • 1
if n = 0 n × (n − 1)! if n > 0 10
slide-25
SLIDE 25 The ‘Hello World!’ of functional programming ◮ Classic example: the factorial function. ◮ A recursive procedure: calls itself, directly or indirectly. n! =
  • 1
if n = 0 n × (n − 1)! if n > 0 10
slide-26
SLIDE 26 The ‘Hello World!’ of functional programming ◮ Classic example: the factorial function. ◮ A recursive procedure: calls itself, directly or indirectly. n! =
  • 1
if n = 0 n × (n − 1)! if n > 0 (defun fac (n) (if (= n 0) 1 (* n (fac (- n 1))))) 10
slide-27
SLIDE 27 The ‘Hello World!’ of functional programming ◮ Classic example: the factorial function. ◮ A recursive procedure: calls itself, directly or indirectly. ◮ May seem circular, but is well-defined as long as there’s a base case terminating the recursion. n! =
  • 1
if n = 0 n × (n − 1)! if n > 0 (defun fac (n) (if (= n 0) 1 (* n (fac (- n 1))))) 10
slide-28
SLIDE 28 The ‘Hello World!’ of functional programming ◮ Classic example: the factorial function. ◮ A recursive procedure: calls itself, directly or indirectly. ◮ May seem circular, but is well-defined as long as there’s a base case terminating the recursion. ◮ For comparison: a non-recursive implementation (in Python). n! =
  • 1
if n = 0 n × (n − 1)! if n > 0 (defun fac (n) (if (= n 0) 1 (* n (fac (- n 1))))) def fac(n): r = 1 while (n > 0): r = r * n n = n - 1 return r 10
slide-29
SLIDE 29 A special case of recursion: Tail recursion ◮ A more efficient way to define n! recursively. ◮ Use a helper procedure with an accumulator variable to collect the product along the way. (defun fac (n) (fac-iter 1 1 n)) (defun fac-iter (prod count n) (if (> count n) prod (fac-iter (* count prod) (+ count 1) n))) 11
slide-30
SLIDE 30 A special case of recursion: Tail recursion ◮ A more efficient way to define n! recursively. ◮ Use a helper procedure with an accumulator variable to collect the product along the way. (defun fac (n) (fac-iter 1 1 n)) (defun fac-iter (prod count n) (if (> count n) prod (fac-iter (* count prod) (+ count 1) n))) 11
slide-31
SLIDE 31 A special case of recursion: Tail recursion ◮ A more efficient way to define n! recursively. ◮ Use a helper procedure with an accumulator variable to collect the product along the way. ◮ The recursive call is in tail position: (defun fac (n) (fac-iter 1 1 n)) (defun fac-iter (prod count n) (if (> count n) prod (fac-iter (* count prod) (+ count 1) n))) ◮ no work remains to be done in the calling function. ◮ Once we reach the base case, the return value is ready. 11
slide-32
SLIDE 32 A special case of recursion: Tail recursion ◮ A more efficient way to define n! recursively. ◮ Use a helper procedure with an accumulator variable to collect the product along the way. ◮ The recursive call is in tail position: (defun fac (n) (fac-iter 1 1 n)) (defun fac-iter (prod count n) (if (> count n) prod (fac-iter (* count prod) (+ count 1) n))) ◮ no work remains to be done in the calling function. ◮ Once we reach the base case, the return value is ready. ◮ Most CL compilers do tail call optimization, so that the recursion is executed as an iterative loop. 11
slide-33
SLIDE 33 A special case of recursion: Tail recursion ◮ A more efficient way to define n! recursively. ◮ Use a helper procedure with an accumulator variable to collect the product along the way. ◮ The recursive call is in tail position: (defun fac (n) (fac-iter 1 1 n)) (defun fac-iter (prod count n) (if (> count n) prod (fac-iter (* count prod) (+ count 1) n))) ◮ no work remains to be done in the calling function. ◮ Once we reach the base case, the return value is ready. ◮ Most CL compilers do tail call optimization, so that the recursion is executed as an iterative loop. ◮ (The next lecture will cover CL’s built-in loop construct.) 11
slide-34
SLIDE 34 Tracing the processes Recursive (defun fac (n) (if (= n 0) 1 (* n (fac (- n 1))))) ? (fac 7) ⇒ (* 7 (fac 6)) ⇒ (* 7 (* 6 (fac 5))) ⇒ (* 7 (* 6 (* 5 (fac 4)))) ⇒ (* 7 (* 6 (* 5 (* 4 (fac 3))))) ⇒ (* 7 (* 6 (* 5 (* 4 (* 3 (fac 2)))))) ⇒ (* 7 (* 6 (* 5 (* 4 (* 3 (* 2 (fac 1))))))) ⇒ (* 7 (* 6 (* 5 (* 4 (* 3 (* 2 1)))))) ⇒ (* 7 (* 6 (* 5 (* 4 (* 3 2))))) ⇒ (* 7 (* 6 (* 5 (* 4 6)))) ⇒ (* 7 (* 6 (* 5 24))) ⇒ (* 7 (* 6 120)) ⇒ (* 7 720) → 5040 Iterative (tail recursive) (defun fac (n) (fac-iter 1 1 n)) (defun fac-iter (prod count n) (if (> count n) prod (fac-iter (* count prod) (+ count 1) n))) ? (fac 7) ⇒ (fac-iter 1 1 7) ⇒ (fac-iter 1 2 7) ⇒ (fac-iter 2 3 7) ⇒ (fac-iter 6 4 7) ⇒ (fac-iter 24 5 7) ⇒ (fac-iter 120 6 7) ⇒ (fac-iter 720 7 7) ⇒ (fac-iter 5040 8 7) → 5040 12
slide-35
SLIDE 35 Tracing the processes Recursive (defun fac (n) (if (= n 0) 1 (* n (fac (- n 1))))) ? (fac 7) ⇒ (* 7 (fac 6)) ⇒ (* 7 (* 6 (fac 5))) ⇒ (* 7 (* 6 (* 5 (fac 4)))) ⇒ (* 7 (* 6 (* 5 (* 4 (fac 3))))) ⇒ (* 7 (* 6 (* 5 (* 4 (* 3 (fac 2)))))) ⇒ (* 7 (* 6 (* 5 (* 4 (* 3 (* 2 (fac 1))))))) ⇒ (* 7 (* 6 (* 5 (* 4 (* 3 (* 2 1)))))) ⇒ (* 7 (* 6 (* 5 (* 4 (* 3 2))))) ⇒ (* 7 (* 6 (* 5 (* 4 6)))) ⇒ (* 7 (* 6 (* 5 24))) ⇒ (* 7 (* 6 120)) ⇒ (* 7 720) → 5040 Iterative (tail recursive) (defun fac (n) (fac-iter 1 1 n)) (defun fac-iter (prod count n) (if (> count n) prod (fac-iter (* count prod) (+ count 1) n))) ? (fac 7) ⇒ (fac-iter 1 1 7) ⇒ (fac-iter 1 2 7) ⇒ (fac-iter 2 3 7) ⇒ (fac-iter 6 4 7) ⇒ (fac-iter 24 5 7) ⇒ (fac-iter 120 6 7) ⇒ (fac-iter 720 7 7) ⇒ (fac-iter 5040 8 7) → 5040 12
slide-36
SLIDE 36 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. 13
slide-37
SLIDE 37 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 13
slide-38
SLIDE 38 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 ? (quote pi) → pi 13
slide-39
SLIDE 39 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 ? (quote pi) → pi ? 'pi → pi 13
slide-40
SLIDE 40 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 ? (quote pi) → pi ? 'pi → pi ? foobar → error; unbound variable 13
slide-41
SLIDE 41 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 ? (quote pi) → pi ? 'pi → pi ? foobar → error; unbound variable ? 'foobar → foobar 13
slide-42
SLIDE 42 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 ? (quote pi) → pi ? 'pi → pi ? foobar → error; unbound variable ? 'foobar → foobar ? (* 2 pi) → 6.283185307179586d0 13
slide-43
SLIDE 43 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 ? (quote pi) → pi ? 'pi → pi ? foobar → error; unbound variable ? 'foobar → foobar ? (* 2 pi) → 6.283185307179586d0 ? '(* 2 pi) → 13
slide-44
SLIDE 44 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 ? (quote pi) → pi ? 'pi → pi ? foobar → error; unbound variable ? 'foobar → foobar ? (* 2 pi) → 6.283185307179586d0 ? '(* 2 pi) → (* 2 pi) 13
slide-45
SLIDE 45 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 ? (quote pi) → pi ? 'pi → pi ? foobar → error; unbound variable ? 'foobar → foobar ? (* 2 pi) → 6.283185307179586d0 ? '(* 2 pi) → (* 2 pi) ? () → 13
slide-46
SLIDE 46 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 ? (quote pi) → pi ? 'pi → pi ? foobar → error; unbound variable ? 'foobar → foobar ? (* 2 pi) → 6.283185307179586d0 ? '(* 2 pi) → (* 2 pi) ? () → error; missing procedure 13
slide-47
SLIDE 47 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 ? (quote pi) → pi ? 'pi → pi ? foobar → error; unbound variable ? 'foobar → foobar ? (* 2 pi) → 6.283185307179586d0 ? '(* 2 pi) → (* 2 pi) ? () → error; missing procedure ? '() → 13
slide-48
SLIDE 48 The quote operator ◮ A special form making expressions self-evaluating. ◮ The quote operator (or simply ‘'’) suppresses evaluation. ? pi→ 3.141592653589793d0 ? (quote pi) → pi ? 'pi → pi ? foobar → error; unbound variable ? 'foobar → foobar ? (* 2 pi) → 6.283185307179586d0 ? '(* 2 pi) → (* 2 pi) ? () → error; missing procedure ? '() → () 13
slide-49
SLIDE 49 Both code and data are s-expressions ◮ We’ve mentioned how sexps are used to represent both data and code. ◮ Note the double role of lists: ◮ Lists are function calls; ? (* 10 (+ 2 3)) → 50 ? (bar 1 2) → error; function bar undefined 14
slide-50
SLIDE 50 Both code and data are s-expressions ◮ We’ve mentioned how sexps are used to represent both data and code. ◮ Note the double role of lists: ◮ Lists are function calls; ? (* 10 (+ 2 3)) → 50 ? (bar 1 2) → error; function bar undefined ◮ But, lists can also be data; ? '(foo bar) → (foo bar) ? (list 'foo 'bar) → (foo bar) 14
slide-51
SLIDE 51 Break http://xkcd.com/297/ Eric Raymond, How to Become a Hacker, 2001: 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 should never actually use Lisp itself a lot. 15
slide-52
SLIDE 52 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) 16
slide-53
SLIDE 53 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → 16
slide-54
SLIDE 54 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) 16
slide-55
SLIDE 55 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 16
slide-56
SLIDE 56 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) 16
slide-57
SLIDE 57 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) ? (first (rest '(1 2 3))) → 16
slide-58
SLIDE 58 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) ? (first (rest '(1 2 3))) → 2 16
slide-59
SLIDE 59 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) ? (first (rest '(1 2 3))) → 2 ? (rest (rest (rest '(1 2 3)))) → 16
slide-60
SLIDE 60 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) ? (first (rest '(1 2 3))) → 2 ? (rest (rest (rest '(1 2 3)))) → nil 16
slide-61
SLIDE 61 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) ? (first (rest '(1 2 3))) → 2 ? (rest (rest (rest '(1 2 3)))) → nil ◮ Many additional list operations (derivable from the above), e.g. ? (list 1 2 3) → (1 2 3) 16
slide-62
SLIDE 62 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) ? (first (rest '(1 2 3))) → 2 ? (rest (rest (rest '(1 2 3)))) → nil ◮ Many additional list operations (derivable from the above), e.g. ? (list 1 2 3) → (1 2 3) ? (append '(1 2) '(3) '(4 5 6)) → (1 2 3 4 5 6) 16
slide-63
SLIDE 63 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) ? (first (rest '(1 2 3))) → 2 ? (rest (rest (rest '(1 2 3)))) → nil ◮ Many additional list operations (derivable from the above), e.g. ? (list 1 2 3) → (1 2 3) ? (append '(1 2) '(3) '(4 5 6)) → (1 2 3 4 5 6) ? (length '(1 2 3)) → 3 16
slide-64
SLIDE 64 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) ? (first (rest '(1 2 3))) → 2 ? (rest (rest (rest '(1 2 3)))) → nil ◮ Many additional list operations (derivable from the above), e.g. ? (list 1 2 3) → (1 2 3) ? (append '(1 2) '(3) '(4 5 6)) → (1 2 3 4 5 6) ? (length '(1 2 3)) → 3 ? (reverse '(1 2 3)) → (3 2 1) 16
slide-65
SLIDE 65 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) ? (first (rest '(1 2 3))) → 2 ? (rest (rest (rest '(1 2 3)))) → nil ◮ Many additional list operations (derivable from the above), e.g. ? (list 1 2 3) → (1 2 3) ? (append '(1 2) '(3) '(4 5 6)) → (1 2 3 4 5 6) ? (length '(1 2 3)) → 3 ? (reverse '(1 2 3)) → (3 2 1) ? (nth 2 '(1 2 3)) → 3 16
slide-66
SLIDE 66 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) ? (first (rest '(1 2 3))) → 2 ? (rest (rest (rest '(1 2 3)))) → nil ◮ Many additional list operations (derivable from the above), e.g. ? (list 1 2 3) → (1 2 3) ? (append '(1 2) '(3) '(4 5 6)) → (1 2 3 4 5 6) ? (length '(1 2 3)) → 3 ? (reverse '(1 2 3)) → (3 2 1) ? (nth 2 '(1 2 3)) → 3 ? (last '(1 2 3)) → (3) 16
slide-67
SLIDE 67 LISP = LISt Processing ◮ cons builds up new lists; first and rest destructure them. ? (cons 1 (cons 2 (cons 3 nil))) → (1 2 3) ? (cons 0 '(1 2 3)) → (0 1 2 3) ? (first '(1 2 3)) → 1 ? (rest '(1 2 3)) → (2 3) ? (first (rest '(1 2 3))) → 2 ? (rest (rest (rest '(1 2 3)))) → nil ◮ Many additional list operations (derivable from the above), e.g. ? (list 1 2 3) → (1 2 3) ? (append '(1 2) '(3) '(4 5 6)) → (1 2 3 4 5 6) ? (length '(1 2 3)) → 3 ? (reverse '(1 2 3)) → (3 2 1) ? (nth 2 '(1 2 3)) → 3 ? (last '(1 2 3)) → (3) Wait, why not 3? 16
slide-68
SLIDE 68 Lists are really chained ‘cons cells’ (1 2 3)
❅ ❅ ❅ ❘ 1
❅ ❅ ❅ ❘ 2
❅ ❅ ❅ ❘ 3 nil (cons 1 (cons 2 (cons 3 nil))) 17
slide-69
SLIDE 69 Lists are really chained ‘cons cells’ (1 2 3) ((1 2) 3)
❅ ❅ ❅ ❘ 1
❅ ❅ ❅ ❘ 2
❅ ❅ ❅ ❘ 3 nil
❅ ❅ ❅ ❘
1 ✁ ✁ ✁ ☛ ❅ ❅ ❅ ❘ 3 nil
❅ ❅ ❅ ❘ 2 nil (cons 1 (cons 2 (cons 3 nil))) (cons (cons 1 (cons 2 nil)) (cons 3 nil)) 17
slide-70
SLIDE 70 Assigning values: ‘Generalized variables’ ◮ setf provides a uniform way of assigning values to variables. 18
slide-71
SLIDE 71 Assigning values: ‘Generalized variables’ ◮ setf provides a uniform way of assigning values to variables. ◮ General form: (setf place value) ◮ . . . where place can either be a variable named by a symbol or some
  • ther storage location:
18
slide-72
SLIDE 72 Assigning values: ‘Generalized variables’ ◮ setf provides a uniform way of assigning values to variables. ◮ General form: (setf place value) ◮ . . . where place can either be a variable named by a symbol or some
  • ther storage location:
? (defparameter *foo* 42) 18
slide-73
SLIDE 73 Assigning values: ‘Generalized variables’ ◮ setf provides a uniform way of assigning values to variables. ◮ General form: (setf place value) ◮ . . . where place can either be a variable named by a symbol or some
  • ther storage location:
? (defparameter *foo* 42) ? (setf *foo* (+ *foo* 1)) 18
slide-74
SLIDE 74 Assigning values: ‘Generalized variables’ ◮ setf provides a uniform way of assigning values to variables. ◮ General form: (setf place value) ◮ . . . where place can either be a variable named by a symbol or some
  • ther storage location:
? (defparameter *foo* 42) ? (setf *foo* (+ *foo* 1)) ? *foo* → 43 18
slide-75
SLIDE 75 Assigning values: ‘Generalized variables’ ◮ setf provides a uniform way of assigning values to variables. ◮ General form: (setf place value) ◮ . . . where place can either be a variable named by a symbol or some
  • ther storage location:
? (defparameter *foo* 42) ? (setf *foo* (+ *foo* 1)) ? *foo* → 43 ? (setf *foo* '(2 2 3)) 18
slide-76
SLIDE 76 Assigning values: ‘Generalized variables’ ◮ setf provides a uniform way of assigning values to variables. ◮ General form: (setf place value) ◮ . . . where place can either be a variable named by a symbol or some
  • ther storage location:
? (defparameter *foo* 42) ? (setf *foo* (+ *foo* 1)) ? *foo* → 43 ? (setf *foo* '(2 2 3)) ? (setf (first *foo*) 1) 18
slide-77
SLIDE 77 Assigning values: ‘Generalized variables’ ◮ setf provides a uniform way of assigning values to variables. ◮ General form: (setf place value) ◮ . . . where place can either be a variable named by a symbol or some
  • ther storage location:
? (defparameter *foo* 42) ? (setf *foo* (+ *foo* 1)) ? *foo* → 43 ? (setf *foo* '(2 2 3)) ? (setf (first *foo*) 1) ? *foo* → (1 2 3) 18
slide-78
SLIDE 78 Some other macros for assignment Example Type of x Effect (incf x y) number (setf x (+ x y)) (incf x) number (incf x 1) (decf x y) number (setf x (- x y)) (decf x) number (decf x 1) (push y x) list (setf x (cons y x)) (pop x) list (let ((y (first x))) (setf x (rest x)) y) (pushnew y x) list (if (member y x) x (push y x)) 19
slide-79
SLIDE 79 Local variables ◮ Sometimes we want to store intermediate results. ◮ let and let* create temporary value bindings for symbols. ? (defparameter *foo* 42) ? (defparameter *bar* 100) ? (let ((*bar* 7) (baz 1)) (+ baz *bar* *foo*)) → 20
slide-80
SLIDE 80 Local variables ◮ Sometimes we want to store intermediate results. ◮ let and let* create temporary value bindings for symbols. ? (defparameter *foo* 42) ? (defparameter *bar* 100) ? (let ((*bar* 7) (baz 1)) (+ baz *bar* *foo*)) → 50 20
slide-81
SLIDE 81 Local variables ◮ Sometimes we want to store intermediate results. ◮ let and let* create temporary value bindings for symbols. ? (defparameter *foo* 42) ? (defparameter *bar* 100) ? (let ((*bar* 7) (baz 1)) (+ baz *bar* *foo*)) → 50 ? *bar* → 20
slide-82
SLIDE 82 Local variables ◮ Sometimes we want to store intermediate results. ◮ let and let* create temporary value bindings for symbols. ? (defparameter *foo* 42) ? (defparameter *bar* 100) ? (let ((*bar* 7) (baz 1)) (+ baz *bar* *foo*)) → 50 ? *bar* → 100 20
slide-83
SLIDE 83 Local variables ◮ Sometimes we want to store intermediate results. ◮ let and let* create temporary value bindings for symbols. ? (defparameter *foo* 42) ? (defparameter *bar* 100) ? (let ((*bar* 7) (baz 1)) (+ baz *bar* *foo*)) → 50 ? *bar* → 100 ? baz → 20
slide-84
SLIDE 84 Local variables ◮ Sometimes we want to store intermediate results. ◮ let and let* create temporary value bindings for symbols. ? (defparameter *foo* 42) ? (defparameter *bar* 100) ? (let ((*bar* 7) (baz 1)) (+ baz *bar* *foo*)) → 50 ? *bar* → 100 ? baz → error; unbound variable 20
slide-85
SLIDE 85 Local variables ◮ Sometimes we want to store intermediate results. ◮ let and let* create temporary value bindings for symbols. ? (defparameter *foo* 42) ? (defparameter *bar* 100) ? (let ((*bar* 7) (baz 1)) (+ baz *bar* *foo*)) → 50 ? *bar* → 100 ? baz → error; unbound variable ◮ Bindings valid only in the body of let. ◮ Previously existing bindings are shadowed within the lexical scope. 20
slide-86
SLIDE 86 Local variables ◮ Sometimes we want to store intermediate results. ◮ let and let* create temporary value bindings for symbols. ? (defparameter *foo* 42) ? (defparameter *bar* 100) ? (let ((*bar* 7) (baz 1)) (+ baz *bar* *foo*)) → 50 ? *bar* → 100 ? baz → error; unbound variable ◮ Bindings valid only in the body of let. ◮ Previously existing bindings are shadowed within the lexical scope. ◮ let* is like let but binds sequentially. 20
slide-87
SLIDE 87 Predicates ◮ A predicate tests some condition. ◮ Evaluates to a boolean truth value: ◮ nil (the empty list) means false. ◮ Anything non-nil (including t) means true. ? (listp ’(1 2 3)) → t ? (null (rest ’(1 2 3))) → nil ? (evenp 2) → t ? (defparameter foo 42) ? (or (not (numberp foo)) (and (>= foo 0) (<= foo 42))) → t ◮ Plethora of equality tests: eq, eql, equal, and equalp. 21
slide-88
SLIDE 88 Equality for one and all ◮ eq tests object identity; it is not useful for numbers or characters. ◮ eql is like eq, but well-defined on numbers and characters. ◮ equal tests structural equivalence ◮ equalp is like equal but insensitive to case and numeric type. 22
slide-89
SLIDE 89 Equality for one and all ◮ eq tests object identity; it is not useful for numbers or characters. ◮ eql is like eq, but well-defined on numbers and characters. ◮ equal tests structural equivalence ◮ equalp is like equal but insensitive to case and numeric type. ? (eq (list 1 2 3) ’(1 2 3)) → nil 22
slide-90
SLIDE 90 Equality for one and all ◮ eq tests object identity; it is not useful for numbers or characters. ◮ eql is like eq, but well-defined on numbers and characters. ◮ equal tests structural equivalence ◮ equalp is like equal but insensitive to case and numeric type. ? (eq (list 1 2 3) ’(1 2 3)) → nil ? (equal (list 1 2 3) ’(1 2 3)) → t 22
slide-91
SLIDE 91 Equality for one and all ◮ eq tests object identity; it is not useful for numbers or characters. ◮ eql is like eq, but well-defined on numbers and characters. ◮ equal tests structural equivalence ◮ equalp is like equal but insensitive to case and numeric type. ? (eq (list 1 2 3) ’(1 2 3)) → nil ? (equal (list 1 2 3) ’(1 2 3)) → t ? (eq 42 42) → ? [implementation-dependent] 22
slide-92
SLIDE 92 Equality for one and all ◮ eq tests object identity; it is not useful for numbers or characters. ◮ eql is like eq, but well-defined on numbers and characters. ◮ equal tests structural equivalence ◮ equalp is like equal but insensitive to case and numeric type. ? (eq (list 1 2 3) ’(1 2 3)) → nil ? (equal (list 1 2 3) ’(1 2 3)) → t ? (eq 42 42) → ? [implementation-dependent] ? (eql 42 42) → t 22
slide-93
SLIDE 93 Equality for one and all ◮ eq tests object identity; it is not useful for numbers or characters. ◮ eql is like eq, but well-defined on numbers and characters. ◮ equal tests structural equivalence ◮ equalp is like equal but insensitive to case and numeric type. ? (eq (list 1 2 3) ’(1 2 3)) → nil ? (equal (list 1 2 3) ’(1 2 3)) → t ? (eq 42 42) → ? [implementation-dependent] ? (eql 42 42) → t ? (eql 42 42.0) → nil 22
slide-94
SLIDE 94 Equality for one and all ◮ eq tests object identity; it is not useful for numbers or characters. ◮ eql is like eq, but well-defined on numbers and characters. ◮ equal tests structural equivalence ◮ equalp is like equal but insensitive to case and numeric type. ? (eq (list 1 2 3) ’(1 2 3)) → nil ? (equal (list 1 2 3) ’(1 2 3)) → t ? (eq 42 42) → ? [implementation-dependent] ? (eql 42 42) → t ? (eql 42 42.0) → nil ? (equalp 42 42.0) → t 22
slide-95
SLIDE 95 Equality for one and all ◮ eq tests object identity; it is not useful for numbers or characters. ◮ eql is like eq, but well-defined on numbers and characters. ◮ equal tests structural equivalence ◮ equalp is like equal but insensitive to case and numeric type. ? (eq (list 1 2 3) ’(1 2 3)) → nil ? (equal (list 1 2 3) ’(1 2 3)) → t ? (eq 42 42) → ? [implementation-dependent] ? (eql 42 42) → t ? (eql 42 42.0) → nil ? (equalp 42 42.0) → t ? (equal "foo" "foo") → t 22
slide-96
SLIDE 96 Equality for one and all ◮ eq tests object identity; it is not useful for numbers or characters. ◮ eql is like eq, but well-defined on numbers and characters. ◮ equal tests structural equivalence ◮ equalp is like equal but insensitive to case and numeric type. ? (eq (list 1 2 3) ’(1 2 3)) → nil ? (equal (list 1 2 3) ’(1 2 3)) → t ? (eq 42 42) → ? [implementation-dependent] ? (eql 42 42) → t ? (eql 42 42.0) → nil ? (equalp 42 42.0) → t ? (equal "foo" "foo") → t ? (equalp "FOO" "foo") → t 22
slide-97
SLIDE 97 Equality for one and all ◮ eq tests object identity; it is not useful for numbers or characters. ◮ eql is like eq, but well-defined on numbers and characters. ◮ equal tests structural equivalence ◮ equalp is like equal but insensitive to case and numeric type. ? (eq (list 1 2 3) ’(1 2 3)) → nil ? (equal (list 1 2 3) ’(1 2 3)) → t ? (eq 42 42) → ? [implementation-dependent] ? (eql 42 42) → t ? (eql 42 42.0) → nil ? (equalp 42 42.0) → t ? (equal "foo" "foo") → t ? (equalp "FOO" "foo") → t ◮ Also many type-specialized tests like =, string=, etc. 22
slide-98
SLIDE 98 Rewind: A note on symbol semantics ◮ Symbols can have values as functions and variables at the same time. ◮ #’ (sharp-quote) gives us the function object bound to a symbol. ? (defun foo (x) (* x 1000)) 23
slide-99
SLIDE 99 Rewind: A note on symbol semantics ◮ Symbols can have values as functions and variables at the same time. ◮ #’ (sharp-quote) gives us the function object bound to a symbol. ? (defun foo (x) (* x 1000)) ? (defparameter foo 42) → 2 23
slide-100
SLIDE 100 Rewind: A note on symbol semantics ◮ Symbols can have values as functions and variables at the same time. ◮ #’ (sharp-quote) gives us the function object bound to a symbol. ? (defun foo (x) (* x 1000)) ? (defparameter foo 42) → 2 ? (foo foo) → 23
slide-101
SLIDE 101 Rewind: A note on symbol semantics ◮ Symbols can have values as functions and variables at the same time. ◮ #’ (sharp-quote) gives us the function object bound to a symbol. ? (defun foo (x) (* x 1000)) ? (defparameter foo 42) → 2 ? (foo foo) → 42000 23
slide-102
SLIDE 102 Rewind: A note on symbol semantics ◮ Symbols can have values as functions and variables at the same time. ◮ #’ (sharp-quote) gives us the function object bound to a symbol. ? (defun foo (x) (* x 1000)) ? (defparameter foo 42) → 2 ? (foo foo) → 42000 ? foo → 42 23
slide-103
SLIDE 103 Rewind: A note on symbol semantics ◮ Symbols can have values as functions and variables at the same time. ◮ #’ (sharp-quote) gives us the function object bound to a symbol. ? (defun foo (x) (* x 1000)) ? (defparameter foo 42) → 2 ? (foo foo) → 42000 ? foo → 42 ? #’foo → #<Interpreted Function FOO> 23
slide-104
SLIDE 104 Rewind: A note on symbol semantics ◮ Symbols can have values as functions and variables at the same time. ◮ #’ (sharp-quote) gives us the function object bound to a symbol. ? (defun foo (x) (* x 1000)) ? (defparameter foo 42) → 2 ? (foo foo) → 42000 ? foo → 42 ? #’foo → #<Interpreted Function FOO> ? (funcall #’foo foo) → 42000 23
slide-105
SLIDE 105 Rewind: A note on symbol semantics ◮ Symbols can have values as functions and variables at the same time. ◮ #’ (sharp-quote) gives us the function object bound to a symbol. ? (defun foo (x) (* x 1000)) ? (defparameter foo 42) → 2 ? (foo foo) → 42000 ? foo → 42 ? #’foo → #<Interpreted Function FOO> ? (funcall #’foo foo) → 42000 ◮ #’ and funcall (as well as apply) are useful when passing around functions as arguments. 23
slide-106
SLIDE 106 Higher-order functions ◮ Functions that accept functions as arguments or return values. ◮ Functions in Lisp are first-class objects. ◮ Can be created at run-time, passed as arguments, returned as values, stored in variables. . . just like any other data type. 24
slide-107
SLIDE 107 Higher-order functions ◮ Functions that accept functions as arguments or return values. ◮ Functions in Lisp are first-class objects. ◮ Can be created at run-time, passed as arguments, returned as values, stored in variables. . . just like any other data type. ? (defun filter (list test) (cond ((null list) nil) ((funcall test (first list)) (cons (first list) (filter (rest list) test))) (t (filter (rest list) test)))) 24
slide-108
SLIDE 108 Higher-order functions ◮ Functions that accept functions as arguments or return values. ◮ Functions in Lisp are first-class objects. ◮ Can be created at run-time, passed as arguments, returned as values, stored in variables. . . just like any other data type. ? (defun filter (list test) (cond ((null list) nil) ((funcall test (first list)) (cons (first list) (filter (rest list) test))) (t (filter (rest list) test)))) 24
slide-109
SLIDE 109 Higher-order functions ◮ Functions that accept functions as arguments or return values. ◮ Functions in Lisp are first-class objects. ◮ Can be created at run-time, passed as arguments, returned as values, stored in variables. . . just like any other data type. ? (defun filter (list test) (cond ((null list) nil) ((funcall test (first list)) (cons (first list) (filter (rest list) test))) (t (filter (rest list) test)))) ? (defparameter foo '(11 22 33 44 55)) 24
slide-110
SLIDE 110 Higher-order functions ◮ Functions that accept functions as arguments or return values. ◮ Functions in Lisp are first-class objects. ◮ Can be created at run-time, passed as arguments, returned as values, stored in variables. . . just like any other data type. ? (defun filter (list test) (cond ((null list) nil) ((funcall test (first list)) (cons (first list) (filter (rest list) test))) (t (filter (rest list) test)))) ? (defparameter foo '(11 22 33 44 55)) ? (filter foo #'evenp) → (22 44) 24
slide-111
SLIDE 111 Anonymous functions ◮ We can also pass function arguments without first binding them to a name, using lambda expressions: (lambda (parameters) body) ◮ A function definition without the defun and symbol part. ? (filter foo #’(lambda (x) (and (> x 20) (< x 50)))) → (22 33 44) 25
slide-112
SLIDE 112 Anonymous functions ◮ We can also pass function arguments without first binding them to a name, using lambda expressions: (lambda (parameters) body) ◮ A function definition without the defun and symbol part. ? (filter foo #’(lambda (x) (and (> x 20) (< x 50)))) → (22 33 44) ◮ Typically used for ad-hoc functions that are only locally relevant and simple enough to be expressed inline. 25
slide-113
SLIDE 113 Anonymous functions ◮ We can also pass function arguments without first binding them to a name, using lambda expressions: (lambda (parameters) body) ◮ A function definition without the defun and symbol part. ? (filter foo #’(lambda (x) (and (> x 20) (< x 50)))) → (22 33 44) ◮ Typically used for ad-hoc functions that are only locally relevant and simple enough to be expressed inline. ◮ Or, when constructing functions as return values. 25
slide-114
SLIDE 114 Returning functions ◮ We have seen how to create anonymous functions using lambda and pass them as arguments. ◮ Now let’s combine that with a function that itself returns another function (which we then bind to a variable). 26
slide-115
SLIDE 115 Returning functions ◮ We have seen how to create anonymous functions using lambda and pass them as arguments. ◮ Now let’s combine that with a function that itself returns another function (which we then bind to a variable). ? (defparameter foo '(11 22 33 44 55)) ? (defun make-range-test (lower upper) #'(lambda (x) (and (> x lower) (< x upper)))) 26
slide-116
SLIDE 116 Returning functions ◮ We have seen how to create anonymous functions using lambda and pass them as arguments. ◮ Now let’s combine that with a function that itself returns another function (which we then bind to a variable). ? (defparameter foo '(11 22 33 44 55)) ? (defun make-range-test (lower upper) #'(lambda (x) (and (> x lower) (< x upper)))) ? (filter foo (make-range-test 10 30)) → (11 22) 26
slide-117
SLIDE 117 Programming in INF4820 ◮ In the IFI Linux environment, we have available Allegro Common Lisp, a commercial Lisp interpreter and compiler. ◮ We will provide a pre-configured, integrated setup with emacs and the SLIME Lisp interaction mode. ◮ Several open-source Lisp implementations exist, e.g. Clozure or SBCL; compatible with SLIME, so feel free to experiment (at some later point). ◮ First-time users, please spend some time studying basic keyboard commands, for example: C-h t and M-x doctor RET. ◮ See the getting started guide and emacs cheat sheet on the course page. ◮ Obligatory assignment 1 is out now, and due Wed. 9th Sept. ◮ See course page or just run ’svn update’. 27
slide-118
SLIDE 118 Next week More Common Lisp. ◮ More on argument lists (optional arguments, keywords, defaults). ◮ More data types: Hash-tables, a-lists, arrays, sequences, and structures ◮ More higher-order functions. ◮ Iteration (loop) and mapping. 28