* Lecture 4A: Pattern Matching and Rule-Based Substitution
  https://youtu.be/_fXQ1SwKjDg

last week we wrote a stylized language for elementary calculus rules

it was very stylized; it followed a dispatch structure

the calculus rules are like this:

:             rule
:  pattern ----------> skeleton
:     |                   |
:     | match             | instantiation
:     |                   |
:     v                   v
: expression |----->  expression
:  source              target

  - pattern :: something that matches
  - skeleton :: something you substitute into to get a new expression

the pattern is matched against the expression (source) and it produces
a new expression (target) by instantiation of a skeleton

instead of stooping to the computers way of understanding these rules,
we are going to bring the computer to us

we will separate the structure from the rules themselves

here are some rules:
#+BEGIN_SRC scheme
  (define deriv-rules
    '(
      ( (dd (?c c) (? v))		0 )
      ( (dd (?v v) (? v))		1 )
      ( (dd (?v u) (? v))		0 )

      ( (dd (+ (? x1) (? x2)) (? v))
	(+ (dd (: x1) (: v))
	   (dd (: x2) (: v)))	  )

      ;; ...
      ))
#+END_SRC

we are making up a language here

'?' we are calling pattern variables in the language we are inventing
':' we are calling skeleton evaluation (substitution objects)

heres some syntax:
#+BEGIN_SRC scheme
  ;; Pattern Match

  ;; foo -- matches exactly foo
  ;; (f a b) -- matches a list whose first element is f,
  ;;					 second is a,
  ;;					 third is b
  ;; (? x) -- matches anything, call it x
  ;; (?c x) -- matches a constant, call it x
  ;; (?v x) -- matches a variable, call it x

  ;; Skeletons

  ;; foo -- instantiates to itself
  ;; (f a b) -- instantiates to a 3-list,
  ;;		results of instantiating each of f, a, b
  ;; (: x) -- instantiates to the value of x as in the pattern matched
#+END_SRC

gjs: "it's so much fun to make up a language"

what would we do with such a thing?

we are going to write a program called Simplifier
#+BEGIN_SRC scheme
  (define dsimp
    (simplifier deriv-rules))

  ;; (dsimp '(dd (+ x y) x))
  ;; -> (+ 1 0)
#+END_SRC

we have a "deck" of rules

:         +----------+
:       +----------+ |
:     +----------+ | |
:   +----------+ | |-+
:   |   RULE   | |-+
:   |  p -- s  |-+
:   +----------+
:
:         "dictionary"
:  +-------+       +--------------+
:  | match | ----> | instantiator | ---+
:  +-------+       +--------------+    |
:     🡑                                |
:     |      *expressions*             |
:     |                                |
:     +--------------------------------+

--> break

THE MATCHER

:                 +--- PATTERN
:                 |
:                 v
:                +---------+
: expression --> | matcher | --> dict
:                +---------+
:                         |
:                         v
:                       dict

the matcher is complicated. i dont think ill reproduce it here

there is a string of case analyses. it ends with the general case,
an important pattern:
#+BEGIN_SRC scheme
  (define (match pat exp dict)
    (cond ((eq? dict 'failed) 'failed)
	  ((atom? pat)
	   ;;...atom patterns
	   )
	  ;; ...
	  ((atom? exp) 'failed)
	  (else
	   (match (cdr pat)
		  (cdr exp)
		  (match (car pat)
			 (car exp)
			 dict)))))
#+END_SRC

gjs sez: "go do a startup, make a couple mega bucks"

we see our first eval/apply! we wont learn about it today tho

--> break

"gigo"
  --> garbage in garbage out

the simplifier is a recursive traversal of an expression, in parts
and in whole.

another idiom:
#+BEGIN_SRC scheme
  (define (simplify-exp exp)
    (try-rules
     (if (compound? exp)
	 (map simplify-exp exp)
	 exp)))
#+END_SRC

the recursion here is _hard_
we dont have to think about it
if we did, we'd get confused

gjs: "learn how to program with abandon
