Title: Assignments
1Assignments
2l-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 -gt locations
- Store binds a location to a value.
- store locations -gt values
- assign-op location x value x store -gt store
3Sharing
- 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)
4Side-effect causing Scheme primitives
- Initialize variable (define ltvargt ltexpgt)
- Update variable (set! ltvargt ltexpgt)
- Other ops display, write,
- set-car!, set-cdr!,...
- (set! x y)
- denotes location denotes value
- Sequencing
- (begin ltexp1gt ltexp2gt ltexpngt)
5Extending object (not meta-) language and the
interpreter to support variable assignment
6Modifying 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)))
7Introduction of variable assignment
- Syntax
- ltexpressiongt
- set ltidentifiergt ltexpressiongt
- 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
8Simulating 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
- )
9Simulating Objects and Classes
10Defining 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)))
- )
11Using the stack object
- gt (empty?)
- t
- gt (push! 5)
- gt (top)
- 5
- gt (pop!)
- gt (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.
12stack 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 ) )
- )))
13Object vs. Class
- (define s1
- (make-stack))
- (define s2
- (make-stack))
- ((s1 'push!) 1)
- ((s2 'push!) 2)
- ( (s1 'top) )
- 1
- ( (s1 'top) )
- 1
- ( (s2 'top) )
- 2
- gt (stack 'empty?)
- gt ((stack 'empty?))
- t
- gt ((stack 'push!) 5)
- gt ((stack 'top))
- 5
- gt ((stack 'empty?))
- () or f
- gt ((stack 'pop!))
- gt ((stack 'empty?))
- t
14Instance/Object vs. Class/Type
- (define stack
- (let ((stk '()) )
- (lambda (msg)
- (case msg
- ...
- )
- ))
- )
- (define make-stack
- (lambda()
- (let ((stk '()) )
- (lambda (msg)
- (case msg
- ...
- )
- ))
- ))
15stack 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 )
- )))
- )
- )
16Template 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) ))
- ) ) ) )
17- (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))
18make-stack
(make-stack) (make-stack)
19Rewrite in Java
- public class 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()
-
- public void push(Object x)
- pushed localpushed
- stk.addElement(x)
- ...
20- ...
- public void pop()
- if (stk.isEmpty())
- throw new Exception(Stack Empty)
- else --pushed --localpushed
- stk.removeElementAt(stk.size()-1)
-
-
- public Object top()
- if (empty())
- throw new Exception(Stack Empty)
else return stk.lastElement() -
- public int pushed() return pushed
- public int localpushed()
- return localpushed
21Approximate Environment
22Rewrite in Java
- public class Test
- public static void main(String args)
- Stackclass stack1 new Stackclass()
- Stackclass stack1 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()
-
23Approximate Environment
24Inheritance
- Share and reuse classes with modifications to
fields and methods - Improve programmer productivity and aid code
evolution
25Delegation
- (define make-bounded-stack
- (lambda (n)
- (let ((bound n) (stk (make-stack)))
- (lambda (message)
- (case message
- ((push!)
- (if (lt ((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))
- )
- ))))
26Delegation vs Inheritance
- 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
27Inheritance in Java
- class Boundedstackclass extends Stack
- private int bound
- Boundedstackclass()
- super()
- bound 10
-
- public void push(Object x)
- if (size() lt bound)
- super.push(x)
- else new Exception(Overflow)
-
- public void setbound(int x)
- bound x
-
-
- Specify only incremental changes.
- Access parents version of a method through super.
28Composition and Delegation in Java
- class Boundedstackclass
- private int bound
- private Stack stk
- Boundedstackclass()
- stk new Stack()
- bound 10
-
- public void push(Object x)
- if (size() lt bound)
- stk.push(x)
- else new Exception(Overflow)
-
- public void setbound(int x)
- bound x
-
- public Object top()
- return stk.top()
-
- ...
29Scoping 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()
-
30Binding 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()
31Advanced 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.