 ; - `remember-stack [stackname :as local]`
 ;    save the entire stack to the `local`
 ;    raise an Exception if it's undefined
-; - `place [stackname item]`
-;    push the item to the named stack
+; - `place [stackname args fn]`
+;    push the results of applying `fn` to the named `args` to the named stack
 ;    raise an Exception if it's undefined
 ; - `replace-stack [stackname new-stack]`
 ;    replace the indicated stack with a new list
 ;    raise an exception if it's undefined
-; - `calculate [fn :as local]
-;    save the result of `fn` under key `local`
+
+
+; restrictions are your friend:
+; every time a `consume` appears, we know one more item is needed from that stack
+; every time `consume-stack` or `count-of` appears, we know we need that type
+; every time `remember stackname :as` happens, we know we need at least 1 item
+; etc ... 
+; In other words, the :needs can be inferred for each instruction from its DSL definition
+
 
 ;; And I THINK that supports all defined Push instructions I've ever seen....
 

; - `consume-stack [stackname :as local]`
;    save the entire stack into `local` and clear it
;    raise an Exception if it's undefined
; - `remember [stackname :as local]`
;    store top item from `stackname` under key `local`
;    raise an Exception if it's empty or undefined

(fact "clear-locals also does what it's supposed to do"
  (let [foo (store-local (make-interpreter) :foo 8)]
    (:locals (clear-locals foo)) => nil))


(defn recall
  [interpreter k]
  (get-in interpreter [:locals k]))


(fact "recall retrieves a named item from :locals of its interpreter"
  (let [foo (store-local (make-interpreter) :foo 8)]
  (recall foo :foo) => 8))

;;


(defn consume
