Presentation is loading. Please wait.

Presentation is loading. Please wait.

Assignments cs7100(Prasad) L13Assg.

Similar presentations


Presentation on theme: "Assignments cs7100(Prasad) L13Assg."— Presentation transcript:

1 Assignments cs7100(Prasad) L13Assg

2 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 env and store allow one to describe the semantics of assignment in a purely functional style. (DENOTATIONAL SEMANTICS) On the other hand, the interpreter in Scheme use vector for the same purpose, for convenient implementation. Object language structures are mapped to similar Scheme structures. (META-CIRCULAR INTERPRETER) cs7100(Prasad) L13Assg

3 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); a loc value x cs7100(Prasad) L13Assg

4 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>) In Scheme, locations are denotable, but not expressible. Ordering of expression evaluation important in the presence of side-effects. cs7100(Prasad) L13Assg

5 Extending object (not meta-) language and the interpreter to support variable assignment
cs7100(Prasad) L13Assg

6 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))) l-value : aref – position – vector of values Implicitily, the implementation allocates storage for locals in let-construct and procedure-definition, and captures call-by-value parameter passing mechanism. Support for call by reference requires change to the interpreter. Support for multiple parameter passing mechanisms in the object language requires additional syntax. cs7100(Prasad) L13Assg

7 Refer to full interpreter code for contextual details
(define-datatype reference reference? (a-ref (position integer?) (vec vector?))) (define deref (lambda (ref) (cases reference ref (a-ref (pos vec) (vector-ref vec pos))))) (define setref! (lambda (ref val) (vector-set! vec pos val))) 1)) Refer to full interpreter code for contextual details A reference is an entire vector plus a position. cs7100(Prasad) L13Assg

8 Refer to full interpreter code for contextual details
(define apply-env-ref (lambda (env sym) (cases environment env (empty-env-record () (eopl:error 'apply-env-ref "No binding for ~s" sym) ) (extended-env-record (syms vals env) (let ((pos (rib-find-position sym syms))) (if (number? pos) (a-ref pos vals) (apply-env-ref env sym))))))) (define apply-env (deref (apply-env-ref env sym)))) Refer to full interpreter code for contextual details Appy-env-ref returns an aref (position + vector) cs7100(Prasad) L13Assg

9 Refer to full interpreter code for contextual details
(define extend-env-recursively (lambda (proc-names idss bodies old-env) (let ((len (length proc-names))) (let ((vec (make-vector len))) (let ((env (extended-env-record proc-names vec old-env))) (for-each (lambda (pos ids body) (vector-set! vec pos (closure ids body env))) (iota len) idss bodies) env))))) The mutually recursively procedures are bound to the right closures in the vector. Refer to full interpreter code for contextual details cs7100(Prasad) L13Assg

10 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 var) (eval-expression exp env) ) ) l-value r-value The semantics of “set x = x” will clarify the distinction between l-value and r-value. In main stream languages, the coercion (dereferencing) is implicit, while in languages such as ML, it is explicit. E.g., in C, we can write the assignment “int x = 5; x = x;”, while in ML the corresponding code is “val x = ref 5; x = !x;” cs7100(Prasad) L13Assg

11 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) let and assignment in the object language can allow us to simulate letrec, but only in the context of procedural values. (letrec ( (x (lambda () y)) (y 1) ) (x) ) = but (letrec ( (x y) (y 1) ) x ) = error cs7100(Prasad) L13Assg

12 Simulating Objects and Classes
cs7100(Prasad) L13Assg

13 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))) ) One stack object. Representation private.(encapsulation) Methods public, in fact, global. Illustrates the independence of scope and lifetime: limited scope, infinite lifetime. (let ( (stk '()) ) (define empty? (lambda() (null? stk))) (define push! (lambda(x) (set! stk (cons x stk)))) (define pop! (lambda() (set! stk (cdr stk)))) (define top (lambda() (car stk))) ) This definition is incorrect because methods are local, not global. Quote character is ’ and not ‘ or ’ cs7100(Prasad) L13Assg

14 Using the stack object > (empty?) #t > (push! 5) > (top) 5
> (pop!) 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. Note how the ability to restrict visibility using let-construct and using assignment operation, it is possible to encode objects (with state). cs7100(Prasad) L13Assg

15 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 ) ) ))) In the previous case, the methods are global and the second stack instance must support a differently named global methods, to avoid name clashes. In order to make stack objects respond to same methods, that is share a common interface, one can recast it using message passing style. Quote character is ' and not ‘ or ’ cs7100(Prasad) L13Assg

16 Object vs. Class (define s1 (make-stack)) > ((stack 'empty?))
((s1 'push!) 1) ((s2 'push!) 2) ( (s1 'top) ) 1 ( (s2 'top) ) 2 > (stack 'empty?) > ((stack 'empty?)) #t > ((stack 'push!) 5) > ((stack 'top)) 5 > ((stack 'empty?)) () or #f > ((stack 'pop!)) let-construct, thunks, procedures and assignment are the basic ingredients required to support OOP style of programming. cs7100(Prasad) L13Assg

17 Instance/Object vs. Class/Type
(define stack (let ((stk '()) ) (lambda (msg) (case msg ... ) )) (define make-stack (lambda() (let ((stk '()) ) (lambda (msg) (case msg ... ) )) When stack is defined, stk is allocated. To delay allocation, one can use thunk. Each time the thunk is evaluated, a new incarnation of stk corresponding to a new instance is created. cs7100(Prasad) L13Assg

18 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 ) ))) ) The two invocations of (makestack) result in two different private mini-environments for stk. However, does the two invocations share the resulting procedure codes? (cf. conventional classes) cs7100(Prasad) L13Assg

19 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) )) ) ) ) ) Illustrates: classes ; class variables, instances, instance variables, class methods, instance methods. How do we enable class methods independent of an instance in this setting? One approach: bind class name to (lambda (classmsg) …) value with “new” message allocating storage and initializing the instance, and other messages invoking class methods. In this case, instances will not respond to class messages, unless they are explicitly delegated to it. cs7100(Prasad) L13Assg

20 (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 () (car stk)))) ((local-pushed) (lambda () local-pushed)) ((pushed) (lambda () pushed)) (else (error "Stack: Invalid message" message))))) ))) Illustrates classes ; class variables, instances, instance variables, class methods, instance methods. How do we enable class methods independent of an instance in this setting? One approach: bind class name to (lambda (classmsg) …) value with “new” message allocating storage and initializing the instance, and other messages invoking class methods. In this case, instances will not respond to class messages, unless they are explicitly delegated to it. cs7100(Prasad) L13Assg

21 make-stack (lambda () (let (…) … ) pushed = 0
(make-stack) (make-stack) (lambda (msg) ) stk = () local-pushed = 0 (lambda (msg) ) stk = () local-pushed = 0 cs7100(Prasad) L13Assg

22 Rewrite 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); } Here pushed can be made “private” for now, and changed to “protected” later. Scheme uses list, while Java uses vector APIs to implement “unbounded” stacks. (Recall that Scheme’s built-in vectors are akin to heterogeneous arrays.) cs7100(Prasad) L13Assg

23 throw new Exception(“Stack Empty”); else { --pushed; --localpushed;
... 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; } cs7100(Prasad) L13Assg

24 Approximate Environment
Approximate because the diagram has additional empty boxes after class-var and class-val. Fix: Place a cross in the empty class-var box and view class-val box as signifying a vector. Interpret = Compile + Run Similarly, Run-time Class-Instance Structures = Symbol table Heap (not activation records) * Environment * *Store* compile-time entity run-time entity Note that stack instances will be vector of values, while the class contains instance fields, class env, and method table. cs7100(Prasad) L13Assg

25 Rewrite in Java Stackclass stack1 = new Stackclass();
public class Test { public static void main(String [] args) { 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(); } If the method definition contains n-formals, the method call will take (n+1) arguments because it makes explicit the receiver. cs7100(Prasad) L13Assg

26 Approximate Environment
Approximation: Extra boxes in the diagram. Result after the following evaluations: --> define stack1 = simpleinstance(stackclass) --> define stack2 = simpleinstance(stackclass) --> $push(stack1, 7) cs7100(Prasad) L13Assg

27 Inheritance Share and reuse classes with modifications to fields and methods Improve programmer productivity and aid code evolution Classes provide an organization for the objects in the language. Inheritance and composition are two kinds of relationships among classes. cs7100(Prasad) L13Assg

28 Inheritance in Java Specify only incremental changes.
class Boundedstackclass extends Stack { private int bound; Boundedstackclass() { super(); bound = 10; } public void push(Object x) { if (size() < bound) super.push(x); else new Exception(“Overflow”); public void setbound(int x){ bound = x; Specify only incremental changes. Access parent’s version of a method through super. cs7100(Prasad) L13Assg

29 Composition 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() < bound) stk.push(x); else new Exception(”Overflow”); public void setbound(int x){ bound = x; public Object top() { return stk.top(); ... Explicit list of other delegated stack methods Not as convenient as in message passing style. To simulate that we need to pass a message name and have a switch statement. Delegated message is not dispatched automatically; it requires a small stub code “to pass the buck”. Multiple automatic delegation has similar problems as multiple inheritance. cs7100(Prasad) L13Assg

30 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)) ) )))) Typically, the inherited fields are fixed. All bounded stacks will inherit fields in the parent stack class. Composition and delegation enables substituting objects with same interfaces at run-time. These objects may potentially have different representations. ; (((make-bounded-stack 24) 'top))  cs7100(Prasad) L13Assg

31 Delegation (define stk (make-bounded-stack 24)) ( (stk 'push!) 3)
( (stk 'top) ) (((make-bounded-stack 24) 'push!) 3) ; (((make-bounded-stack 24) 'top)) Typically, the inherited fields are fixed. All bounded stacks will inherit fields in the parent stack class. Composition and delegation enables substituting objects with same interfaces at run-time. These objects may potentially have different representations. ; (((make-bounded-stack 24) 'top)) cs7100(Prasad) L13Assg

32 Delegation 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 For all practical purposes, inheritance can be approximated well using delegation and composition. Given that there is no one way to resolve inheritance conflicts in the context of a DAG class structure, composition and delegation provides a nice mechanism to approximate multiple inheritance of code as illustrated in Java. Fundamental differences show up only when you consider polymorphism issues and updates to public fields and methods. (See our paper in “Computer Languages”.) cs7100(Prasad) L13Assg

33 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(); A.java:9: Variable 'cv’ and ‘iv’ are inherited in local class B (Test. 1$B), and hides a local variable of the same name. An explicit 'this' qualifier must be used to select the variable, or the local must be renamed. System.out.print( ""+ cv + iv ); ========================================================================== JDK 1.0: local variables hide fields. So use “this” for disambiguation. JDK 2.0: access local variables via renaming. Use “this” for fields. NO DEFAULTS. Language design approaches to resolve name conflicts due to multiple definitions due to enclosing class/method and ancestor classes: Both definition meaningful 1.1 Choose one as the default and provide syntactic sugar to get to the other. 1.2 Require the user to always pick one over the other. 2. One definition more appropriate than the other. 2.1 Choose that and ban the other. 2.2 Force user to explicitly pick the appropriate one for pragmatic reasons: minimizing potential errors due to oversight. ===================================================== Typically local variables hide the fields. Any relation to allocating locals on stack and objects on heaps (cf. threads)???? cs7100(Prasad) L13Assg

34 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(); Parent static/instance fields hidden in the event of name conflicts. However, instance methods are dynamically bound. cs7100(Prasad) L13Assg

35 Advanced Topics Multiple Inheritance Meta-classes Inner/Nested classes
E.g., C++, Eiffel. Meta-classes E.g., Smalltalk. Inner/Nested classes E.g., Java. Polymorphic Static Typing E.g., ML, Haskell. cs7100(Prasad) L13Assg


Download ppt "Assignments cs7100(Prasad) L13Assg."

Similar presentations


Ads by Google