400 likes | 486 Views
Lecture 3: Of Lists and Slippery Slopes. CS655: Programming Languages University of Virginia. David Evans http://www.cs.virginia.edu/~evans. Menu. Language Features and the Inevitability of Language Decay Lists Higher Order Procedures. Recap: Last Time. Primitives
E N D
Lecture 3: Of Lists and Slippery Slopes CS655: Programming Languages University of Virginia David Evans http://www.cs.virginia.edu/~evans CS 655: Lecture 3
Menu • Language Features and the Inevitability of Language Decay • Lists • Higher Order Procedures CS 655: Lecture 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 CS 655: Lecture 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 CS 655: Lecture 3
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 CS 655: Lecture 3
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. CS 655: Lecture 3
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. CS 655: Lecture 3
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 CS 655: Lecture 3
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 CS 655: Lecture 3
Java is on the slope now, about to crash! (Duke suicide picture by Gary McGraw.) CS 655: Lecture 3
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” CS 655: Lecture 3
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 CS 655: Lecture 3
“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. CS 655: Lecture 3
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. CS 655: Lecture 3
Enough (for now) on language complexity...Next: how do we provide that glue CS 655: Lecture 3
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) CS 655: Lecture 3
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. CS 655: Lecture 3
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 CS 655: Lecture 3
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) CS 655: Lecture 3
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) CS 655: Lecture 3
Examples (cdr (cons 3 4)) 4 (cdr (list 3 4)) (4) (cdr ‘(3 4)) (4) (car ‘((3 4) (5 4 6) 7)) (3 4) CS 655: Lecture 3
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 CS 655: Lecture 3
List Predicates: list? list?: boolean #f if applied to something that is not a list. (list? (cons 3 4)) #f (list? (cons 3 ‘()) #t CS 655: Lecture 3
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) CS 655: Lecture 3
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) CS 655: Lecture 3
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 11 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1... CS 655: Lecture 3
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. CS 655: Lecture 3
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 (+ (fx) (f x)) with (define result (f x)) (+ result result)) CS 655: Lecture 3
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... CS 655: Lecture 3
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. CS 655: Lecture 3
Higher Order Procedures • Last time – procedure that returns procedure (define (make-adder x) (lambda (y) (+ x y))) • Now – procedures that use procedures are parameters CS 655: Lecture 3
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)) CS 655: Lecture 3
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)) CS 655: Lecture 3
Can we abstract this? (define (max-worker arg val) (if (null? arg) val (max-worker (cdr arg) (max (car arg) val)))) (define (sum-worker arg val) (if (null? arg) val (sum-worker (cdr arg) (+ (car arg) val)))) CS 655: Lecture 3
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 +)) CS 655: Lecture 3
Average (define (average-list arg) (/ (sum-list arg) (hard-worker arg 0 (lambda (x y) (+ y 1))))) length CS 655: Lecture 3
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) CS 655: Lecture 3
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 CS 655: Lecture 3
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 CS 655: Lecture 3
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) CS 655: Lecture 3