```Lecture 3: Of Lists
and Slippery
Slopes
CS655: Programming Languages
David Evans
University of Virginia
http://www.cs.virginia.edu/~evans
25 Jan
CS 655: Lecture 3
1
• Language Features and the Inevitability
of Language Decay
• Lists
• Higher Order Procedures
25 Jan
CS 655: Lecture 3
2
Recap: Last Time
• Primitives
– Numerals, Booleans, Functions
• Means of Combination
– Application
– lambda for making procedures
– Special forms: if
• Means of Abstraction
– define for giving expressions names
25 Jan
CS 655: Lecture 3
3
What Else?
• We can probably write all possible
programs with just this (but no one has
proven it yet, Challenge #1)
• But, it will be easier to write and
understand them, and make them
perform efficiently if we have more stuff
in the language
• Another Means of Abstraction –
compound data
25 Jan
CS 655: Lecture 3
4
Lists
• LISP = LISt Processing
• Could we define pair functions using
Mini-Scheme?
(make-pair 3 4)
(first (make-pair 3 4))
(second (make-pair 3 4))
25 Jan
CS 655: Lecture 3
pair <3, 4>
3
4
5
Defining Pair
(define make-pair
(lambda (x) (lambda (y) (+ x (* 10000 y)))
(define (pair-first p)
(if (> p 10000) p
(pair-first (+ p -10000)))))
(define (pair-second p) (mod p 10000))
Only works for pair elements from 0 – 10000.
But could do something more complicated to make it
work for all numbers.
25 Jan
CS 655: Lecture 3
6
Too Painful...
Provide new Primitives
• We can always make particular
programs easier to write by adding
primitives to our language
• This is a very slippery slope!
– C++: spec is 680 pages, 223 unresolved
issues, 50 operators with 16 precedence
levels, etc.
25 Jan
CS 655: Lecture 3
7
The Slippery Slope
• Everything you add to a language
makes it harder to implement, harder to
programs in, harder to learn, more
expensive to buy manuals for, etc...
• Everything you add to a language
interacts with everything else in
complex and often unexpected ways
25 Jan
CS 655: Lecture 3
8
Java on the Slope
• Java in 1994: “Write once, run anywhere”
– Language spec and tutorial and HotJava
description: ~40 pages
• Java in 2001: “Write once, test everywhere”
– Java Standard (J2SE), Java Enterprise (J2EE),
Java Micro (J2ME),
PersonalJava, EmbeddedJava, JavaCard,
(all from Sun)
– J2EE Spec Book: 800 pages, 7 authors
– J2SE Language Spec: 544 pages
– AP Computer Science (transitioning to Java by
2003?) – needs 35 points to define Java subset
JavaPhone, JavaTV, etc.
25 Jan
CS 655: Lecture 3
9
Java is on
the slope
to crash!
25 Jan
CS 655: Lecture 3
(Duke suicide picture by Gary McGraw.)
10
Feature-itis
• Every possible new feature makes
some program better
• Every programmer will clamor for their
favorite feature
• There is no cure: Mistakes never go
away, they just get “deprecated”
25 Jan
CS 655: Lecture 3
11
Committees  Feature-itis
• Languages designed and/or evolved by
committees* and marketing
departments (not passionate creators)
quickly become morasses of complexity
* Unless the committee has at least 3 eventual
Turing award winners
Algol 60: Backus, McCarthy, Perlis
Algol 68: Dijkstra, Hoare, McCarthy, Wirth
25 Jan
CS 655: Lecture 3
12
“A final hint: listen carefully to what
language users say they really want,
until you have an understanding of
what they really want. Then find
some way of achieving the latter at a
small fraction of the cost of the
former.”
C. A. R. Hoare, Hints on Programming
Language Design, 1973.
25 Jan
CS 655: Lecture 3
13
So...
When programmers say they want
pairs, lists, binary trees, red-black
trees, hash tables, network
streams, 3D graphics, complex
numbers, etc. we should give them
a way to glue two values together.
25 Jan
CS 655: Lecture 3
14
Enough (for now) on language
complexity...
Next: how do we provide that glue
25 Jan
CS 655: Lecture 3
15
List Primitives in Scheme
cons: ,   List
(“construct”)
,   ( . )
Procedure that takes something of
any type, something of any type, and
returns something a List.
(cons 3 4)
(3 . 4)
(cons 3 (cons 4 5)
(3 . (4 . 5))
shown as (3 4 . 5)
25 Jan
CS 655: Lecture 3
16
cdr, cdr, sdr
• car – ( . )  
Takes a cons pair and returns the first element.
Contents of the Address part of the Register
• cdr – ( . )  
Takes a cons pair and returns the second element.
Contents of the Decrement part of the Register
• They sdr called cdr “tail”, and car, “head” but
historical names too entrenched in LISP to
change.
25 Jan
CS 655: Lecture 3
17
Examples
(car (cons 3 4))
3
(cdr (cons 3 4))
4
(cdr (cons 3 (cons 4 5)))
(4 . 5)
(car (cdr (cons 3 (cons 4 5))))
4
25 Jan
CS 655: Lecture 3
18
Lists
• ‘() is a special constant known as nil.
• We call zero or more cons’s ending
with ‘() a “List” (nil is a list).
(cons 3 ‘())
(3)
25 Jan
CS 655: Lecture 3
19
Creating Lists
• list is short for using a lot of cons’s
(list)
()
(list 1 2 3 4) = (cons 1 (cons 2 (cons 3 (cons 4 ‘())
(1 2 3 4)
• ‘ (quote) is even shorter (but has more
special meanings)
(quote (1 2 3))
‘(1 2 3)
25 Jan
(1 2 3)
(1 2 3)
CS 655: Lecture 3
20
Examples
(cdr (cons 3 4))
4
(cdr (list 3 4))
(4)
(cdr ‘(3 4))
(4)
(car ‘((3 4) (5 4 6) 7))
(3 4)
25 Jan
CS 655: Lecture 3
21
List Predicates: null?
null?:   boolean (not really a type in Scheme)
#f is applied to something that is not nil.
(null? (cdr (cons 3 4)))
#f
Scheme 7.5 gives (), means the same thing.
(null? (cdr (list 3)))
#t
25 Jan
CS 655: Lecture 3
22
List Predicates: list?
list?:   boolean
#f if applied to something that is not a list.
(list? (cons 3 4))
#f
(list? (cons 3 ‘())
#t
25 Jan
CS 655: Lecture 3
23
Manipulating Cons Cells
set-car!: ( . ), 
Takes a cons cell and value of
any type. Replaces first element of
cons with value.
(define pair1 (cons 1 2))
(1 . 2)
(set-car! pair1 3)
no value
pair1
(3 . 2)
25 Jan
CS 655: Lecture 3
24
Manipulating Cons Cells
set-cdr!: ( . ), 
Takes a cons cell and value of
any type. Replaces second element
of cons with value.
pair1
(3 . 2)
(set-cdr! pair1 3)
no value
pair1
(3 . 3)
25 Jan
CS 655: Lecture 3
25
Can we make an infinite list?
(define little '(1))
little
little
(1)
(set-cdr! little little)
Unspecified return value
little
(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 111111111111111111111111111111
111111111111111111111111111111111111111111
11111111111111111111111 111111111111111111111111
11111111111111111111111111111111111111111111111111111111
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1...
25 Jan
CS 655: Lecture 3
26
Bang!
• set-car! and set-cdr! change state
• All Scheme (primitive) procedures that
change state end with ! (pronounced
“bang”)
• Without them, Scheme is a pure
functional language.
25 Jan
CS 655: Lecture 3
27
Functions
• Mathematical Abstraction: same inputs
always give same outputs
+, , max, <, etc. are all functions
• If f is a function and x contains only
functions and literals, we can always
replace (+ (f x) (f x)) with
(define result (f x))
(+ result result))
25 Jan
CS 655: Lecture 3
28
Referential Transparency
• This is called referenential transparency
• It doesn’t matter what order or how often
you do things if everything is a function
• Once you have procedures that change
state, it does matter, and language
implementers much be much more careful!
• Much more on this later in the course...
25 Jan
CS 655: Lecture 3
29
Forget the last 7 slides
• For the next two+ weeks, we will
concentrate only on the purely
functional subset of Scheme
• Adding set-car! and set-cdr! is an
example of how a small language
change has a big impact
• You should not use any nonfunctional things in PS1.
25 Jan
CS 655: Lecture 3
30
Higher Order Procedures
• Last time – procedure that returns
procedure
(lambda (y) (+ x y)))
• Now – procedures that use procedures
are parameters
25 Jan
CS 655: Lecture 3
31
Maximum of a List
(define (max x y) (if (> x y) x y)))
(define (max-worker arg val)
(if (null? arg)
val
(max-worker
(cdr arg)
(max (car arg) val))))
(define (max-list arg) (max-worker arg 0))
25 Jan
CS 655: Lecture 3
32
Sum of a List
(define (sum-worker arg val)
(if (null? arg)
val
(sum-worker
(cdr arg)
(+ (car arg) val))))
(define (sum-list arg) (sum-worker arg 0))
25 Jan
CS 655: Lecture 3
33
Can we abstract this?
(define (sum-worker arg val) (define (max-worker arg val)
(if (null? arg)
(if (null? arg)
val
val
(sum-worker
(max-worker
(cdr arg)
(cdr arg)
(+ (car arg) val))))
(max (car arg) val))))
25 Jan
CS 655: Lecture 3
34
Sure...
(define (hard-worker arg val func)
(if (null? arg) val
(hard-worker
(cdr arg)
(func (car arg) val)
func)))
(define (max-list arg) (hard-worker arg 0 max))
(define (sum-list arg) (hard-worker arg 0 +))
25 Jan
CS 655: Lecture 3
35
Average
(define (average-list arg)
(/ (sum-list arg)
(hard-worker
arg
0
(lambda (x y) (+ y 1)))))
25 Jan
CS 655: Lecture 3
length
36
Even harder worker...
(define (harder-worker arg end-val func)
(if (null? arg)
end-val
(func (car arg)
(harder-worker
(cdr arg) end-val func))))
(harder-worker '(1 2 3) '() (lambda (el ls) (cons el ls)))
(1 2 3)
25 Jan
CS 655: Lecture 3
37
More examples...
(harder-worker ‘(1 2 3) ‘()
(lambda (el ls) (append ls (list el))))
(3 2 1)
(harder-worker ‘(1 2 3) 0
(lambda (x y) (+ x y)))
6
25 Jan
CS 655: Lecture 3
38
Even more
convoluted/powerful example
((harder-worker '(1 2 4)
(lambda (x y) (* x y))
(lambda (el f)
(lambda (x y) (f el (f x y)))))
1 2)
2048
25 Jan
= 211
CS 655: Lecture 3
39
Charge
• Problem Set 1 due Thursday
– Office hours, Monday 3-5
• Not on the problem set, but do for fun:
– Obfuscated Scheme contest: try to come
up with a convoluted use of higher-order
procedures for your problem set partner
to figure out.
• Next time: Metalinguistic Abstraction (Ch 4)
25 Jan
CS 655: Lecture 3
40
```