320 likes | 424 Views
Assignments. l-value vs . r-value. Pascal/Ada: x := x + 1 C/Java: x = x + 1 l-value = location, address, reference, … r-value = int, real, (sometimes even) address, … Environment binds an identifier to a location. env : ids -> locations
E N D
Assignments L13Assg
l-value vs. r-value • Pascal/Ada: x := x + 1 • C/Java: x = x + 1 l-value = location, address, reference, … r-value = int, real, (sometimes even) address, … Environment binds an identifier to a location. env : ids -> locations Store binds a location to a value. store : locations -> values assign-op :location x value x store -> store L13Assg
Sharing • For functional subset, it is sufficient to model env as a function from ids to values. • For imperative programming that has both assignment and sharing, separating env and store is necessary. • E.g., sharing/aliasing Point p = new Point(); Point q = p; • E.g., call by reference void f(Point p){}; f(q); L13Assg
Side-effect causing Scheme primitives • Initialize variable: (define <var> <exp>) • Update variable: (set! <var> <exp>) • Other ops: display, write, set-car!, set-cdr!,... (set! x y) denotes location denotes value • Sequencing: (begin <exp1> <exp2> … <expn>) L13Assg
Extending object (not meta-) language and the interpreter to support variable assignment L13Assg
Modifying environment and the interpreter • An identifier denotes the address of a mutable data structure that holds a value (that is, it models a memory location). • This address is called a reference, and the contents of these references are modified by a variable assignment. • Variable reference (var-exp (id) (deref (apply-env-ref env id))) L13Assg
Introduction of variable assignment • Syntax <expression> ::= set <identifier> = <expression> • Abstract Syntax varassign-exp (id rhs-exp) • Semantics (varassign-exp (var exp) (set-ref!(apply-env-ref env id) (eval-expression rhs-exp env) ) ) l-value r-value L13Assg
Simulating letrec using let and assignment (letrec ((var1 exp1) (var2 exp2)) exp ) (* exp1 and exp2 are lambda-forms *) (let ((var1 ’*) (var2 ’*)) (set! var1 exp1) (set! var2 exp2) exp ) L13Assg
Simulating Objects and Classes L13Assg
Defining a stack object (define empty? '()) (define push! '()) (define pop! '()) (define top'()) (let ( (stk'()) ) (set! empty? (lambda() (null? stk))) (set! push! (lambda(x) (set! stk (cons x stk)))) (set! pop! (lambda() (set! stk (cdr stk)))) (set! top (lambda() (car stk))) ) L13Assg
> (empty?) #t > (push! 5) > (top) 5 > (pop!) > (empty?) #t Only one stack object. Scope of stk is limited (encapsulation), but its lifetime is not. representation pvt. methods public. Persistent state. Ops. share data and change state. Using the stack object L13Assg
stack object : Message passing style (define stack (let ( (stk '()) ) (lambda (msg) (case msg ((empty?) (lambda () (null? stk)) ) (( push!) (lambda (x) (set! stk (cons x stk))) ) (( pop! ) (lambda () (set! stk (cdr stk))) ) ((top) (lambda () (car stk)) ) (else 'error ) ) ))) L13Assg
> (stack 'empty?) > ((stack 'empty?)) #t > ((stack 'push!) 5) > ((stack 'top)) 5 > ((stack 'empty?)) () or #f > ((stack 'pop!)) > ((stack 'empty?)) #t (define s1 (make-stack)) (define s2 (make-stack)) ((s1 'push!) 1) ((s2 'push!) 2) ( (s1 'top) ) 1 ( (s1 'top) ) 1 ( (s2 'top) ) 2 Object vs. Class L13Assg
(define stack (let ((stk '()) ) (lambda (msg) (case msg ... ) )) ) (define make-stack (lambda() (let ((stk '()) ) (lambda (msg) (case msg ... ) )) )) Instance/Object vs. Class/Type L13Assg
stack class : Message passing style (define make-stack (lambda () (let ( (stk '()) ) (lambda (msg) (case msg ((empty?) (lambda () (null? stk)) ) (( push!) (lambda (x) (set! stk (cons x stk))) ) (( pop! ) (lambda () (set! stk (cdr stk))) ) ((top) (lambda () (car stk)) ) (else 'error ) ))) ) ) L13Assg
Template for class definition (define class-name (let ((class-var val)) (lambda () (let ((inst-var val)) (lambda (msg) (case msg ((m1) code) ((m2) code) ((c3) code) (else ’error) )) )) ) ) L13Assg
(define make-stack (let ((pushed 0)) (lambda () (let ((stk '()) (local-pushed 0) ) (lambda (message) (case message ((empty?) (lambda () (null? stk))) ((push!) (lambda (x) (set! pushed (+ pushed 1)) (set! local-pushed (+ local-pushed 1)) (set! stk (cons x stk)))) ((pop!) (lambda () (if (null? stk) (error "Stack: Underflow") (begin (set! pushed (- pushed 1)) (set! local-pushed (- local-pushed 1)) (set! stk (cdr stk)))))) ((top) (lambda () (if (null? stk) (error "Stack: Underflow") (car stk)))) ((local-pushed) (lambda () local-pushed)) ((pushed) (lambda () pushed)) (else (error "Stack: Invalid message" message)))))))) L13Assg
(lambda () (let (…) … ) ) pushed = 0 (lambda (msg) … ) (lambda (msg) … ) stk = () local-pushed = 0 stk = () local-pushed = 0 make-stack (make-stack)(make-stack) L13Assg
Rewrite in Java publicclass Stackclass { static int pushed; private Vector stk; private int localpushed; static { pushed := 0 } public Stackclass(){ localpushed = 0; stk = new Vector(); } public boolean empty() { return stk.isEmpty() }; publicvoid push(Object x){ pushed++; localpushed++; stk.addElement(x); } ... L13Assg
... publicvoid pop(){ if (stk.isEmpty()) throw new Exception(“Stack Empty”); else { --pushed; --localpushed; stk.removeElementAt(stk.size()-1); } } public Object top(){ if (empty()) thrownew Exception(“Stack Empty”);elsereturn stk.lastElement(); } public int pushed() { return pushed; } public int localpushed(){ return localpushed; } } L13Assg
Approximate Environment L13Assg
Rewrite in Java public class Test { public static void main(String [] args) { Stackclassstack1 = new Stackclass(); Stackclassstack1 = new Stackclass(); stack1.push(new Integer(7)); stack1.top(); stack2.push(new Integer(6)); stack2.push(new Integer(8)); stack2.top(); stack1.localpushed(); stack2.localpushed(); stack1.pushed(); stack2.pushed(); } } L13Assg
Approximate Environment L13Assg
Inheritance Share and reuse classes with modifications to fields and methods Improve programmer productivity and aid code evolution L13Assg
Inheritance in Java class Boundedstackclass extends Stack { private int bound; Boundedstackclass() { super(); bound = 10; } publicvoid push(Object x) { if (size() < bound) super.push(x); elsenew Exception(“Overflow”); } publicvoid setbound(int x){ bound = x; } } • Specify only incremental changes. • Access parent’s version of a method through super. L13Assg
Composition and Delegation in Java class Boundedstackclass { private int bound; privateStack stk; Boundedstackclass() { stk = new Stack(); bound = 10; } publicvoid push(Object x) { if (size() < bound) stk.push(x); elsenew Exception(”Overflow”); } publicvoid setbound(int x){ bound = x; } public Object top() { returnstk.top(); } ... Explicit list of other delegated stack methods } L13Assg
Delegation (define make-bounded-stack (lambda (n) (let ((bound n) (stk (make-stack))) (lambda (message) (case message ((push!) (if (< ((stk 'local-pushed)) bound) (stk 'push!) (error “Overflow”))) ((set-bound!) (lambda (x) (set! bound x))) ((set-stack!) (lambda (s) (set! stk s))) (else(stk message)) ) )))) L13Assg
Delegation (define stk (make-bounded-stack 24)) ( (stk 'push!) 3) ( (stk 'top) ) (((make-bounded-stack 24) 'push!) 3) ; (((make-bounded-stack 24) 'top)) L13Assg
Code sharing by organization of objects. Delegate message handling. Dynamic and flexible. When and how to delegate can depend on system state. E.g., Java 1.1 Event Model Code sharing by organization of classes. Single vs multiple inheritance. Static but efficient. Type determines message interpretation. E.g., Java 1.0 Event Model Delegation vs Inheritance L13Assg
Scoping: Lexical vs Static class A { static int cv; int iv; } class Test { public static void main(String [] args){ int iv, cv; class B extends A { void print() { System.out.print( “”+ cv + iv ); /*error*/ System.out.println( “”+this.cv +this.iv ); } } new B(). print(); } } L13Assg
Binding: Dynamic vs Static class A { static int cv = 10; int iv = 70; int f() {return 40;} void print() { System.out.println( “”+ cv + iv + f()); }} class B extends A { static int cv = 33 ; int iv = 88; int f() {return 55;} } class Test2 { public static void main(String [] args){ new A(). print(); new B(). print(); }} L13Assg
Advanced Topics • Multiple Inheritance • E.g., C++, Eiffel. • Meta-classes • E.g., Smalltalk. • Inner/Nested classes • E.g., Java. • Polymorphic Static Typing • E.g., ML, Haskell. L13Assg