25 Jan CS 655: Lecture 3 1
Lecture 3: Of Lists and Slippery Slopes
David Evanshttp://www.cs.virginia.edu/~evans
CS655: Programming LanguagesUniversity of Virginia
25 Jan CS 655: Lecture 3 2
Menu
• Language Features and the Inevitability of Language Decay
• Lists
• Higher Order Procedures
25 Jan CS 655: Lecture 3 3
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 4
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 5
Lists
• LISP = LISt Processing
• Could we define pair functions using Mini-Scheme?
(make-pair 3 4) pair <3, 4>
(first (make-pair 3 4)) 3
(second (make-pair 3 4)) 4
25 Jan CS 655: Lecture 3 6
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 7
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 8
The Slippery Slope• Everything you add to a language
makes it harder to implement, harder to reason about, harder to understand 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 9
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,
JavaPhone, JavaTV, etc. (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
25 Jan CS 655: Lecture 3 10
Java is on Java is on the slope the slope now, about now, about to crash!to crash! (Duke suicide picture by Gary McGraw.)
25 Jan CS 655: Lecture 3 11
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 12
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, PerlisAlgol 68: Dijkstra, Hoare, McCarthy, Wirth
25 Jan CS 655: Lecture 3 13
“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 14
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 15
Enough (for now) on language complexity...
Next: how do we provide that glue
25 Jan CS 655: Lecture 3 16
List Primitives in Schemecons: , 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 17
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 18
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 19
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 20
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)
‘(1 2 3) (1 2 3)
25 Jan CS 655: Lecture 3 21
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 22
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 23
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 24
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 25
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 26
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 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 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 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 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 1 1 1 1...
25 Jan CS 655: Lecture 3 27
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 28
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 29
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 30
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 non-functional things in PS1.
25 Jan CS 655: Lecture 3 31
Higher Order Procedures
• Last time – procedure that returns procedure
(define (make-adder x)
(lambda (y) (+ x y)))
• Now – procedures that use procedures are parameters
25 Jan CS 655: Lecture 3 32
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 33
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 34
Can we abstract this?
(define (sum-worker arg val)
(if (null? arg)
val
(sum-worker
(cdr arg)
(+ (car arg) val))))
(define (max-worker arg val)
(if (null? arg)
val
(max-worker
(cdr arg)
(max (car arg) val))))
25 Jan CS 655: Lecture 3 35
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 36
Average
(define (average-list arg)
(/ (sum-list arg)
(hard-worker
arg
0
(lambda (x y) (+ y 1)))))
length
25 Jan CS 655: Lecture 3 37
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 38
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 39
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 = 211
25 Jan CS 655: Lecture 3 40
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)