From 9507eca041da7342cbce87bf5a03404826e4bd2d Mon Sep 17 00:00:00 2001
From: Tom Helmuth <thelmuth@hamilton.edu>
Date: Tue, 2 Nov 2021 10:35:34 -0400
Subject: [PATCH 1/9] Changed all macros to functions.

---
 src/propeller/push/utils/macros.cljc | 58 ++++++++++++++--------------
 1 file changed, 30 insertions(+), 28 deletions(-)

diff --git a/src/propeller/push/utils/macros.cljc b/src/propeller/push/utils/macros.cljc
index f6dd102..bc571fc 100755
--- a/src/propeller/push/utils/macros.cljc
+++ b/src/propeller/push/utils/macros.cljc
@@ -2,34 +2,36 @@
   (:require [propeller.push.core :as push]
             [propeller.push.utils.helpers :refer [get-vector-literal-type]]))
 
-;; Defines a Push instruction as a keyword-function pair, and adds it to the
-;; instruction table
-(defmacro def-instruction
-  [instruction definition]
-  `(swap! push/instruction-table assoc ~instruction ~definition))
+(defn def-instruction
+  "Defines a Push instruction as a keyword-function pair, and adds it to the
+   instruction table"
+  [instruction function]
+  (swap! push/instruction-table assoc instruction function))
 
-;; Given a generic function, e.g. _dup, and a stack type to instantiate it for,
-;; e.g. :char, returns the appropriate stack metadata for that function instance
-(defmacro make-metadata
+(defn make-metadata
+  "Given a generic function, e.g. _dup, and a stack type to instantiate it for,
+   e.g. :char, returns the appropriate stack metadata for that function instance"
   [function stack]
-  `(->> (:stacks (meta ~function))
-        (replace {:elem (get-vector-literal-type ~stack)})
-        (cons ~stack)
-        set
-        (assoc-in (meta ~function) [:stacks])
-        (#(dissoc % :name))))
+  (->> (:stacks (meta function))
+       (replace {:elem (get-vector-literal-type stack)})
+       (cons stack)
+       set
+       (assoc-in (meta function) [:stacks])
+       (#(dissoc % :name))))
 
-;; Given a sequence of stacks, e.g. [:float :integer], and a sequence of suffix
-;; function strings, e.g. [_add, _mult, _eq], automates the generation of all
-;; possible combination instructions, which here would be :float_add, :float_mult,
-;; :float_eq, :integer_add, :integer_mult, and :integer_eq, also transferring
-;; and updating the generic function's stack-type metadata. For some vector
-;; instructions, the placeholder :elem will be replaced with the stack of the
-;; corresponding element type (e.g. for :vector_integer, with :integer)
-(defmacro generate-instructions [stacks functions]
-  `(doseq [stack# ~stacks
-           func# ~functions
-           :let [instruction-name# (keyword (str (name stack#) (:name (meta func#))))
-                 metadata# (make-metadata func# stack#)
-                 new-func# (with-meta (partial func# stack#) metadata#)]]
-     (def-instruction instruction-name# new-func#)))
+(defn generate-instructions
+  "Given a sequence of stacks, e.g. [:float :integer], and a sequence of suffix
+   function strings, e.g. [_add, _mult, _eq], automates the generation of all
+   possible combination instructions, which here would be :float_add, :float_mult,
+   :float_eq, :integer_add, :integer_mult, and :integer_eq, also transferring
+   and updating the generic function's stack-type metadata. For some vector
+   instructions, the placeholder :elem will be replaced with the stack of the
+   corresponding element type (e.g. for :vector_integer, with :integer)"
+  [stacks functions]
+  (doseq [stack stacks
+          func functions]
+    (let [instruction-name (keyword (str (name stack) (:name (meta func))))
+          metadata (make-metadata func stack)
+          new-func (with-meta (partial func stack) metadata)]
+      (println [instruction-name new-func (meta new-func)])
+      (def-instruction instruction-name new-func))))
\ No newline at end of file

From 69a65229fed908323d217924bcaffbd92a358895 Mon Sep 17 00:00:00 2001
From: Tom Helmuth <thelmuth@hamilton.edu>
Date: Tue, 2 Nov 2021 10:37:49 -0400
Subject: [PATCH 2/9] Made Smallest problem not parse printed integer.

---
 src/propeller/problems/software/smallest.cljc | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/propeller/problems/software/smallest.cljc b/src/propeller/problems/software/smallest.cljc
index 9ca4dbb..cefcefe 100755
--- a/src/propeller/problems/software/smallest.cljc
+++ b/src/propeller/problems/software/smallest.cljc
@@ -80,10 +80,7 @@
                          :print))
                      inputs)
         errors (map (fn [correct-output output]
-                      (let [parsed-output (try (read-string output)
-                                               #?(:clj  (catch Exception e 1000.0)
-                                                  :cljs (catch js/Error. e 1000.0)))]
-                        (if (= correct-output parsed-output) 0 1)))
+                      (if (= (str correct-output) output) 0 1))
                     correct-outputs
                     outputs)]
     (assoc individual

From d6ed2456c71a92984a62008cc7404189b92b4db1 Mon Sep 17 00:00:00 2001
From: Tom Helmuth <thelmuth@hamilton.edu>
Date: Tue, 2 Nov 2021 11:11:51 -0400
Subject: [PATCH 3/9] Started changing away from macros in files.

---
 src/propeller/push/instructions/numeric.cljc | 8 ++------
 src/propeller/push/utils/macros.cljc         | 3 +--
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/src/propeller/push/instructions/numeric.cljc b/src/propeller/push/instructions/numeric.cljc
index 8e5b6f9..da5f5d6 100755
--- a/src/propeller/push/instructions/numeric.cljc
+++ b/src/propeller/push/instructions/numeric.cljc
@@ -1,12 +1,8 @@
 (ns propeller.push.instructions.numeric
-  #?(:cljs (:require-macros
-             [propeller.push.utils.macros :refer [def-instruction
-                                                  generate-instructions]]))
   (:require [propeller.push.utils.helpers :refer [make-instruction]]
             [propeller.tools.math :as math]
-            #?(:cljs [cljs.reader :refer [read-string]]
-               :clj [propeller.push.utils.macros :refer [def-instruction
-                                                         generate-instructions]])))
+            [propeller.push.utils.macros :refer [def-instruction
+                                                 generate-instructions]]))
 
 ;; =============================================================================
 ;; FLOAT and INTEGER Instructions (polymorphic)
diff --git a/src/propeller/push/utils/macros.cljc b/src/propeller/push/utils/macros.cljc
index bc571fc..939f831 100755
--- a/src/propeller/push/utils/macros.cljc
+++ b/src/propeller/push/utils/macros.cljc
@@ -33,5 +33,4 @@
     (let [instruction-name (keyword (str (name stack) (:name (meta func))))
           metadata (make-metadata func stack)
           new-func (with-meta (partial func stack) metadata)]
-      (println [instruction-name new-func (meta new-func)])
-      (def-instruction instruction-name new-func))))
\ No newline at end of file
+      (def-instruction instruction-name new-func))))

From a42d23bf7aa867214b86fe98f1390b64e5fc3e11 Mon Sep 17 00:00:00 2001
From: Tom Helmuth <thelmuth@hamilton.edu>
Date: Tue, 2 Nov 2021 11:18:29 -0400
Subject: [PATCH 4/9] Moved push/core.cljc to push/instructions.cljc

---
 src/propeller/genome.cljc                           | 4 ++--
 src/propeller/push/{core.cljc => instructions.cljc} | 2 +-
 src/propeller/push/interpreter.cljc                 | 4 ++--
 src/propeller/push/utils/helpers.cljc               | 6 +++---
 src/propeller/push/utils/macros.cljc                | 4 ++--
 src/propeller/session.cljc                          | 2 +-
 6 files changed, 11 insertions(+), 11 deletions(-)
 rename src/propeller/push/{core.cljc => instructions.cljc} (93%)
 mode change 100755 => 100644

diff --git a/src/propeller/genome.cljc b/src/propeller/genome.cljc
index d032081..70470fe 100755
--- a/src/propeller/genome.cljc
+++ b/src/propeller/genome.cljc
@@ -1,5 +1,5 @@
 (ns propeller.genome
-  (:require [propeller.push.core :as push]
+  (:require [propeller.push.instructions :as instructions]
             [propeller.utils :as utils]))
 
 (defn make-random-plushy
@@ -16,7 +16,7 @@
    (let [plushy (if (:diploid argmap) (map first (partition 2 plushy)) plushy)
          opener? #(and (vector? %) (= (first %) 'open))]    ;; [open <n>] marks opens
      (loop [push ()                                         ;; iteratively build the Push program from the plushy
-            plushy (mapcat #(if-let [n (get push/opens %)] [% ['open n]] [%]) plushy)]
+            plushy (mapcat #(if-let [n (get instructions/opens %)] [% ['open n]] [%]) plushy)]
        (if (empty? plushy)                                  ;; maybe we're done?
          (if (some opener? push)                            ;; done with plushy, but unclosed open
            (recur push '(close))                            ;; recur with one more close
diff --git a/src/propeller/push/core.cljc b/src/propeller/push/instructions.cljc
old mode 100755
new mode 100644
similarity index 93%
rename from src/propeller/push/core.cljc
rename to src/propeller/push/instructions.cljc
index f9d23bd..7761637
--- a/src/propeller/push/core.cljc
+++ b/src/propeller/push/instructions.cljc
@@ -1,4 +1,4 @@
-(ns propeller.push.core)
+(ns propeller.push.instructions)
 
 ;; PushGP instructions are represented as keywords, and stored in an atom. They
 ;; can be either constant literals or functions that take and return a Push state
diff --git a/src/propeller/push/interpreter.cljc b/src/propeller/push/interpreter.cljc
index 9941146..87ec56d 100755
--- a/src/propeller/push/interpreter.cljc
+++ b/src/propeller/push/interpreter.cljc
@@ -1,5 +1,5 @@
 (ns propeller.push.interpreter
-  (:require [propeller.push.core :as push]
+  (:require [propeller.push.instructions :as instructions]
             [propeller.push.state :as state]
             [propeller.push.instructions.input-output :as io]
             [propeller.push.utils.helpers :refer [get-literal-type]]))
@@ -14,7 +14,7 @@
       ;;
       ;; Recognize functional instruction or input instruction
       (keyword? instruction)
-      (if-let [function (instruction @push/instruction-table)]
+      (if-let [function (instruction @instructions/instruction-table)]
         (function popped-state)
         (io/handle-input-instruction popped-state instruction))
       ;;
diff --git a/src/propeller/push/utils/helpers.cljc b/src/propeller/push/utils/helpers.cljc
index 8de76be..4b3b818 100755
--- a/src/propeller/push/utils/helpers.cljc
+++ b/src/propeller/push/utils/helpers.cljc
@@ -1,6 +1,6 @@
 (ns propeller.push.utils.helpers
   (:require [clojure.set]
-            [propeller.push.core :as push]
+            [propeller.push.instructions :as instructions]
             [propeller.push.state :as state]
             [propeller.utils :as u]
             #?(:cljs [goog.string :as gstring])
@@ -29,7 +29,7 @@
 ;; only. Won't include random instructions unless :random is in the set as well
 (defn get-stack-instructions
   [stacks]
-  (doseq [[instruction-name function] @push/instruction-table]
+  (doseq [[instruction-name function] @instructions/instruction-table]
     (assert
       (:stacks (meta function))
       #?(:clj  (format
@@ -38,7 +38,7 @@
          :cljs (gstring/format
                  "ERROR: Instruction %s does not have :stacks defined in metadata."
                  (name instruction-name)))))
-  (for [[instruction-name function] @push/instruction-table
+  (for [[instruction-name function] @instructions/instruction-table
         :when (clojure.set/subset? (:stacks (meta function)) stacks)]
     instruction-name))
 
diff --git a/src/propeller/push/utils/macros.cljc b/src/propeller/push/utils/macros.cljc
index 939f831..08ab01a 100755
--- a/src/propeller/push/utils/macros.cljc
+++ b/src/propeller/push/utils/macros.cljc
@@ -1,12 +1,12 @@
 (ns propeller.push.utils.macros
-  (:require [propeller.push.core :as push]
+  (:require [propeller.push.instructions :as instructions]
             [propeller.push.utils.helpers :refer [get-vector-literal-type]]))
 
 (defn def-instruction
   "Defines a Push instruction as a keyword-function pair, and adds it to the
    instruction table"
   [instruction function]
-  (swap! push/instruction-table assoc instruction function))
+  (swap! instructions/instruction-table assoc instruction function))
 
 (defn make-metadata
   "Given a generic function, e.g. _dup, and a stack type to instantiate it for,
diff --git a/src/propeller/session.cljc b/src/propeller/session.cljc
index d949528..4996b0e 100755
--- a/src/propeller/session.cljc
+++ b/src/propeller/session.cljc
@@ -5,7 +5,7 @@
             [propeller.variation :as variation]
             [propeller.problems.simple-regression :as regression]
             [propeller.problems.string-classification :as string-classif]
-            [propeller.push.core :as push]
+            [propeller.push.instructions :as instructions]
             [propeller.push.interpreter :as interpreter]
             [propeller.push.state :as state]
             [propeller.push.utils.helpers :refer [get-stack-instructions]]))

From 0d58508baede41c408777176f97264b4977936d1 Mon Sep 17 00:00:00 2001
From: Tom Helmuth <thelmuth@hamilton.edu>
Date: Tue, 2 Nov 2021 11:23:21 -0400
Subject: [PATCH 5/9] Moved push/utils/limits.cljc to push/limits.cljc

---
 src/propeller/push/instructions/polymorphic.cljc | 2 +-
 src/propeller/push/{utils => }/limits.cljc       | 2 +-
 src/propeller/push/state.cljc                    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
 rename src/propeller/push/{utils => }/limits.cljc (98%)

diff --git a/src/propeller/push/instructions/polymorphic.cljc b/src/propeller/push/instructions/polymorphic.cljc
index 4635cc4..8f0c113 100755
--- a/src/propeller/push/instructions/polymorphic.cljc
+++ b/src/propeller/push/instructions/polymorphic.cljc
@@ -5,7 +5,7 @@
   (:require [propeller.utils :as utils]
             [propeller.push.state :as state]
             [propeller.push.utils.helpers :refer [make-instruction]]
-            [propeller.push.utils.limits :as limit]
+            [propeller.push.limits :as limit]
             #?(:clj [propeller.push.utils.macros :refer [def-instruction
                                                          generate-instructions]])))
 
diff --git a/src/propeller/push/utils/limits.cljc b/src/propeller/push/limits.cljc
similarity index 98%
rename from src/propeller/push/utils/limits.cljc
rename to src/propeller/push/limits.cljc
index 1e4c7c4..611b13e 100644
--- a/src/propeller/push/utils/limits.cljc
+++ b/src/propeller/push/limits.cljc
@@ -1,4 +1,4 @@
-(ns propeller.push.utils.limits
+(ns propeller.push.limits
   (:require [propeller.utils :as u]))
 
 ;; =============================================================================
diff --git a/src/propeller/push/state.cljc b/src/propeller/push/state.cljc
index 921e2eb..c211198 100755
--- a/src/propeller/push/state.cljc
+++ b/src/propeller/push/state.cljc
@@ -1,5 +1,5 @@
 (ns propeller.push.state
-  (:require [propeller.push.utils.limits :as l]
+  (:require [propeller.push.limits :as l]
             #?(:cljs [goog.string :as gstring])))
 
 ;; Empty push state - all available stacks are empty

From d8c97e29e884681bc125b7d1608ef4143ee1227f Mon Sep 17 00:00:00 2001
From: Tom Helmuth <thelmuth@hamilton.edu>
Date: Tue, 2 Nov 2021 12:37:06 -0400
Subject: [PATCH 6/9] Moved macros and helpers to push/instructions.cljc

---
 src/propeller/problems/PSB2/basement.cljc     |   2 +-
 .../problems/PSB2/bouncing_balls.cljc         |   3 +-
 src/propeller/problems/PSB2/bowling.cljc      |   2 +-
 src/propeller/problems/PSB2/camel_case.cljc   |   2 +-
 src/propeller/problems/PSB2/dice_game.cljc    |   2 +-
 src/propeller/problems/PSB2/fizz_buzz.cljc    |   2 +-
 src/propeller/problems/PSB2/fuel_cost.cljc    |   2 +-
 src/propeller/problems/PSB2/gcd.cljc          |   2 +-
 src/propeller/problems/PSB2/luhn.cljc         |   2 +-
 .../problems/PSB2/middle_character.cljc       |   2 +-
 .../problems/PSB2/paired_digits.cljc          |   2 +-
 .../problems/PSB2/shopping_list.cljc          |   2 +-
 src/propeller/problems/PSB2/snow_day.cljc     |   2 +-
 .../problems/PSB2/solve_boolean.cljc          |   2 +-
 src/propeller/problems/PSB2/spin_words.cljc   |   2 +-
 .../problems/PSB2/square_digits.cljc          |   2 +-
 .../problems/PSB2/substitution_cipher.cljc    |   3 +-
 src/propeller/problems/PSB2/twitter.cljc      |   3 +-
 .../problems/software/number_io.cljc          |   3 +-
 src/propeller/problems/software/smallest.cljc |   3 +-
 src/propeller/push/instructions.cljc          | 121 +++++++++++++++++-
 src/propeller/push/instructions/bool.cljc     |   5 +-
 .../push/instructions/character.cljc          |   5 +-
 src/propeller/push/instructions/code.cljc     |   5 +-
 .../push/instructions/input_output.cljc       |   6 +-
 src/propeller/push/instructions/numeric.cljc  |   8 +-
 .../push/instructions/polymorphic.cljc        |   9 +-
 src/propeller/push/instructions/string.cljc   |   6 +-
 src/propeller/push/instructions/vector.cljc   |   7 +-
 src/propeller/push/interpreter.cljc           |   5 +-
 src/propeller/push/utils/helpers.cljc         |  86 -------------
 src/propeller/push/utils/macros.cljc          |  36 ------
 src/propeller/session.cljc                    |   5 +-
 33 files changed, 163 insertions(+), 186 deletions(-)
 delete mode 100755 src/propeller/push/utils/helpers.cljc
 delete mode 100755 src/propeller/push/utils/macros.cljc

diff --git a/src/propeller/problems/PSB2/basement.cljc b/src/propeller/problems/PSB2/basement.cljc
index 9358220..2ac4248 100644
--- a/src/propeller/problems/PSB2/basement.cljc
+++ b/src/propeller/problems/PSB2/basement.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.math :as math]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/bouncing_balls.cljc b/src/propeller/problems/PSB2/bouncing_balls.cljc
index 4a9c599..f7e5c88 100644
--- a/src/propeller/problems/PSB2/bouncing_balls.cljc
+++ b/src/propeller/problems/PSB2/bouncing_balls.cljc
@@ -3,9 +3,8 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
-            [clojure.pprint :as pprint]
             [propeller.tools.math :as math]
             [propeller.gp :as gp]
             #?(:cljs [cljs.reader :refer [read-string]])))
diff --git a/src/propeller/problems/PSB2/bowling.cljc b/src/propeller/problems/PSB2/bowling.cljc
index 773fdff..70d4613 100644
--- a/src/propeller/problems/PSB2/bowling.cljc
+++ b/src/propeller/problems/PSB2/bowling.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.math :as math]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/camel_case.cljc b/src/propeller/problems/PSB2/camel_case.cljc
index 5348284..99b20be 100644
--- a/src/propeller/problems/PSB2/camel_case.cljc
+++ b/src/propeller/problems/PSB2/camel_case.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.metrics :as metrics]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/dice_game.cljc b/src/propeller/problems/PSB2/dice_game.cljc
index bce6587..ee1ec07 100644
--- a/src/propeller/problems/PSB2/dice_game.cljc
+++ b/src/propeller/problems/PSB2/dice_game.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.math :as math]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/fizz_buzz.cljc b/src/propeller/problems/PSB2/fizz_buzz.cljc
index 5a0182d..4b892e7 100644
--- a/src/propeller/problems/PSB2/fizz_buzz.cljc
+++ b/src/propeller/problems/PSB2/fizz_buzz.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.metrics :as metrics]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/fuel_cost.cljc b/src/propeller/problems/PSB2/fuel_cost.cljc
index 8ce4561..9d45455 100644
--- a/src/propeller/problems/PSB2/fuel_cost.cljc
+++ b/src/propeller/problems/PSB2/fuel_cost.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.math :as math]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/gcd.cljc b/src/propeller/problems/PSB2/gcd.cljc
index 3fc10d3..f835853 100644
--- a/src/propeller/problems/PSB2/gcd.cljc
+++ b/src/propeller/problems/PSB2/gcd.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.math :as math]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/luhn.cljc b/src/propeller/problems/PSB2/luhn.cljc
index 0e40a88..35f0b63 100644
--- a/src/propeller/problems/PSB2/luhn.cljc
+++ b/src/propeller/problems/PSB2/luhn.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.math :as math]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/middle_character.cljc b/src/propeller/problems/PSB2/middle_character.cljc
index 55925e4..f9a4b18 100644
--- a/src/propeller/problems/PSB2/middle_character.cljc
+++ b/src/propeller/problems/PSB2/middle_character.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.metrics :as metrics]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/paired_digits.cljc b/src/propeller/problems/PSB2/paired_digits.cljc
index 4936c8d..633effb 100644
--- a/src/propeller/problems/PSB2/paired_digits.cljc
+++ b/src/propeller/problems/PSB2/paired_digits.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.math :as math]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/shopping_list.cljc b/src/propeller/problems/PSB2/shopping_list.cljc
index f379f8d..7d922de 100644
--- a/src/propeller/problems/PSB2/shopping_list.cljc
+++ b/src/propeller/problems/PSB2/shopping_list.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.math :as math]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/snow_day.cljc b/src/propeller/problems/PSB2/snow_day.cljc
index 1346545..fd0f94c 100644
--- a/src/propeller/problems/PSB2/snow_day.cljc
+++ b/src/propeller/problems/PSB2/snow_day.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.math :as math]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/solve_boolean.cljc b/src/propeller/problems/PSB2/solve_boolean.cljc
index d9cf85b..12524d2 100644
--- a/src/propeller/problems/PSB2/solve_boolean.cljc
+++ b/src/propeller/problems/PSB2/solve_boolean.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.gp :as gp]
             #?(:cljs [cljs.reader :refer [read-string]])))
diff --git a/src/propeller/problems/PSB2/spin_words.cljc b/src/propeller/problems/PSB2/spin_words.cljc
index ed37706..5698f7a 100644
--- a/src/propeller/problems/PSB2/spin_words.cljc
+++ b/src/propeller/problems/PSB2/spin_words.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.metrics :as metrics]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/square_digits.cljc b/src/propeller/problems/PSB2/square_digits.cljc
index 9aa44cd..bc3bc61 100644
--- a/src/propeller/problems/PSB2/square_digits.cljc
+++ b/src/propeller/problems/PSB2/square_digits.cljc
@@ -3,7 +3,7 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
             [propeller.tools.metrics :as metrics]
             [propeller.gp :as gp]
diff --git a/src/propeller/problems/PSB2/substitution_cipher.cljc b/src/propeller/problems/PSB2/substitution_cipher.cljc
index d297c75..3f83e64 100644
--- a/src/propeller/problems/PSB2/substitution_cipher.cljc
+++ b/src/propeller/problems/PSB2/substitution_cipher.cljc
@@ -3,9 +3,8 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
-            [propeller.tools.math :as math]
             [propeller.tools.metrics :as metrics]
             [propeller.gp :as gp]
             #?(:cljs [cljs.reader :refer [read-string]])))
diff --git a/src/propeller/problems/PSB2/twitter.cljc b/src/propeller/problems/PSB2/twitter.cljc
index 2d95dee..3d70851 100644
--- a/src/propeller/problems/PSB2/twitter.cljc
+++ b/src/propeller/problems/PSB2/twitter.cljc
@@ -3,9 +3,8 @@
             [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.utils :as utils]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.push.state :as state]
-            [propeller.tools.math :as math]
             [propeller.tools.metrics :as metrics]
             [propeller.gp :as gp]
             #?(:cljs [cljs.reader :refer [read-string]])))
diff --git a/src/propeller/problems/software/number_io.cljc b/src/propeller/problems/software/number_io.cljc
index aefcc09..d356743 100755
--- a/src/propeller/problems/software/number_io.cljc
+++ b/src/propeller/problems/software/number_io.cljc
@@ -2,9 +2,8 @@
   (:require [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.push.state :as state]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.utils :as utils]
-            [propeller.push.state :as state]
             [propeller.tools.math :as math]
             [propeller.gp :as gp]
             #?(:cljs [cljs.reader :refer [read-string]])))
diff --git a/src/propeller/problems/software/smallest.cljc b/src/propeller/problems/software/smallest.cljc
index f63887b..4c61033 100755
--- a/src/propeller/problems/software/smallest.cljc
+++ b/src/propeller/problems/software/smallest.cljc
@@ -2,9 +2,8 @@
   (:require [propeller.genome :as genome]
             [propeller.push.interpreter :as interpreter]
             [propeller.push.state :as state]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]
+            [propeller.push.instructions :refer [get-stack-instructions]]
             [propeller.utils :as utils]
-            [propeller.push.state :as state]
             [propeller.gp :as gp]
             #?(:cljs [cljs.reader :refer [read-string]])))
 
diff --git a/src/propeller/push/instructions.cljc b/src/propeller/push/instructions.cljc
index 7761637..d44dd91 100644
--- a/src/propeller/push/instructions.cljc
+++ b/src/propeller/push/instructions.cljc
@@ -1,4 +1,9 @@
-(ns propeller.push.instructions)
+(ns propeller.push.instructions
+  (:require [clojure.set]
+            [propeller.push.state :as state]
+            [propeller.utils :as u]
+            #?(:cljs [goog.string :as gstring])
+            #?(:cljs [goog.string.format])))
 
 ;; PushGP instructions are represented as keywords, and stored in an atom. They
 ;; can be either constant literals or functions that take and return a Push state
@@ -13,3 +18,117 @@
             :exec_k 2
             :exec_s 3
             :exec_y 1})
+
+
+#?(:clj
+   (def cls->type
+     {Boolean    :boolean
+      Short      :integer
+      Integer    :integer
+      Long       :integer
+      BigInteger :integer
+      Double     :float
+      BigDecimal :float
+      Float      :float
+      Character  :char
+      String     :string}))
+
+#?(:cljs
+   (def pred->type
+     [[boolean? :boolean]
+      [int? :integer]
+      [float? :float]
+      [string? :string]
+      [char? :char]]))
+
+(defn get-literal-type
+  "If a piece of data is a literal, return its corresponding stack name
+   e.g. `:integer`. Otherwise, return `nil`."
+  [data]
+  (or (when (vector? data)
+        (if (empty? data)
+          :generic-vector
+          (keyword (str "vector_" (name (get-literal-type (u/first-non-nil data)))))))
+      #?(:clj  (cls->type (type data))
+         :cljs (loop [remaining pred->type]
+                 (let [[pred d-type] (first remaining)]
+                   (cond
+                     (empty? remaining) nil
+                     (pred data) d-type
+                     :else (recur (rest remaining))))))))
+
+(defn get-vector-literal-type
+  "Returns the literal stack corresponding to some vector stack."
+  [vector-stack]
+  (get state/vec-stacks vector-stack))
+
+(defn def-instruction
+  "Defines a Push instruction as a keyword-function pair, and adds it to the
+   instruction table"
+  [instruction function]
+  (swap! instruction-table assoc instruction function))
+
+(defn make-metadata
+  "Given a generic function, e.g. _dup, and a stack type to instantiate it for,
+   e.g. :char, returns the appropriate stack metadata for that function instance"
+  [function stack]
+  (->> (:stacks (meta function))
+       (replace {:elem (get-vector-literal-type stack)})
+       (cons stack)
+       set
+       (assoc-in (meta function) [:stacks])
+       (#(dissoc % :name))))
+
+(defn generate-instructions
+  "Given a sequence of stacks, e.g. [:float :integer], and a sequence of suffix
+   function strings, e.g. [_add, _mult, _eq], automates the generation of all
+   possible combination instructions, which here would be :float_add, :float_mult,
+   :float_eq, :integer_add, :integer_mult, and :integer_eq, also transferring
+   and updating the generic function's stack-type metadata. For some vector
+   instructions, the placeholder :elem will be replaced with the stack of the
+   corresponding element type (e.g. for :vector_integer, with :integer)"
+  [stacks functions]
+  (doseq [stack stacks
+          func functions]
+    (let [instruction-name (keyword (str (name stack) (:name (meta func))))
+          metadata (make-metadata func stack)
+          new-func (with-meta (partial func stack) metadata)]
+      (def-instruction instruction-name new-func))))
+
+
+(defn make-instruction
+  "A utility function for making Push instructions. Takes a state, a function
+   to apply to the args, the stacks to take the args from, and the stack to
+   return the result to. Applies the function to the args (popped from the
+   given stacks), and pushes the result onto the return-stack.
+
+   If the function returns :ignore-instruction, then we will return the
+   initial state unchanged. This allows instructions to fail gracefully
+   without consuming stack values."
+  [state function arg-stacks return-stack]
+  (let [popped-args (state/get-args-from-stacks state arg-stacks)]
+    (if (= popped-args :not-enough-args)
+      state
+      (let [result (apply function (:args popped-args))
+            new-state (:state popped-args)]
+        (if (= result :ignore-instruction)
+          state
+          (state/push-to-stack new-state return-stack result))))))
+
+(defn get-stack-instructions
+  "Given a set of stacks, returns all instructions that operate on those stacks
+   only. Won't include random instructions unless :random is in the set as well"
+  [stacks]
+  (doseq [[instruction-name function] @instruction-table]
+    (assert
+     (:stacks (meta function))
+     #?(:clj  (format
+               "ERROR: Instruction %s does not have :stacks defined in metadata."
+               (name instruction-name))
+        :cljs (gstring/format
+               "ERROR: Instruction %s does not have :stacks defined in metadata."
+               (name instruction-name)))))
+  (for [[instruction-name function] @instruction-table
+        :when (clojure.set/subset? (:stacks (meta function)) stacks)]
+    instruction-name))
+
diff --git a/src/propeller/push/instructions/bool.cljc b/src/propeller/push/instructions/bool.cljc
index 85a1ba2..620fcfa 100755
--- a/src/propeller/push/instructions/bool.cljc
+++ b/src/propeller/push/instructions/bool.cljc
@@ -1,7 +1,6 @@
 (ns propeller.push.instructions.bool
-  #?(:cljs (:require-macros [propeller.push.utils.macros :refer [def-instruction]]))
-  (:require [propeller.push.utils.helpers :refer [make-instruction]]
-            #?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
+  (:require [propeller.push.instructions :refer [def-instruction
+                                                 make-instruction]]))
 
 ;; =============================================================================
 ;; BOOLEAN Instructions
diff --git a/src/propeller/push/instructions/character.cljc b/src/propeller/push/instructions/character.cljc
index 2f5d77b..33e064a 100755
--- a/src/propeller/push/instructions/character.cljc
+++ b/src/propeller/push/instructions/character.cljc
@@ -1,9 +1,8 @@
 (ns propeller.push.instructions.character
-  #?(:cljs (:require-macros [propeller.push.utils.macros :refer [def-instruction]]))
   (:require [propeller.push.state :as state]
-            [propeller.push.utils.helpers :refer [make-instruction]]
             [propeller.tools.character :as char]
-            #?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
+            [propeller.push.instructions :refer [def-instruction
+                                                 make-instruction]]))
 
 ;; =============================================================================
 ;; CHAR Instructions
diff --git a/src/propeller/push/instructions/code.cljc b/src/propeller/push/instructions/code.cljc
index 86e0478..424e558 100755
--- a/src/propeller/push/instructions/code.cljc
+++ b/src/propeller/push/instructions/code.cljc
@@ -1,9 +1,8 @@
 (ns propeller.push.instructions.code
-  #?(:cljs (:require-macros [propeller.push.utils.macros :refer [def-instruction]]))
   (:require [propeller.utils :as utils]
             [propeller.push.state :as state]
-            [propeller.push.utils.helpers :refer [make-instruction]]
-            #?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
+            [propeller.push.instructions :refer [def-instruction
+                                                 make-instruction]]))
 
 ;; =============================================================================
 ;; CODE Instructions
diff --git a/src/propeller/push/instructions/input_output.cljc b/src/propeller/push/instructions/input_output.cljc
index b597c7b..6dc4799 100755
--- a/src/propeller/push/instructions/input_output.cljc
+++ b/src/propeller/push/instructions/input_output.cljc
@@ -1,10 +1,6 @@
 (ns propeller.push.instructions.input-output
-  #?(:cljs (:require-macros
-             [propeller.push.utils.macros :refer [def-instruction
-                                                  generate-instructions]]))
   (:require [propeller.push.state :as state]
-            [propeller.push.utils.helpers :refer [make-instruction]]
-            [propeller.push.utils.macros :refer [def-instruction
+            [propeller.push.instructions :refer [def-instruction
                                                  generate-instructions]]))
 
 ;; =============================================================================
diff --git a/src/propeller/push/instructions/numeric.cljc b/src/propeller/push/instructions/numeric.cljc
index da5f5d6..b9cbf1f 100755
--- a/src/propeller/push/instructions/numeric.cljc
+++ b/src/propeller/push/instructions/numeric.cljc
@@ -1,8 +1,8 @@
 (ns propeller.push.instructions.numeric
-  (:require [propeller.push.utils.helpers :refer [make-instruction]]
-            [propeller.tools.math :as math]
-            [propeller.push.utils.macros :refer [def-instruction
-                                                 generate-instructions]]))
+  (:require [propeller.tools.math :as math]
+            [propeller.push.instructions :refer [def-instruction
+                                                 generate-instructions
+                                                 make-instruction]]))
 
 ;; =============================================================================
 ;; FLOAT and INTEGER Instructions (polymorphic)
diff --git a/src/propeller/push/instructions/polymorphic.cljc b/src/propeller/push/instructions/polymorphic.cljc
index 8f0c113..d744f3c 100755
--- a/src/propeller/push/instructions/polymorphic.cljc
+++ b/src/propeller/push/instructions/polymorphic.cljc
@@ -1,13 +1,10 @@
 (ns propeller.push.instructions.polymorphic
-  #?(:cljs (:require-macros
-             [propeller.push.utils.macros :refer [def-instruction
-                                                  generate-instructions]]))
   (:require [propeller.utils :as utils]
             [propeller.push.state :as state]
-            [propeller.push.utils.helpers :refer [make-instruction]]
             [propeller.push.limits :as limit]
-            #?(:clj [propeller.push.utils.macros :refer [def-instruction
-                                                         generate-instructions]])))
+            [propeller.push.instructions :refer [def-instruction
+                                                 generate-instructions
+                                                 make-instruction]]))
 
 ;; =============================================================================
 ;; Polymorphic Instructions
diff --git a/src/propeller/push/instructions/string.cljc b/src/propeller/push/instructions/string.cljc
index d602430..b7450cd 100755
--- a/src/propeller/push/instructions/string.cljc
+++ b/src/propeller/push/instructions/string.cljc
@@ -1,10 +1,8 @@
 (ns propeller.push.instructions.string
-  #?(:cljs (:require-macros
-             [propeller.push.utils.macros :refer [def-instruction]]))
   (:require [clojure.string :as string]
-            [propeller.push.utils.helpers :refer [make-instruction]]
             [propeller.push.state :as state]
-            #?(:clj [propeller.push.utils.macros :refer [def-instruction]])))
+            [propeller.push.instructions :refer [def-instruction
+                                                 make-instruction]]))
 
 ;; =============================================================================
 ;; STRING Instructions
diff --git a/src/propeller/push/instructions/vector.cljc b/src/propeller/push/instructions/vector.cljc
index a8822f2..4e4687b 100755
--- a/src/propeller/push/instructions/vector.cljc
+++ b/src/propeller/push/instructions/vector.cljc
@@ -1,11 +1,10 @@
 (ns propeller.push.instructions.vector
-  #?(:cljs (:require-macros [propeller.push.utils.macros :refer [generate-instructions]]))
   (:require [clojure.string]
             [propeller.utils :as utils]
             [propeller.push.state :as state]
-            [propeller.push.utils.helpers :refer [get-vector-literal-type
-                                                  make-instruction]]
-            #?(:clj [propeller.push.utils.macros :refer [generate-instructions]])))
+            [propeller.push.instructions :refer [generate-instructions
+                                                 make-instruction
+                                                 get-vector-literal-type]]))
 
 ;; =============================================================================
 ;; VECTOR Instructions
diff --git a/src/propeller/push/interpreter.cljc b/src/propeller/push/interpreter.cljc
index 87ec56d..738537a 100755
--- a/src/propeller/push/interpreter.cljc
+++ b/src/propeller/push/interpreter.cljc
@@ -1,15 +1,14 @@
 (ns propeller.push.interpreter
   (:require [propeller.push.instructions :as instructions]
             [propeller.push.state :as state]
-            [propeller.push.instructions.input-output :as io]
-            [propeller.push.utils.helpers :refer [get-literal-type]]))
+            [propeller.push.instructions.input-output :as io]))
 
 (defn interpret-one-step
   "Takes a Push state and executes the next instruction on the exec stack."
   [state]
   (let [popped-state (state/pop-stack state :exec)
         instruction (first (:exec state))
-        literal-type (get-literal-type instruction)]     ; nil for non-literals
+        literal-type (instructions/get-literal-type instruction)]     ; nil for non-literals
     (cond
       ;;
       ;; Recognize functional instruction or input instruction
diff --git a/src/propeller/push/utils/helpers.cljc b/src/propeller/push/utils/helpers.cljc
deleted file mode 100755
index 4b3b818..0000000
--- a/src/propeller/push/utils/helpers.cljc
+++ /dev/null
@@ -1,86 +0,0 @@
-(ns propeller.push.utils.helpers
-  (:require [clojure.set]
-            [propeller.push.instructions :as instructions]
-            [propeller.push.state :as state]
-            [propeller.utils :as u]
-            #?(:cljs [goog.string :as gstring])
-            #?(:cljs [goog.string.format])))
-
-;; A utility function for making Push instructions. Takes a state, a function
-;; to apply to the args, the stacks to take the args from, and the stack to
-;; return the result to. Applies the function to the args (popped from the
-;; given stacks), and pushes the result onto the return-stack.
-;;
-;; If the function returns :ignore-instruction, then we will return the
-;; initial state unchanged. This allows instructions to fail gracefully
-;; without consuming stack values.
-(defn make-instruction
-  [state function arg-stacks return-stack]
-  (let [popped-args (state/get-args-from-stacks state arg-stacks)]
-    (if (= popped-args :not-enough-args)
-      state
-      (let [result (apply function (:args popped-args))
-            new-state (:state popped-args)]
-        (if (= result :ignore-instruction)
-          state
-          (state/push-to-stack new-state return-stack result))))))
-
-;; Given a set of stacks, returns all instructions that operate on those stacks
-;; only. Won't include random instructions unless :random is in the set as well
-(defn get-stack-instructions
-  [stacks]
-  (doseq [[instruction-name function] @instructions/instruction-table]
-    (assert
-      (:stacks (meta function))
-      #?(:clj  (format
-                 "ERROR: Instruction %s does not have :stacks defined in metadata."
-                 (name instruction-name))
-         :cljs (gstring/format
-                 "ERROR: Instruction %s does not have :stacks defined in metadata."
-                 (name instruction-name)))))
-  (for [[instruction-name function] @instructions/instruction-table
-        :when (clojure.set/subset? (:stacks (meta function)) stacks)]
-    instruction-name))
-
-
-#?(:clj
-   (def cls->type
-     {Boolean    :boolean
-      Short      :integer
-      Integer    :integer
-      Long       :integer
-      BigInteger :integer
-      Double     :float
-      BigDecimal :float
-      Float      :float
-      Character  :char
-      String     :string}))
-
-#?(:cljs
-   (def pred->type
-     [[boolean? :boolean]
-      [int? :integer]
-      [float? :float]
-      [string? :string]
-      [char? :char]]))
-
-(defn get-literal-type
-  "If a piece of data is a literal, return its corresponding stack name
-   e.g. `:integer`. Otherwise, return `nil`."
-  [data]
-  (or (when (vector? data)
-        (if (empty? data)
-          :generic-vector
-          (keyword (str "vector_" (name (get-literal-type (u/first-non-nil data)))))))
-      #?(:clj  (cls->type (type data))
-         :cljs (loop [remaining pred->type]
-                 (let [[pred d-type] (first remaining)]
-                   (cond
-                     (empty? remaining) nil
-                     (pred data) d-type
-                     :else (recur (rest remaining))))))))
-
-(defn get-vector-literal-type
-  "Returns the literal stack corresponding to some vector stack."
-  [vector-stack]
-  (get state/vec-stacks vector-stack))
diff --git a/src/propeller/push/utils/macros.cljc b/src/propeller/push/utils/macros.cljc
deleted file mode 100755
index 08ab01a..0000000
--- a/src/propeller/push/utils/macros.cljc
+++ /dev/null
@@ -1,36 +0,0 @@
-(ns propeller.push.utils.macros
-  (:require [propeller.push.instructions :as instructions]
-            [propeller.push.utils.helpers :refer [get-vector-literal-type]]))
-
-(defn def-instruction
-  "Defines a Push instruction as a keyword-function pair, and adds it to the
-   instruction table"
-  [instruction function]
-  (swap! instructions/instruction-table assoc instruction function))
-
-(defn make-metadata
-  "Given a generic function, e.g. _dup, and a stack type to instantiate it for,
-   e.g. :char, returns the appropriate stack metadata for that function instance"
-  [function stack]
-  (->> (:stacks (meta function))
-       (replace {:elem (get-vector-literal-type stack)})
-       (cons stack)
-       set
-       (assoc-in (meta function) [:stacks])
-       (#(dissoc % :name))))
-
-(defn generate-instructions
-  "Given a sequence of stacks, e.g. [:float :integer], and a sequence of suffix
-   function strings, e.g. [_add, _mult, _eq], automates the generation of all
-   possible combination instructions, which here would be :float_add, :float_mult,
-   :float_eq, :integer_add, :integer_mult, and :integer_eq, also transferring
-   and updating the generic function's stack-type metadata. For some vector
-   instructions, the placeholder :elem will be replaced with the stack of the
-   corresponding element type (e.g. for :vector_integer, with :integer)"
-  [stacks functions]
-  (doseq [stack stacks
-          func functions]
-    (let [instruction-name (keyword (str (name stack) (:name (meta func))))
-          metadata (make-metadata func stack)
-          new-func (with-meta (partial func stack) metadata)]
-      (def-instruction instruction-name new-func))))
diff --git a/src/propeller/session.cljc b/src/propeller/session.cljc
index 4996b0e..c9a159d 100755
--- a/src/propeller/session.cljc
+++ b/src/propeller/session.cljc
@@ -7,8 +7,7 @@
             [propeller.problems.string-classification :as string-classif]
             [propeller.push.instructions :as instructions]
             [propeller.push.interpreter :as interpreter]
-            [propeller.push.state :as state]
-            [propeller.push.utils.helpers :refer [get-stack-instructions]]))
+            [propeller.push.state :as state]))
 
 #_(interpreter/interpret-program
     '(1 2 :integer_add) state/empty-state 1000)
@@ -36,7 +35,7 @@
 ;    1000)
 ;
 ;#_(genome/plushy->push
-;    (genome/make-random-plushy (get-stack-instructions #{:float :integer :exec :boolean}) 20))
+;    (genome/make-random-plushy (instructions/get-stack-instructions #{:float :integer :exec :boolean}) 20))
 ;
 ;#_(gp/gp {:instructions            propeller.problems.software.number-io/instructions
 ;          :error-function          propeller.problems.software.number-io/error-function

From 45a61c86f7cc4567d67f9f1d471f7dcdd0312798 Mon Sep 17 00:00:00 2001
From: Tom Helmuth <thelmuth@hamilton.edu>
Date: Tue, 2 Nov 2021 12:53:39 -0400
Subject: [PATCH 7/9] Added parentheses requirements to 14 instructions that
 did not have them.

---
 src/propeller/push/instructions.cljc | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/propeller/push/instructions.cljc b/src/propeller/push/instructions.cljc
index d44dd91..30a83bc 100644
--- a/src/propeller/push/instructions.cljc
+++ b/src/propeller/push/instructions.cljc
@@ -11,15 +11,40 @@
 
 ;; Number of blocks opened by instructions (default = 0)
 (def opens {:exec_dup 1
+            :exec_dup_times 1
+            :exec_dup_items 0 ; explicitly set to 0 to make it clear that this is intended
+            :exec_eq 0 ; explicitly set to 0 to make it clear that this is intended
+            :exec_pop 1
+            :exec_rot 3
+            :exec_shove 1
+            :exec_swap 2
+            :exec_yank 0 ; explicitly set to 0 to make it clear that this is intended
+            :exec_yank_dup 0 ; explicitly set to 0 to make it clear that this is intended
+            :exec_deep_dup 0 ; explicitly set to 0 to make it clear that this is intended
+            :exec_print 1
             :exec_if  2
             :exec_when 1
             :exec_while 1
             :exec_do_while 1
+            :exec_do_range 1
+            :exec_do_count 1
+            :exec_do_times 1
             :exec_k 2
             :exec_s 3
-            :exec_y 1})
+            :exec_y 1
+            :string_iterate 1
+            :vector_boolean_iterate 1
+            :vector_string_iterate 1
+            :vector_integer_iterate 1
+            :vector_float_iterate 1})
 
 
+#_(generate-instructions
+ [:boolean :char :code :exec :float :integer :string
+  :vector_boolean :vector_float :vector_integer :vector_string]
+ [_dup _dup_times _dup_items _empty _eq _flush _pop _rot _shove
+  _stack_depth _swap _yank _yank_dup _deep_dup])
+
 #?(:clj
    (def cls->type
      {Boolean    :boolean

From 0d3b65734b6f6c891a207551364606a67f9da53e Mon Sep 17 00:00:00 2001
From: Tom Helmuth <thelmuth@hamilton.edu>
Date: Tue, 2 Nov 2021 13:12:12 -0400
Subject: [PATCH 8/9] Updated Smallest and Number IO problems to use
 generations and population parameters same as Clojush

---
 src/propeller/problems/software/number_io.cljc |   4 ++--
 src/propeller/problems/software/smallest.cljc  |   4 ++--
 src/propeller/push/.DS_Store                   | Bin 6148 -> 0 bytes
 3 files changed, 4 insertions(+), 4 deletions(-)
 delete mode 100644 src/propeller/push/.DS_Store

diff --git a/src/propeller/problems/software/number_io.cljc b/src/propeller/problems/software/number_io.cljc
index d356743..a434a44 100755
--- a/src/propeller/problems/software/number_io.cljc
+++ b/src/propeller/problems/software/number_io.cljc
@@ -98,8 +98,8 @@
        :error-function          error-function
        :training-data           (:train train-and-test-data)
        :testing-data            (:test train-and-test-data)
-       :max-generations         500
-       :population-size         500
+       :max-generations         300
+       :population-size         1000
        :max-initial-plushy-size 100
        :step-limit              200
        :parent-selection        :lexicase
diff --git a/src/propeller/problems/software/smallest.cljc b/src/propeller/problems/software/smallest.cljc
index 4c61033..8c7a068 100755
--- a/src/propeller/problems/software/smallest.cljc
+++ b/src/propeller/problems/software/smallest.cljc
@@ -97,8 +97,8 @@
        :error-function          error-function
        :training-data           (:train train-and-test-data)
        :testing-data            (:test train-and-test-data)
-       :max-generations         500
-       :population-size         500
+       :max-generations         300
+       :population-size         1000
        :max-initial-plushy-size 100
        :step-limit              200
        :parent-selection        :lexicase
diff --git a/src/propeller/push/.DS_Store b/src/propeller/push/.DS_Store
deleted file mode 100644
index ac2df55ffa8225678a064b46b36532358a892ac2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 6148
zcmeHKOHRW;4E3}{DxXD{tk8%X^ai6UoS+M~h(rRUl&NU5&ndVHr(nYxF2M<Swnt4u
z8pH}!$d>FkaqRiL8O?`?+@dPxL^C3qLK#QLFnfgmv-V_^JSRXWbv#i;Ic@2IVlUbp
zhsXfW-5KWVkv5pO_WZ$9Z1VCp#uAe|98})Tmw8;Rb#$*kR=A2;R#e-Z=>7BgLNW#$
zU&Z3rvFrO*9~>`cI>J)qg;+Mj_~!0*{PLxn)O7V@{C3T$?JAqj?fcv54h2azV+<Gr
z#=rqFz}q@xda7vF7%&EmfgJ<9KX@o(NLVY%)&V0=0N?~}5tQZn1@!CyhJ>{uJP@a;
zKuvY&iQzOIexKq(!dg+&$w|woC$;R-3q>z~@Oud-7ZlAJ1I9p?fw6wh`24>be*brq
z?8_K12L2TTZjvpt1%{N)*52Uwto6_vC=18cin|mP<S0fgAI0ZT5%@h9fFWV62oJ<A
N0z!isW8hC2_yS|5T)qGR


From c5b9aece9c41789085eaa8c2934524fe2075379c Mon Sep 17 00:00:00 2001
From: Tom Helmuth <thelmuth@hamilton.edu>
Date: Tue, 2 Nov 2021 13:12:46 -0400
Subject: [PATCH 9/9] Fixed issue with translation that caused infinite loops
 if an explicit number of open parentheses is set to 0

---
 src/propeller/genome.cljc            | 7 ++++++-
 src/propeller/push/instructions.cljc | 9 ++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/propeller/genome.cljc b/src/propeller/genome.cljc
index 70470fe..cd71c8c 100755
--- a/src/propeller/genome.cljc
+++ b/src/propeller/genome.cljc
@@ -16,7 +16,12 @@
    (let [plushy (if (:diploid argmap) (map first (partition 2 plushy)) plushy)
          opener? #(and (vector? %) (= (first %) 'open))]    ;; [open <n>] marks opens
      (loop [push ()                                         ;; iteratively build the Push program from the plushy
-            plushy (mapcat #(if-let [n (get instructions/opens %)] [% ['open n]] [%]) plushy)]
+            plushy (mapcat #(let [n (get instructions/opens %)]
+                              (if (and n
+                                       (> n 0))
+                                [% ['open n]]
+                                [%]))
+                           plushy)]
        (if (empty? plushy)                                  ;; maybe we're done?
          (if (some opener? push)                            ;; done with plushy, but unclosed open
            (recur push '(close))                            ;; recur with one more close
diff --git a/src/propeller/push/instructions.cljc b/src/propeller/push/instructions.cljc
index 30a83bc..361c28b 100644
--- a/src/propeller/push/instructions.cljc
+++ b/src/propeller/push/instructions.cljc
@@ -36,15 +36,10 @@
             :vector_boolean_iterate 1
             :vector_string_iterate 1
             :vector_integer_iterate 1
-            :vector_float_iterate 1})
+            :vector_float_iterate 1
+            })
 
 
-#_(generate-instructions
- [:boolean :char :code :exec :float :integer :string
-  :vector_boolean :vector_float :vector_integer :vector_string]
- [_dup _dup_times _dup_items _empty _eq _flush _pop _rot _shove
-  _stack_depth _swap _yank _yank_dup _deep_dup])
-
 #?(:clj
    (def cls->type
      {Boolean    :boolean