* Lecture 3A Henderson Escher Example
https://youtu.be/PEwZL3H2oKg

last time we talked about compound data

data abstraction,, this strange character 'george'

get used to the idea that procedures can be objects

like representing line segments

: (define make-segment cons)
: (define seg-start car)
: (define seg-start cdr)

the notion of *closure*

closure is the thing that allows us to build complexity

if we'd like to glue together 1, 2, 3, 4
there are lots of ways to do it

((1 2) (3 4))
((1 (2 3)) 4)

lisp likes a list to represent a chain of items

(1 (2 (3 (4 /))))

#+BEGIN_SRC scheme
  (cons 1
	(cons 2
	      (cons 3
		    (cons 4 nil))))
#+END_SRC

list provides the convenience 'list'

#+BEGIN_SRC scheme
  (list 1 2 3 4)
  (define 1-to-4 (list 1 2 3 4))
#+END_SRC

the car of the whole thing is the first item
the second item is the car of the cdr
the third item is the car of the cdr of the cdr
etc

we move thru a list by cdring down a list

#+BEGIN_SRC scheme
  (scale-list 10 1-to-4)
  (define (scale-list s l)
    (if (null? 1)
	nil
	(cons (* (car l) s)
	      (scale-list s (cdr l)))))
#+END_SRC

we should generalize that with a higher order procedure

#+BEGIN_SRC scheme
  (define (map p l)
    (if (null? l)
	nil
	(cons (p (car l))
	      (map p (cdr l)))))
#+END_SRC

scale-list becomes:

#+BEGIN_SRC scheme
  (define (scale-list s l)
    (map (lambda (item) (* item s))
	 l))
#+END_SRC

we could have written map iteratively, or recursively, but once we
start thinking in terms of map, we stop thinking about iter vs recurs,
we think about the aggregate, forgetting the details (control
structure and order)

comes from APL

there is also for-each, which is like map, but does an action to each
item rather than returning a list

#+BEGIN_SRC scheme
  (define (for-each proc list)
    (cond ((null? list) "done")
	  (else (proc (car list))
		(for-each proc
			  (cdr list)))))
#+END_SRC

---> break

we'll spend the rest of the time discussing one example

sums everything up to now, including
  - list structure
  - abstraction
  - representation
  - commonality captured by higher order procedures

will also introduce the 3rd big idea of the course:
  - metalinguistic abstraction

the very most important thing:
  when thinking about a language,
  - primitives
  - means of combination
  - means of abstraction

this example was made up by a fella named Peter Henderson

like escher (geb!!)

a language describes these escherian figures

also gets at that procedures vs data thing

if not already, hopefully will be completely confused about that

this language has one PRIMITIVE:
  - picture

it draws a picture scaled to fill a rectangle

some means of COMBINATION or OPERATION:
  - rotate
  - flip
  - beside
  - above

great complexity can be quickly built courtesy of closure

how is this language implemented?

the basic element is a rectangle, specified by
  - an origin (vector)
  - a horizontal part (vector)
  - a vertical part (vector)

we can assume we have
  - make-rect
  - horiz
  - vert
  - origin

to map points to a rectangle
#+BEGIN_SRC scheme
  (define (coord-map rect)
    (lambda (point)
      (+vect
       (+vect (scale (xcor point)
		     (horiz rect))
	      (scale (ycor point)
		     (vert rect)))
       (origin rect))))
#+END_SRC

how do we get an image to start with?

#+BEGIN_SRC scheme
  ;; Constructing Primitive Pictures
  ;;    from Lists of Segments

  (define (make-picture seglist)
    (lambda (rect)
      (for-each
       (lambda (s)
	 (drawline
	  ((coord-map rect) (seg-start s))
	  ((coord-map rect) (seg-end s))))
       seglist)))
#+END_SRC

eg,
#+BEGIN_SRC scheme
  (define r (make-rect ...))
  (define g (make-picture ...))
  (g r) ;; draws g in r
#+END_SRC

---> break

why's it nice?

once the primitive elements have been defined, means of combination
just fall out

#+BEGIN_SRC scheme
  (define (beside p1 p2 a)
    (lambda (rect)
      (p1 (make-rect
	   (origin rect)
	   (scale a (horiz rect))
	   (vert rect)))
      (p2 (make-rect
	   (+vect (origin rect)
		  (scale a (horiz rect)))
	   (scale (- 1 a) (horiz rect))
	   (vert rect)))))
#+END_SRC

#+BEGIN_SRC scheme
  (define (rotate90 pict)
    (lambda (rect)
      (pict (make-rect
	     (+vect (origin rect)
		    (horiz rect))
	     (vert rect)
	     (scale -1 (horiz rect))))))
#+END_SRC

the real punch line comes with the means of abstraction in this
language

this language is not only /implemented/ in lisp but /embedded/

all the power of lisp is available to us

#+BEGIN_SRC scheme
  (define (right-push p n a)
    (if (= n 0)
	p
	(beside p (right-push p
			      (- n 1)
			      a)
		a)))
#+END_SRC

for some convoluted higer order procedures,
#+BEGIN_SRC scheme
  (define (push comb)
    (λ (pict n a)
      ((repeated
	(λ (p) (comb pict p a))
	n)
       pict)))

  (define right-push (push beside))
#+END_SRC

we are trying to nicely embed this language in another (lisp)

there is no difference between data and procedure

is rect a procedure or data? both. neither.


theres a more general point about the structure of a system as the
creating of a language

engineering is creating a language, a sequence of layers of language

harry's wearing sandals!!


              language of
        schemes of combination
    --------------------------------
              language of
          geometric positions
    --------------------------------
              language of 
            primitive picts

in traditional "engineering", each thing is defined to do one thing
in lisp, things are designed to talk about entire realms of ideas
