λ λ CS 251 Fall 2019 CS 251 Fall 2019 Topics Principles of Programming Languages Principles of Programming Languages Ben Wood Ben Wood • Mutation is unnecessary. Immutability • Immutability offers referential transparency. • Mutation complicates aliasing. and Referential Transparency • Broader design considerations https://cs.wellesley.edu/~cs251/f19/ 1 Immutability 2 Immutability Mutation is unnecessary. Is immutability an obstacle or a tool? – Programming experience in 251 and previously Patterns for accumulating results without mutation : – Readings about language implementation – Build recursively – Efficiency in space and time – Create fresh copy with changes – Reliability – Explicitly thread state through (e.g., fold): – Maintainability • Function does one step, from arguments to – Ease of making/avoiding mistakes result. – Clarity • HOF passes result on to the next step. – … Immutability 3 Immutability 4
Immutability offers Consider mutation referential transparency Mutable cons cell (define x (mcons 3 4)) (define (sort-pair p) (define y (sort-mpair x)) x 3 4 (if (< (car p) (cdr p)) ? p y ; mutate car of x to hold 5 (cons (cdr p) (car p)))) ? (set-mcdr! x 5) 3 4 (define (sort-pair p) (if (< (car p) (cdr p)) (define z (mcdr y)) (cons (car p) (cdr p)) (cons (cdr p) (car p)))) What is z ? Cons cells are immutable. Cannot tell if you copy or alias. Immutability 5 Immutability 6 append Java security nightmare (define (append xs ys) (if (null? xs) class ProtectedResource { private Resource theResource = ...; ys private String[] allowedUsers = ...; (cons (car xs) (append (cdr xs) ys)))) public String[] getAllowedUsers() { (define x (list 2 4) return allowedUsers; (define y (list 5 3 0)) } (define z (append x y)) public String currentUser() { ... } public void useTheResource() { 2 4 x for (int i = 0; i < allowedUsers.length; i++) { y 5 3 0 if (currentUser().equals(allowedUsers[i])) { ... // access allowed: use it 2 4 z return; or ? } } 2 4 x throw new IllegalAccessException(); y 5 3 0 } } 2 4 5 3 0 z Immutability 7 Immutability 8
Mutant users! A biasing on aliasing Immutabili Im lity The problem: Aliasing do does s not affect correctness, just performance. p.getAllowedUsers()[0] = p.currentUser(); Other code ca cannot break your code, regardless of aliasing. p.useTheResource(); Changing your aliasing ca cannot break other code. Document what, no not how. Safe by defau Saf ault lt, optimize for performan ance. The fix: Mu Mutability public String[] getAllowedUsers() { Aliasing do does affect both correctness and performance. … return a copy of allowedUsers … Other code ca can break your code, depending on your aliasing. } Changing your aliasing ca can break other code. Document what an and how. Uns Unsafe by y defaul ult, optimize for performanc nce and nd safety. Could this happen without mutability? All the more important for parallelism and concurrency… Immutability 9 Immutability 10 Wh What must we inspect to Identify dependences between ________. A broader PL design theme Ra Racket: immutable le natural l recursion (define (fib n) recursiv re ive (if (< n 2) calls alls Design choices matter. Less can be more (reliable). n (+ (fib (- n 1)) (fib (- n 2))))) Immutability + recursion (vs. mutability + loops) are central: Racket: immutable Ra le tail l recursion (define (fib n) – Limiting ho how programs can be expressed (a.k.a., not giving programmers (define (fib-tail n fibi fibi+1) Last Week unmitigated access – Making elements more transparent/explicit (if (= 0 n) to dangerous volatile weapons) fibi (a.k.a., not further obscuring (fib-tail (- n 1) fibi+1 (+ fibi fibi+1)))) This style of design choice often supports: subtle/tricky program elements (fib n 0 1)) through layers of implicitness) – Simple reasoning And maybe the – Strong default guarantees def fib(n): Python: lo loop iterat ation with mutat ation fib_i = 0 – Automated optimization opportunities fib_i_plus_1 = 1 whole program loop lo for i in range(n): It does no not t mean limiting wh what computable functions can be fib_i_prev = fib_i iterat it ratio ions implemented, just ho how . fib_i = fib_i_plus_1 fib_i_plus_1 = fib_i_prev + fib_i_plus_1 return fib_i Tail Recursion 11 Immutability 12
Recommend
More recommend