Chapter 3: Modularity, Objects, and State

so far we have reviewed the primitive elements of how programs are
made and how those primitive elements can be combined in complex
ways.

we learned the value of abstraction and modular programs.

  - modular :: the nature of a program thot it can be divided
               "naturally" into coherent parts that can be separately
               developed and maintained

we now look towards how to design entire systems. we will look at two
prominent strategies for program construction:
  - objects :: seeing a program as a collection of distinct objects
               whose behaviors may change over time
  - streams :: seeing a program as a flow of information in a system

we will finally discard the substitution model of chapter 1 in favor
of the environment model

* 3.1 assignment and local state
we ordinarily view the world as a collection of independent objects
each of which has state that changes over time.

at this point (in ch 3!!!) we will discuss local state variables and
the assignment operator

** 3.1.1 local state variables
we now have a comptational object with time-varying state

this means:
: (withdraw 25) --> 75
: (withdraw 25) --> 25
: (withdraw 60) --> "Insufficient Funds"
: (withdraw 15) --> 35

these are not pure funtions

when evaluated twice, they yield different results

this is /new/ before, we computed mathematical functions

#+BEGIN_SRC scheme
  (define balance 100)

  (define (withdraw amount)
    (if (>= balance amount)
	(begin (set! balance (- balance amount))
	       balance)
	"Insufficient Funds"))
#+END_SRC

we have the new language features, set! which sets a new value to a
variable: 
: (set! name new-value)

and we have the (begin ... ... ...) form, which returns the value of
its final expression

there's some trouble with that begin variable. we can make it
internal by encapsulating it:
#+BEGIN_SRC scheme
  (define new-withdraw
    (let ((balance 100))
      (lambda (amount)
	(if (>= balance amount)
	    (begin (set! balance (- balance amount))
		   balance)
	    "Insufficient Funds"))))
#+END_SRC

combining set! with local variables is the general technique for
constructing computational objects.

--> here we have just annhialated our substitution model. according to
    it, the above is incomprehensible. we will address later. first, a
    few variations on this new and very exciting theme

#+BEGIN_SRC scheme :session mw
  (define (make-withdraw balance)
    (lambda (amount)
      (if (>= balance amount)
	  (begin (set! balance (- balance amount))
		 balance)
	  "Insufficient Funds")))
#+END_SRC

#+RESULTS:
: make-withdraw

which can be used to make accounts with custom amounts

#+BEGIN_SRC scheme :session mw
  (define W1 (make-withdraw 100))
  (define W2 (make-withdraw 100))
  (W1 50)
  (W2 70)
#+END_SRC

#+RESULTS:
: 30

these two withdrawal accounts are independent of each other

to make a functional bank account:
#+BEGIN_SRC scheme :session bank
  (define (make-account balance)
    (define (withdraw amount)
      (if (>= balance amount)
	  (begin (set! balance (- balance amount))
		 balance)
	  "Insufficient Funds"))
    (define (deposit amount)
      (set! balance (+ balance amount))
      balance)
    (define (dispatch m)
      (cond ((eq? m 'withdraw) withdraw)
	    ((eq? m 'deposit) deposit)
	    (else (error "Unknown request -- MAKE-ACCOUNT"
			 m))))
    dispatch)
#+END_SRC

#+RESULTS:
: make-account

and to use it:
#+BEGIN_SRC scheme :session bank
  (define acc (make-account 100))
  ((acc 'withdraw) 25)
  ((acc 'withdraw) 80)
  ((acc 'deposit) 120)
  ((acc 'withdraw) 60)
#+END_SRC

#+RESULTS:
: 135

and:
#+BEGIN_SRC scheme :session bank
  (define acc2 (make-account 100))
#+END_SRC

#+RESULTS:
: acc2

will be a completely different account

** 3.1.2 the benefits of introducing assignment

with assignment, we can encapsulate state, rather than injecting it
via formal parameters all over the place.

** 3.1.3 the costs of introducing assignment

set! is cool, but it breaks the substitution model.

it breaks all "nice" mathematical models.

the reason it doesnt work is variable scope. like closures, i
think. or like the kind of closure this book said is the wrong thing.


  - functional programming :: as we did in the first two chapters of
       the book, to not use assignment
  - imperative programming :: makes extensive use of assignment

SAMENESS AND CHANGE

  - referentially transparent :: "equals can be substituted for
       equals" without changing the value of an expression

set! violates referential transparency.

