Lecture 14: The environment model (cont

Slides:



Advertisements
Similar presentations
1 Lecture 16: Tables and OOP. 2 Tables -- get and put.
Advertisements

Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is a good way to learn more about programming languages  Interpreters are.
1 Programming Languages (CS 550) Lecture Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
1 Programming Languages and Paradigms Lisp Programming.
מבוא מורחב 1 Lecture #7. מבוא מורחב 2 The rational number abstraction Wishful thinking: (make-rat ) Creates a rational number (numer ) Returns the numerator.
CS 355 – PROGRAMMING LANGUAGES Dr. X. Apply-to-all A functional form that takes a single function as a parameter and yields a list of values obtained.
1-1 An Introduction to Scheme March Introduction A mid-1970s dialect of LISP, designed to be a cleaner, more modern, and simpler version than.
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 10. Environment Model 3.2, pages
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 8. Environment Model 3.2, pages
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 11. Dotted tail notation (define (proc m1 m2. opt) ) Mandatory Arguments: m1, m2 Mandatory Arguments: m1, m2.
SICP Data Mutation Primitive and Compound Data Mutators Stack Example non-mutating mutating Queue Example non-mutating mutating.
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
1 Lecture 15: More about assignment and the Environment Model (EM)
1 Lecture OO, the notion of inheritance 3 Stacks in OO style (define (make-stack) (let ((top-ptr '())) (define (empty?) (null? top-ptr)) (define.
SICP Interpretation Parts of an interpreter Arithmetic calculator Names Conditionals and if Storing procedures in the environment Environment as.
David Evans CS200: Computer Science University of Virginia Computer Science Lecture 18: Think Globally, Mutate Locally.
COP4020 Programming Languages Functional Programming Prof. Xin Yuan.
1 The Evaluator. 2 Compiler vs. Interpreter Command Processing Unit The Computer Program in Low Level Machine Language Program in High Level Language.
1 Lecture 14: Assignment and the Environment Model (EM)
1/32 Data Mutation Primitive and compound data mutators set! for names set-car!, set-cdr! for pairs Stack example non-mutating mutating Queue example non-mutating.
1 FP Foundations, Scheme In Text: Chapter Chapter 14: FP Foundations, Scheme Mathematical Functions Def: A mathematical function is a mapping of.
1 The Evaluator. 2 Compiler vs. Interpreter Command Processing Unit The Computer Program in Low Level Machine Language Program in High Level Language.
Operational Semantics of Scheme
Abstract Syntax cs7100 (Prasad) L7AST.
Basic Scheme February 8, 2007 Compound expressions Rules of evaluation
Edited by Original material by Eric Grimson
6.001 Jeopardy.
Pairs and Lists. Data Abstraction. SICP: Sections – 2.2.1
6.001 SICP Object Oriented Programming
The role of abstractions
September 4, 1997 Programming Languages (CS 550) Lecture 6 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts.
Lecture 14 - Environment Model (cont.) - Mutation - Stacks and Queues
Env. Model Implementation
Original material by Eric Grimson
Class 19: Think Globally, Mutate Locally CS150: Computer Science
6.001 SICP Data abstractions
The Metacircular Evaluator
Lecture 18 Infinite Streams and
Lecture 15: Tables and OOP
FP Foundations, Scheme In Text: Chapter 14.
Dynamic Scoping Lazy Evaluation
The Metacircular Evaluator
6.001 SICP Environment model
Lecture 16: Tables and OOP
The Metacircular Evaluator (Continued)
6.001 SICP Further Variations on a Scheme
Lecture #9 מבוא מורחב.
Abstract Syntax cs7100 (Prasad) L7AST.
Lecture 12: Message passing The Environment Model
Lecture 13 - Assignment and the environments model Chapter 3
Data Mutation Primitive and compound data mutators set! for names
6.001 SICP Environment model
Lecture 14 - Environment Model (cont.) - Mutation - Stacks and Queues
overview today’s ideas set-car! and set-cdr!
topics mutable data structures
6.001 SICP Variations on a Scheme
Mutators for compound data Stack Queue
6.001 SICP Data Mutation Primitive and Compound Data Mutators
Lecture 11: Multiple representations of abstract data Message passing Overloading Section 2.4, pages ,2.5.2 pages מבוא.
Announcements Quiz 5 HW6 due October 23
Lecture #7 מבוא מורחב.
Today’s topics Abstractions Procedural Data
6.001 SICP Interpretation Parts of an interpreter
6.001 SICP Environment model
Lecture 13: Assignment and the Environment Model (EM)
Introduction to the Lab
Lecture 2 מבוא מורחב.
Rehearsal: Lazy Evaluation Infinite Streams in our lazy evaluator
Presentation transcript:

Lecture 14: The environment model (cont Lecture 14: The environment model (cont.) Mutators for compound data (Section 3.3, pages 251-273) Stack; Queue

Example: explaining make-counter Counter: something which counts up from a number (define (make-counter n) (lambda () (set! n (+ n 1)) n) ) (define ca (make-counter 0)) (ca) ==> 1 (ca) ==> 2 (define cb (make-counter 0)) (cb) ==> 1 (ca) ==> 3 (cb) ==> 2

(define ca (make-counter 0)) | GE p: n b:(lambda () (set! n (+ n 1)) n) make-counter: ca: E1 n: 0 environment pointer points to E1 because the lambda was evaluated in E1 p: b:(set! n (+ n 1)) n (lambda () (set! n (+ n 1)) n) | E1

(ca) | GE ==> 1 GE p: n b:(lambda () (set! n (+ n 1)) n) make-counter: E1 n: 0 p: b:(set! n (+ n 1)) n ca: 1 E2 empty (set! n (+ n 1)) | E2 n | E2 ==> 1

(ca) | GE ==> 2 GE p: n b:(lambda () (set! n (+ n 1)) n) make-counter: E1 n: 0 p: b:(set! n (+ n 1)) n ca: 1 2 E3 empty (set! n (+ n 1)) | E3 n | E3 ==> 2

(define cb (make-counter 0)) | GE p: n b:(lambda () (set! n (+ n 1)) n) make-counter: E1 n: 2 p: b:(set! n (+ n 1)) n ca: E3 cb: E4 n: 0 p: b:(set! n (+ n 1)) n (lambda () (set! n (+ n 1)) n) | E4

(cb) | GE ==> 1 n: 0 E4 p: b:(set! n (+ n 1)) n cb: GE p: n b:(lambda () (set! n (+ n 1)) n) make-counter: E1 n: 2 p: b:(set! n (+ n 1)) n ca: E2 1 E5

Capturing state in local frames & procedures p: b:(set! n (+ n 1)) n cb: GE p: n b:(lambda () (set! n (+ n 1)) n) make-counter: E1 n: 2 p: b:(set! n (+ n 1)) n ca: E2

Lessons from the make-counter example Environment diagrams get complicated very quickly Rules are meant for the computer to follow, not to help humans A lambda inside a procedure body captures the frame that was active when the lambda was evaluated this effect can be used to store local state

Lets do a message passing example (define (cons x y) (define (dispatch op) (cond ((eq? op 'car) x) ((eq? op 'cdr) y) (else (error "Unknown op -- CONS" op)))) dispatch) (define (car x) (x 'car)) (define (cdr x) (x 'cdr)) This code was modeled on the board. Recall that we explained that this example shows how Scheme’s “static scoping” comes to play. By this we mean that even though the procedure dispatch Pointed to by “a” is called from within the car procedure, our static scoping model that looks for variables in the env the procedure was defined in, causes us to look for x in the env where dispatch was Created, and thus we find the correct variable x to return, the one with value 1. (define a (cons 1 2)) (car a)

(define (cons x y) ..) | GE GE p: x,y b:(def disp (op) .. dispatch) b:(x ‘cdr) cdr: p: x b:(x ‘car) car:

(define a (cons 1 2)) | GE GE p: x,y b:(def disp (op) .. dispatch) b:(x ‘car) car: cdr: a: E1 x: 1 Y: 2 p: op b:(cond ..) Disp: p: x b:(x ‘cdr)

(car a) | GE GE p: x,y b:(def disp (op) .. dispatch) cons: p: x b:(x ‘car) car: cdr: a: x: E2 E1 x: 1 Y: 2 p: op b:(cond ..) Disp: p: x b:(x ‘cdr)

(x ‘car) | E2 GE p: x,y b:(def disp (op) .. dispatch) cons: p: x b:(x ‘car) car: cdr: a: x: E1 x: 1 Y: 2 E2 p: op b:(cond ..) Disp: E3 empty p: x b:(x ‘cdr)

Returned value is x|E1=1. After that what remains is: GE p: x,y b:(def disp (op) .. dispatch) cons: p: x b:(x ‘car) car: cdr: a: E1 x: 1 Y: 2 p: op b:(cond ..) Disp: p: x b:(x ‘cdr)

Explaining Nested Definitions Nested definitions : block structure (define (sqrt x) (define (good-enough? guess) (< (abs (- (square guess) x)) 0.001)) (define (improve guess) (average guess (/ x guess))) (define (sqrt-iter guess) (if (good-enough? guess) guess (sqrt-iter (improve guess)))) (sqrt-iter 1.0))

p: x b:(define good-enou ..) (define improve ..) sqrt: (sqrt 2) | GE GE p: x b:(define good-enou ..) (define improve ..) (define sqrt-iter ..) (sqrt-iter 1.0) sqrt: guess: 1 good-enou? E1 x: 2 good-enough: p: guess b:(< (abs ….) The same x in all subprocedures improve: sqrt-iter: guess: 1 sqrt-iter

Summary: The Environment Model A precise, completely mechanical description of: name-rule looking up the value of a variable define-rule creating a new definition of a var set!-rule changing the value of a variable lambda-rule creating a procedure application rule applying a procedure You will use it to implement the Scheme interpreter, Gotta practice using it… It’s a major part of the final exam As we noted earlier in the course, we need to change models to explain a more complex universe, in the same way that in Physics one needs to abandon the Newtonian model in order to reason effectively about sub-atomic particles.

Mutators for compound data

Mutating Compound Data constructor: (cons x y) creates a new pair p selectors: (car p) returns car part of pair (cdr p) returns cdr part of pair mutators: (set-car! p new-x) changes car pointer in pair (set-cdr! p new-y) changes cdr pointer in pair ; Pair,anytype -> undef -- side-effect only!

Example: Pair/List Mutation (define a (list ‘red ‘blue)) red blue b a 10 X a ==> (red blue) (define b a) b ==> (red blue) (set-car! a 10) a ==> (10 ‘blue) b ==> (10 ‘blue)

Compare this with… red blue c 10 X d (define c (list ‘red ‘blue)) (define d (list ‘red ‘blue)) red blue c 10 X d c ==> (red blue) d ==> (red blue) (set-car! c 10) c ==> (10 blue) d ==> (red blue)

Equivalent vs. The Same In the first example a and b are the same. A change to one changes the other. The point to a single object. red blue b a 10 X In the second example c and d have at first the same value, but later on one changes and the other does not.They just happen to have at some point in time the same value. red blue c 10 X d

Eq? vs. Equal? To check whether two names point to the same object: Test with eq? (eq? a b) ==> #t To check whether two elements currently have the same content: Test with equal? (equal? (list 1 2) (list 1 2)) ==> #t (eq? (list 1 2) (list 1 2)) ==> #f

Q&A: “2 B 2 B =” Q: If we change an object, is it the same object? A: Yes, if we retain the same pointer to the object. Q: How can we tell if two elements share the same object? A. One thing you can do is mutate one and see if the other also changes.

Example 2: Pair/List Mutation (define x (list 'a 'b)) (set-car! (cdr x) (list 1 2)) Eval (cdr x) to get a pair object Change car pointer of that pair object a b x 2 1 (a ( 1 2))

Your Turn x ==> (3 4) y ==> (1 2) (set-car! x y) x ==> (set-cdr! y (cdr x)) (set-cdr! x (list 7) 7 X 3 4 x ((1 2) 4) X X ((1 4) 4) 1 2 y ((1 4) 7)

Summary Scheme provides built-in mutators set! to change a binding set-car! and set-cdr! to change a pair Mutation introduces substantial complexity Unexpected side effects Substitution model is no longer sufficient to explain behavior

Stack

Stack Data Abstraction constructor: (make-stack) returns an empty stack selectors: (top stack) returns current top element from a stack operations: (insert stack elem) returns a new stack with the element added to the top of the stack (delete stack) returns a new stack with the top element removed from the stack (empty-stack? stack) returns #t if no elements, #f otherwise

Stack Data Abstraction Insert Insert Last in, First out. Insert Delete Insert

Stack Contract If s is a stack, created by (make-stack)and subsequent stack procedures, where i is the number of insertions and d is the number of deletions, then If d>i then it is an error If d=i then (empty-stack? s) is true, and (top s) and (delete s) are errors. If d<i then (empty-stack? s) is false and (top (delete (insert s val))) = (top s) If d<=i then (top (insert s val)) = val for any val

Stack Implementation Strategy implement a stack as a list a b d we will insert and delete items at the front of the stack

Stack Implementation (define (make-stack) nil) (define (empty-stack? stack) (null? stack)) (define (insert stack elem) (cons elem stack)) (define (delete stack) (if (empty-stack? stack) (error "stack underflow – delete") (cdr stack))) (define (top stack) (error "stack underflow – top") (car stack)))

Limitations in our Stack Stack does not have identity (define s (make-stack)) s ==> () (insert s 'a) ==> (a) (set! s (insert s 'b)) s ==> (b)

Alternative Stack Implementation The stack will be a mutable data type. The data type contains a list of elements – as before. Insert and delete mutate a stack object. The first element of the list is special to distinguish Stack objects from other lists – defensive programming X (delete! s) a c d stack s

Alternative Stack Implementation (1) (define (make-stack) (cons 'stack nil)) (define (stack? stack) (and (pair? stack) (eq? 'stack (car stack)))) (define (empty-stack? stack) (if (not (stack? stack)) (error "object not a stack:" stack) (null? (cdr stack)))) (define (top stack) (if (empty-stack? stack) (error "stack underflow – top") (cadr stack)))

Alternative Stack Implementation (2) (define (insert! stack elem) (cond ((not (stack? stack)) (error "object not a stack:" stack)) (else (set-cdr! stack (cons elem (cdr stack))) stack))) (define (delete! stack) (if (empty-stack? stack) (error "stack underflow – delete") (set-cdr! stack (cddr stack))) stack)

Does the user have to know about it? Usually the user does not care about the implementation As long as the contract is being kept. Both implementations keep the contract. Yet: This is a change to the abstraction! The user should know if the object mutates or not in order to use the abstraction correctly. If we (define a b), can a later change because of changes to b?