Structure and interpretation of computer programs modularity, objects, and state (part 1)

33
1 Structure and Interpretation of Computer Programs Modularity, Objects, and State (part 1) Abelson & Sussman 2 UC San Diego CSE 294 May 11, 2011 Barry Demchak

Transcript of Structure and interpretation of computer programs modularity, objects, and state (part 1)

1

Structure and Interpretation of Computer

ProgramsModularity, Objects, and State (part 1)

Abelson & Sussman2

UC San DiegoCSE 294

May 11, 2011Barry Demchak

2

Agenda

Functional vs Imperative languages OOP in Functional languages (e.g., Clojure) Data Encapsulation case studies

Simple mutability (persistence) A simple object

Mutability support Failings of the substitution model The environment model Method dispatch

Language comparisons

3

Functional vs Imperative (1/2)

Programming without any use of assignments … is … known as functional programming.p230

Looping via recursion Higher order programming Repeatable function execution memoization Fewer special forms

Programming that makes extensive use of assignment is … imperative programming.p234

Explicit control structures and special forms Introduces significant data dependency

4

Functional vs Imperative (2/2)

Java/C++/Pascalint factAnswer = 1;for (int counter = 2; counter <= n; counter++)

factAnswer = factAnswer * counter;

Maps directly to registers and compare/jump Lisp/Clojure

(defn factorial [n](if (<= n 1)

1(* n (factorial (dec n)))))

Maps to recurrence relation

5

Agenda

Functional vs Imperative languages OOP in Functional languages (e.g., Clojure) Data Encapsulation case studies

Simple mutability (persistence) A simple object

Mutability support Failings of the substitution model The environment model Method dispatch

Language comparisons

6

Object Oriented Programming

Major properties Abstraction Inheritance Polymorphism Data encapsulation

Major uses Manage complexity Multiple instances of stateful entities Orchestration of stateful entities

Key point: Stateful entities change over time

7

Functional Programming vs OOP

Contradiction Repeatable execution requires immutability

Substitution model(defn factorial [n]

(if (<= n 1)1(* n (factorial (dec n)))))

(factorial 3) (* 3 (factorial 2)) (* 3 (* 2 (factorial 1))) (* 3 (* 2 (* 1 1)))

OOP depends on mutability

8

Agenda

Functional vs Imperative languages OOP in Functional languages (e.g., Clojure) Data Encapsulation case studies

Simple mutability (persistence) A simple object

Mutability support Failings of the substitution model The environment model Method dispatch

Language comparisons

9

Bringing OOP to Functional

Abstraction (as seen by Valentin) Inheritance Polymorphism Data Encapsulation …implies mutable state

Suppose a min() function(defn min [x y]

(if (<= x y) x y))where (min 5 6) -> 5

(min 5 6) -> 5 …

Define last-min() to return last min() calculated

10

Simple Persistence

Global persistence

(def last-min (atom 0))

(defn min [x y] (reset! last-min (if (<= x y) x y)))

No encapsulation

Single instance only

(reset! <name> <value>)

(swap! <name> <func>)

11

(defn min-obj [init-min]

(let [last-min (atom init-min)]

(defn do-min [x y]

(reset! last-min (if (<= x y) x y)))

(defn get-last [] (deref last-min))

{:get #(get-last)

:min #(do-min %1 %2)}))

A Min Object

http://thinkrelevance.com/blog/2009/08/12/rifle-oriented-programming-with-clojure-2.html

12

A Min Object

(defn min-obj [init-min]

(let [last-min (atom init-min)]

(defn do-min [x y]

(reset! last-min (if (<= x y) x y)))

(defn get-last [] (deref last-min))

{:get #(get-last)

:min #(do-min %1 %2)}))

(define min1 (min-obj 1000000)) Constructor

13

A Min Object

(defn min-obj [init-min]

(let [last-min (atom init-min)]

(defn do-min [x y]

(reset! last-min (if (<= x y) x y)))

(defn get-last [] (deref last-min))

{:get #(get-last)

:min #(do-min %1 %2)}))

(define min1 (min-obj 1000000))((min1 :min) 5 6) Call to min()

14

A Min Object

(defn min-obj [init-min]

(let [last-min (atom init-min)]

(defn do-min [x y]

(reset! last-min (if (<= x y) x y)))

(defn get-last [] (deref last-min))

{:get #(get-last)

:min #(do-min %1 %2)}))

(define min1 (min-obj 1000000))((min1 :min) 5 6)((min1 :get)) Fetch last min

15

Agenda

Functional vs Imperative languages OOP in Functional languages (e.g., Clojure) Data Encapsulation case studies

Simple mutability (persistence) A simple object

Mutability support Failings of the substitution model The environment model Method dispatch

Language comparisons

16

(defn min-obj [init-min]

(let [last-min (atom init-min)]

(defn do-min [x y]

(reset! last-min (if (<= x y) x y)))

(defn get-last [] (deref last-min))

{:get #(get-last)

:min #(do-min %1 %2)}))

(define min1 (min-obj 1000000))((min1 :get))

The Problem: Binding last-min

17

The Solution: Environments

Global environment

min:

other variables

parameters: x ybody: (if …)

(defn min [x y] (if (<= x y) x y))

What happens when you define min():

18

The Solution: Environments

Global environment

min:

other variables

parameters: x ybody: (if …)

(defn min [x y] (if (<= x y) x y))

What happens when you define min():

19

Simple Execution

What happens when you execute min():

Global environment

min:

other variables

parameters: x ybody: (if …)

(min 5 6)

E1 environmentx: 5y: 6

(if …)

20

Simple Execution

What happens when you execute min():

Global environment

min:

other variables

parameters: x ybody: (if …)

(min 5 6)

E1 environmentx: 5y: 6

(if …)

Variable references resolved by traversing environment chain

21

(defn min-obj [init-min]

(let [last-min (atom init-min)]

(defn do-min [x y]

(reset! last-min (if (<= x y) x y)))

(defn get-last [] (deref last-min))

{:get #(get-last)

:min #(do-min %1 %2)}))

(define min1 (min-obj 1000000))((min1 :get))

How Does min-obj Get Defined?

22

Object Definition

Global environment

min-obj:

other variables

parameters: init-minbody: (let [... )

(defn min-obj [init-min] (let [...))

What happens when you define min-obj():

23

Object Instantiation

How do you instantiate min-obj():

Global environment

min-obj:

other variables

parameters: init-minbody: (let [... )

(def min1 (min-obj 1000000))

min1:

parameters: body: (:get #(…), :min #(…))

last-min: 1000000do-min: get-last:

Environment E1

parameters: x ybody: (reset! …)

parameters: body: (deref …)

24

Object Instantiation

How do you instantiate min-obj():

Global environment

min-obj:

other variables

parameters: init-minbody: (let [... )

(def min1 (min-obj 1000000))

min1:

parameters: body: (:get #(…), :min #(…))

last-min: 1000000do-min: get-last:

Environment E1

parameters: x ybody: (reset! …)

parameters: body: (deref …)

25

Method Execution

How do you execute min():

Global environment

min-obj:

other variables

parameters: init-minbody: (let [...)

((min1 :min) 5 6)

min1:

parameters: body: (:get #(…), :min #(…))

last-min: 1000000do-min: get-last:

Environment E1

parameters: x ybody: (reset! …)

parameters: body: (deref ...)

E2x: 5y: 6

26

Functional Language OOP

Data encapsulation as a result of Constructor parameter accessible only within

function Binding of internal functions to constructor

parameter allows state retention Other points

Dismantling of environments amenable to access count tracking

Dispatcher can operate on any criteria, and is pre-wired for SOA-style message passing

27

Future Investigation

How to subclass How inheritance works Existing (or desirable) object frameworks Why isn’t OOP very common in Clojure?

28

Agenda

Functional vs Imperative languages OOP in Functional languages (e.g., Clojure) Data Encapsulation case studies

Simple mutability (persistence) A simple object

Mutability support Failings of the substitution model The environment model Method dispatch

Language comparisons

29

Selected Comparisons

Deep Static Scope

Data Encapsulation

Clojure/Lisp Arbitrary depth Yes

Pascal Arbitrary depth Yes, but no instances

Java/C++ No Yes

30

Data Encapsulation Comparison

(defn min-obj [init-min] (let [last-min (atom init-min)] (defn do-min [x y] (reset! last-min (if (<= x y) x y))) (defn get-last [] (deref last-min)) {:get #(get-last) :min #(do-min %1 %2)}))

(define min1 (min-obj 1000000))((min1 :min) 5 6)((min1 :get))

class min_obj { private int last_min; public min_obj(int init_min) { last_min = init_min;} public int min(int x, int y) { last_min = (x <= y ? x : y); return last_min; } public int get () { return last_min;}}

min_obj a = new min_obj(1000000);a.min(5, 6);a.get();

Clojure Java

31

Static Scoping in Pascal

program test;var a : integer; procedure outer(); var b : integer; procedure inner(); var c : integer; begin c := a + b; end; begin b := a; inner(); end;begin a := 0; outer(); end.

Evaluation Stack

a

prev-frame-ptr

b

prev-frame-ptr

c

prev-frame-ptr

Compiler knows stack location of all variables in scope – no traversing

32

Agenda

Functional vs Imperative languages OOP in Functional languages (e.g., Clojure) Data Encapsulation case studies

Simple mutability (persistence) A simple object

Mutability support Failings of the substitution model The environment model Method dispatch

Language comparisons

33

Questions