Every programming language has what we call a "memory model", a way of 
organizing the data that arise while running a program.  Scheme's
memory model contains two main layers, denoted by [] and () below:

	x ----> [] -------------> 'a
	y ----> [] -------------> 4
 an-entry ----> [] -------------> () --> (make-entry 'kathi 3)
     alon ----> [] -------------> () --> (cons 1 (cons 2 empty))
				 
    variables       environment     store 


Every reference to a piece of scheme data is a box.  Therefore, to be
correct, we need to refine this picture to use value boxes inside the
structured data.
				 
	x -------------> [] -------------> 'a
	y -------------> [] -------------> 4
	                                   3 <--------------
                                           'kathi <------  |
                                                        |  |
 an-entry -------------> [] ------> () --> (make-entry [] [])

	                                   2 <--------------
                                           1 <-----        |
                                                  |        |
     alon -------------> [] ------> () --> (cons [] (cons [] empty))
				 

By this picture, we see that Scheme uses an association between
variables (left) and values (right).  You need to understand how
define, set!, and set-structure! affect this association:

- define extends the association: it adds new associations of
variables to values.

- set! changes the association.  After a set!, the path from a
variable name to a value reaches a different value.  Thus, set!
changes the association, but not the values.

- set-structure! changes the values. It does not change the
association.

Here are three examples of how the above picture changes following
these operations:

1. (define z 5) : creates a new box for z and makes the box refer to 5

	x -------------> [] -------------> 'a
	y -------------> [] -------------> 4
	                                   3 <--------------
                                           'kathi <------  |
                                                        |  |
 an-entry -------------> [] ------> () --> (make-entry [] [])

	                                   2 <--------------
                                           1 <-----        |
                                                  |        |
     alon -------------> [] ------> () --> (cons [] (cons [] empty))

	z -------------> [] -------------> 5

2. (set! y 7)

	x -------------> [] -------------> 'a
                                           4
	y -------------> [] -------------> 7
	                                   3 <--------------
                                           'kathi <------  |
                                                        |  |
 an-entry -------------> [] ------> () --> (make-entry [] [])

	                                   2 <--------------
                                           1 <-----        |
                                                  |        |
     alon -------------> [] ------> () --> (cons [] (cons [] empty))

3. (set-entry-phone! an-entry 4)

	x -------------> [] -------------> 'a
	y -------------> [] -------------> 4 <--------------
	                                   3               |
                                           'kathi <------  |
                                                        |  |
 an-entry -------------> [] ------> () --> (make-entry [] [])

	                                   2 <--------------
                                           1 <-----        |
                                                  |        |
     alon -------------> [] ------> () --> (cons [] (cons [] empty))


New topic : Vectors

The international tennis organization provides rankings of the top 100
tennis players.  For each player, the organization stores his or her
name, home country, and number of matches won.  Since people
frequently ask for statistics on players according to their rank, the
organization wants a program through which they can find the
information for a player with a given ranking.  Develop a data
definition and lookup program for this problem.

;; A player is a structure
;;   (make-player name home wins)
;; where name and home are strings and wins is a number

(define-struct player (name home wins))

;; A ranking is a (listof player) containing 100 elements

;; find-by-rank : ranking number[<=100] -> player 
;; returns the player with the given rank, starting from rank 1
(define (find-by-rank a-ranking player-num)
  (local [(define (helper alop at-num)
	    (cond [(= at-num player-num) (first alop)]
		  [else (helper (rest alop) (add1 at-num))]))]
    (helper a-ranking 1)))

You could also have written

(define (find-by-rank a-ranking player-num)
  (cond [(= player-num 1) (first a-ranking)]
        [else (find-by-rank (rest a-ranking) (sub1 player-num))]))

This program is similar to one built-in to Scheme called list-ref.
List-ref consumes a list L and a number N and returns the Nth element
in L, counting from 0.  We could therefore have written find-by-rank
using list-ref as follows:

(define (find-by-rank a-ranking player-num)
  (list-ref a-ranking (sub1 player-num)))

How long does it take to find a player by her rank?  It depends on the
rank.  Finding the top ranked player requires one call to helper;
finding the 100th ranked player requires 100 calls to helper.  This is
unsatisfying.  Shouldn't we be able to access players in the same
amount of time, regardless of their rank?  To do this, we need a form
of compound data which lets us access each component with the same
amount of work.  This form of compound data is called a vector.

A vector is a form of compound data with a fixed number of components.
Each component is numbered according to its position in the vector,
and we can ask for components by their positions.  If I want to create
a vector containing my three favorite cuisines, for example, I could
do so by writing

> (vector 'thai 'indian 'greek)
(vector 'thai 'indian 'greek)

Given a vector, I can perform several operations on it:

(define V (vector ...))

1. Find out how many components it contains:

   (vector-length V)

2. Retrieve its nth component (counting from 0)

   (vector-ref V n)

3. Update its nth component to a new value

   (vector-set! V n new-val)

Here's an example:

> (define cuisine (vector 'thai 'indian 'greek))
> (vector-length cuisine)
3
> (vector-ref cuisine 1)
'indian
> (vector-set! cuisine 2 'mexican)
> cuisine
(vector 'thai 'indian 'mexican)

Sometimes, we can write a function to describe the values in each
position of a vector based on the position number.  In such cases, we
can use the operator build-vector to create vectors.  Build-vector
consumes a number (the desired length of the vector) and a function
that consumes numbers.  It returns a vector in which the value stored
in position i is the result of the function on i.

> (build-vector 5 (lambda (i) (* i i))) 
(vector 0 1 4 9 16)

Thus (build-vector n f) is equivalent to 
     (vector (f 0) (f 1) ... (f (- n 1))

Unlike list-ref, vector-ref uses the same amount of work to access
every element, regardless of its position in the vector.  Thus,
vectors can be a good data structure to use when:

1. the number of components is fixed, 
2. uniform access to components is required, and
3. numbers are a natural way to index the components.

Thus, vectors are good for problems involving rankings of fixed
numbers of elements, such as our tennis organization problem.
However, they are bad for problems such as address books, because the
numbers are not a natural way to index the entries.

Let's redesign our rankings program using vectors.  The data
definition for players stays the same.

;; A ranking is a vector of 100 players

;; find-by-rank : ranking number[<=100] -> player 
;; returns the player with the given rank, starting from rank 1
(define (find-by-rank a-ranking player-num)
  (vector-ref a-ranking (sub1 player-num)))

How would you create a ranking?  We could write a function to create
an empty ranking, and another to update a ranking with a particular
player in a particular spot:

;; make-ranking : num -> vector
;; creates a vector with all components initialized to false
(define (make-ranking size)
  (build-vector size (lambda (i) false)))

;; rank-player! : ranking num player -> void
;; effect : changes value of ranking in position rank to player
(define (rank-player! a-ranking rank a-player)
  (vector-set! a-ranking rank a-player))

Consider another example.  Vectors are common in mathematics.  A
vector is a k-tuple that specifies some point in a vector space.
There are two important operations on vectors in linear algebra (the
arrows over variables indicate that they are vectors instead of
numbers):
                             -->         -->
      scalar arithmetic : s * v   or  s + v 

                         --> -->     --> -->
      vector arithmetic : v * w   or  v + w

Scalar arithmetic adjusts each element in the vector by the given
number using the given operation.  Vector arithmetic combines two
vectors pairwise according to the given operation.  Let's write
programs to perform scalar and vector arithmetic:

(define (scalar* a-num a-vec)
  (build-vector (vector-length a-vec)
		(lambda (i)
		  (* s (vector-ref a-vec i)))))

Or, more generally:

(define (scalar-arith a-num a-vec an-op)
  (build-vector (vector-length a-vec)
		(lambda (i)
		  (an-op s (vector-ref a-vec i)))))

For vector arithmetic, we need:

(define (vector-arith vec1 vec2 an-op)
  (build-vector (vector-length vec1)
		(lambda (i)
		  (an-op (vector-ref vec1 i)
			 (vector-ref vec2 i)))))