 
 
 (defn calculate
-  "Takes a PushDSL blob, a vector of keywords referring to scratch
-  item keys, a function over _those keys_ (using positional notation),
-  and an :as keyword in which to store the result of the function.
-
-  Exceptions when:
-  - [args] is not a vector
-  - no :as argument is present
-  - the wrong number of arguments are provided
-  - (does not check for nil arguments)"
+  "Takes a PushDSL blob, a vector of keywords referring to scratch item keys, a function over _those keys_ (using positional notation), and an :as keyword in which to store the result of the function. Exceptions when: [args] is not a vector, no :as argument is present, the wrong number of arguments are provided. Does not check for nil arguments."
   [[interpreter scratch] args fxn & {:keys [as]}]
   (let [locals (map scratch args)
         result (if (vector? args)



(defn index-from-scratch-ref
  "Takes a keyword and a scratch hashmap. If an integer is stored
  under that key in the hashmap, it's returned. Otherwise raises an
  exception."
  [k locals]
  (let [stored (k locals)]
    (if (number? stored)



(defn save-top-of
  "Takes a PushDSL blob, a stackname (keyword) and a scratch key (also keyword), and copies the top item from that stack into the scratch variable (without deleting it). Exceptions when: no :as argument is present, the stack is empty"
  [[interpreter scratch] stackname & {:keys [as]}]
  (let [old-stack (u/get-stack interpreter stackname)]
    (cond (empty? old-stack) (oops/throw-empty-stack-exception stackname)
