310 likes | 400 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 L123Assg
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 L123Assg
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); L123Assg
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>) L123Assg
Extending object (not meta-) language and the interpreter to support variable assignment L123Assg
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))) L123Assg
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 L123Assg
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 ) L123Assg
Simulating Objects and Classes L123Assg
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))) ) L123Assg
> (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 L123Assg
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 ) ) ))) L123Assg
> (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 L123Assg
(define stack (let ((stk '()) ) (lambda (msg) (case msg ... ) )) ) (define make-stack (lambda() (let ((stk '()) ) (lambda (msg) (case msg ... ) )) )) Instance/Object vs. Class/Type L123Assg
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 ) ))) ) ) L123Assg
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) )) )) ) ) L123Assg
(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)))))))) L123Assg
(lambda () (let (…) … ) ) pushed = 0 (lambda (msg) … ) (lambda (msg) … ) stk = () local-pushed = 0 stk = () local-pushed = 0 make-stack (make-stack)(make-stack) L123Assg
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); } ... L123Assg
... 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; } } L123Assg
Approximate Environment L123Assg
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(); } } L123Assg
Approximate Environment L123Assg
Inheritance Share and reuse classes with modifications to fields and methods Improve programmer productivity and aid code evolution L123Assg
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)) ) )))) L123Assg
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 L123Assg
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. L123Assg
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 } L123Assg
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(); } } L123Assg
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(); }} L123Assg
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. L123Assg