Assignments cs7100(Prasad) L13Assg.

Slides:



Advertisements
Similar presentations
Programming Languages and Paradigms
Advertisements

Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is a good way to learn more about programming languages  Interpreters are.
Assignments and Procs w/Params EOPL3 Chapter 4. Expressible vs. Denotable values Expressible Values –the language can express and compute these –represented.
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.
Cs784(TK)1 Semantics of Procedures and Scopes. Kinds of Scope Static or Lexical scope –determined by structure of program –Scheme, C++, Java, and many.
ISBN Chapter 11 Abstract Data Types and Encapsulation Concepts.
Variables Six properties: Binding times of properties:
Run time vs. Compile time
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
SchemeCOP Introduction to Scheme. SchemeCOP Scheme Meta-language for coding interpreters –“ clean ” semantics Scheme = LISP + ALGOL –simple.
Abstract Data Types and Encapsulation Concepts
Cs784(Prasad)L123Assg1 Assignments. cs784(Prasad)L123Assg2 l-value vs. r-value Pascal/Ada: x := x + 1 C/Java: x = x + 1 l-value = location, address, reference,
1 Chapter 5: Names, Bindings and Scopes Lionel Williams Jr. and Victoria Yan CSci 210, Advanced Software Paradigms September 26, 2010.
MT311 Java Application Development and Programming Languages Li Tak Sing( 李德成 )
OOPs Object oriented programming. Based on ADT principles  Representation of type and operations in a single unit  Available for other units to create.
Cs7100(Prasad)L8Proc1 Procedures. cs7100(Prasad)L8Proc2 Primitive procedures  etc User-defined procedures –Naming a sequence of operations.
MT311 Java Application Development and Programming Languages Li Tak Sing( 李德成 )
ISBN Chapter 11 Abstract Data Types and Encapsulation Concepts.
Object-Oriented Programming Chapter Chapter
OOPs Object oriented programming. Abstract data types  Representationof type and operations in a single unit  Available for other units to create variables.
ISBN Object-Oriented Programming Chapter Chapter
CS412/413 Introduction to Compilers and Translators Spring ’99 Lecture 11: Functions and stack frames.
1 Chapter 11 © 1998 by Addison Wesley Longman, Inc The Concept of Abstraction - The concept of abstraction is fundamental in programming - Nearly.
(1) ICS 313: Programming Language Theory Chapter 11: Abstract Data Types (Data Abstraction)
ISBN Chapter 12 Support for Object-Oriented Programming.
Operational Semantics of Scheme
Functional Programming
Abstract Syntax cs7100 (Prasad) L7AST.
Type Checking and Type Inference
Edited by Original material by Eric Grimson
Abstract Data Types and Encapsulation Concepts
6.001 SICP Variations on a Scheme
6.001 SICP Object Oriented Programming
Java Primer 1: Types, Classes and Operators
CS 326 Programming Languages, Concepts and Implementation
Introduction to Scheme
Interpreters Study Semantics of Programming Languages through interpreters (Executable Specifications) cs7100(Prasad) L8Interp.
Subprograms The basic abstraction mechanism.
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.
11.1 The Concept of Abstraction
Closures and Streams cs784(Prasad) L11Clos
Implementing Recursion
Env. Model Implementation
Abstract Data Types and Encapsulation Concepts
The Metacircular Evaluator
FP Foundations, Scheme In Text: Chapter 14.
Abstract Syntax Prabhaker Mateti 1.
Dynamic Scoping Lazy Evaluation
The Metacircular Evaluator
Procedures App B: SLLGEN 1.
3.7 Variable Assignment Recall instance variables in Python:
Lecture 16: Tables and OOP
The Metacircular Evaluator (Continued)
Streams, Delayed Evaluation and a Normal Order Interpreter
Abstract Syntax cs7100 (Prasad) L7AST.
Lecture 12: Message passing The Environment Model
UNIT V Run Time Environments.
3.6 Interpreter: Recursion
6.001 SICP Variations on a Scheme
Names and Binding In Text: Chapter 5.
Closures and Streams cs7100(Prasad) L11Clos
Assignments and Procs w/Params
topics interpreters meta-linguistic abstraction eval and apply
Lecture 10 Concepts of Programming Languages
Recursive Procedures and Scopes
11.1 The Concept of Abstraction
Chapter 11 Abstraction - The concept of abstraction is fundamental in
Presentation transcript:

Assignments cs7100(Prasad) 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 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

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

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

Extending object (not meta-) language and the interpreter to support variable assignment cs7100(Prasad) 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))) 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

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

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

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

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

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) ) = 1 but (letrec ( (x y) (y 1) ) x ) = error cs7100(Prasad) L13Assg

Simulating Objects and Classes cs7100(Prasad) 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))) ) 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

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

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

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

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

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

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

(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

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

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

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

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

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

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

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

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

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

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

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

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

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

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. 10 70 40 10 70 55 cs7100(Prasad) L13Assg

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