export experiments

export experiments

error: pathspec 'src/tango/export2.clj' did not match any file(s) known to git

--- src/tango/export2.clj
+++ src/tango/export2.clj
@@ -0,0 +1,150 @@
+(ns tango.export2
+  (:require [clj-time.coerce :as tcr]
+            [clj-time.format :as tf]
+            [clj-time.core :as t]
+            [clojure.data.xml :as xml]
+            [clojure.xml :as cxml]
+            [clojure.zip :as zip]
+            [clojure.data.zip.xml :as zx]
+            ))
+
+(defn get-zip []
+  (let [test-file
+        (slurp (str "test/tango/examples/real-example-kungsor.xml"))]
+    (zip/xml-zip
+      (clojure.xml/parse (java.io.ByteArrayInputStream. (.getBytes test-file))))))
+
+(defn get-xml []
+  (let [test-file
+        (slurp (str "test/tango/examples/real-example-kungsor.xml"))]
+    (clojure.xml/parse (java.io.ByteArrayInputStream. (.getBytes test-file)))))
+
+;(def zipper (get-zip))
+;
+;(zx/attr (first (zx/xml-> zipper :CompData)) :Place)
+;
+;(zx/xml-> zipper :Class)
+;
+;(zx/attr (first (zx/xml-> zipper :ClassList :Class)) :Name)
+;
+;(zx/xml-> zipper :ClassList :Class)
+;
+;(first (zx/xml-> zipper :ClassList :Class))
+;(xml/emit-str (xml/element :Result {:Seq 0}))
+;; Producera ett <Result> i <Results>
+
+;(def zipper (zip/xml-zip (get-xml)))
+;
+;(defn tree-edit
+;  "Take a zipper, a function that matches a pattern in the tree,
+;   and a function that edits the current location in the tree.  Examine the tree
+;   nodes in depth-first order, determine whether the matcher matches, and if so
+;   apply the editor."
+;  [zipper matcher editor]
+;  (loop [loc zipper]
+;    (if (zip/end? loc)
+;      (zip/root loc)
+;      (if-let [matcher-result (matcher loc)]
+;        (let [new-loc (zip/edit loc editor)]
+;          (if (not (= (zip/node new-loc) (zip/node loc)))
+;            (recur (zip/next new-loc))))
+;        (recur (zip/next loc))))))
+;
+;;; match predicate, all book tags
+;(defn match-book? [loc]
+;  (let [tag (:tag (zip/node loc))]
+;    ;; true if tag is of type <path>
+;    (= :Class tag)))
+;
+;(def test-names
+;  {"Hiphop Singel Guld U" "XXXXXXXXXXXXXXXXX"})
+;
+;;; edit function
+;(defn editor [node]
+;  (let [id (-> node :attrs :Name)
+;        new-content (conj
+;                      (:content node)
+;                      (xml/element :price {} "XX"               ;(get test-names id id)
+;                                   ))]
+;    (assoc-in node [:content] new-content)))
+;
+;(def edited (tree-edit zipper match-book? editor))
+;
+;edited
+;(xml/indent-str
+;  edited)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(def raw-xml (get-xml))
+
+;; TODO - kolla om results finns pa icke startade
+(let [content (get-in raw-xml [:content])
+      class-list (nth content 2)
+      class-to-fix (first (filter #(= "Hiphop Singel Brons B1" (:Name (:attrs %))) (:content class-list)))
+      class-results (first (filter #(= :Results (:tag %)) (:content class-to-fix)))
+      new-results (conj (:content class-results) {:tag     :Result
+                                                  :attrs   {:hej "Marten"}
+                                                  :content nil})]
+
+  ;new-results
+  (assoc class-results :content new-results)
+  )
+
+(def new-stuff
+  (clojure.walk/postwalk
+    (fn [form]
+      (cond
+        (= (:tag form) :Class) (if (= (:Name (:attrs form))
+                                      "Hiphop Singel Brons B1")
+                                 {:tag     :Class
+                                  :attrs   {:Name "Changed Class"}
+                                  :content nil}
+                                 form)
+        :else form))
+    raw-xml))
+
+(spit "export3.xml" (with-out-str (clojure.xml/emit new-stuff)))
+
+
+(def raw-xml-2
+  (xml/parse (java.io.FileInputStream. "test/tango/examples/real-example-kungsor.xml")))
+
+(def new-stuff-2
+  (clojure.walk/postwalk
+    (fn [form]
+      (cond
+        (= (:tag form) :Class) (if (= (:Name (:attrs form))
+                                      "Hiphop Singel Brons B1")
+                                 (xml/element :Class {:Name "Changed Class"})
+                                 form)
+        :else form))
+    raw-xml-2))
+
+(spit "export4.xml" (xml/emit-str new-stuff-2))
+
+
+;(defn sanitize [cmp]
+;  (let [index (participant-index cmp)]
+;    (clojure.walk/postwalk
+;      (fn [form]
+;        (cond
+;          ;; replace participant-number with participant id in results
+;          (:result/participant-number form) (dissoc
+;                                              (assoc form :result/participant
+;                                                          {:participant/id
+;                                                           (get index
+;                                                                (:result/participant-number form))})
+;                                              :result/participant-number)
+;
+;          ;; adjudicator id should be in map form for lookup ref.
+;          (:judging/adjudicator form) (assoc form :judging/adjudicator
+;                                                  {:adjudicator/id (:judging/adjudicator form)})
+;
+;          ;; remove nil values
+;          (map? form) (let [m (into {} (remove (comp nil? second) form))]
+;                        (when (seq m)
+;                          m))
+;
+;          :else form))
+;      cmp)))


fix tests

fix tests

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/fhirbase/fhirplace.git/'


!app -> !state

!app -> !state

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/zk/rx.git/'


Stub for new test module: rest-api-test

Stub for new test module: rest-api-test

error: pathspec 'test/hurvinek/rest_api_test.clj' did not match any file(s) known to git

--- test/hurvinek/rest_api_test.clj
+++ test/hurvinek/rest_api_test.clj
@@ -0,0 +1,29 @@
+;
+;  (C) Copyright 2016  Pavel Tisnovsky
+;
+;  All rights reserved. This program and the accompanying materials
+;  are made available under the terms of the Eclipse Public License v1.0
+;  which accompanies this distribution, and is available at
+;  http://www.eclipse.org/legal/epl-v10.html
+;
+;  Contributors:
+;      Pavel Tisnovsky
+;
+
+(ns hurvinek.db-spec-test
+  (:require [clojure.test :refer :all]
+            [hurvinek.rest-api :refer :all]))
+
+;
+; Common functions used by tests.
+;
+
+(defn callable?
+    "Test if given function-name is bound to the real function."
+    [function-name]
+    (clojure.test/function? function-name))
+
+;
+; Tests for various function definitions
+;
+


DSL for writing Query Dicts

DSL for writing Query Dicts

error: pathspec 'test/metabase/test/util/mql.clj' did not match any file(s) known to git

--- test/metabase/test/util/mql.clj
+++ test/metabase/test/util/mql.clj
@@ -0,0 +1,179 @@
+(ns metabase.test.util.mql
+  "DSL for writing metabase QL queries."
+  (:require [clojure.core.match :refer [match]]
+            [clojure.tools.macro :refer :all]
+            [clojure.walk :refer [macroexpand-all]]
+            [metabase.driver :as driver]
+            [metabase.test.data :as data]
+            [metabase.test.data.datasets :as datasets]))
+
+(defn- partition-tokens [keywords tokens]
+  (->> (loop [all [], current-split nil, [token & more] tokens]
+         (cond
+           (not token)                (conj all current-split)
+           (contains? keywords token) (recur (or (when (seq current-split)
+                                                   (conj all current-split))
+                                                 all)
+                                             [token]
+                                             more)
+           :else                      (recur all
+                                             (conj current-split token)
+                                             more)))
+       (map seq)
+       (filter identity)))
+
+(def ^:private ^:const outer-q-tokens
+  '#{with run return})
+
+(def ^:private ^:const inner-q-tokens
+  '#{ag breakout fields filter lim order page tbl})
+
+(defmacro Q:temp-get [& args]
+  `(:id (data/-temp-get ~'db ~@(map name args))))
+
+(defmacro with-id-as [id body]
+  `(symbol-macrolet [~'id ~id]
+     ~(macroexpand-all body)))
+
+(defn resolve-dataset [^clojure.lang.Symbol dataset]
+  (require 'metabase.test.data.dataset-definitions)
+  (var-get (ns-resolve 'metabase.test.data.dataset-definitions dataset)))
+
+(defmacro Q:with-temp-db [dataset body]
+  `(data/with-temp-db [~'db (data/dataset-loader) (resolve-dataset '~dataset)]
+     (symbol-macrolet [~'db-id (:id ~'db)]
+       (macrolet [(~'id [& args#] `(Q:temp-get ~@args#))]
+         ~(macroexpand-all body)))))
+
+(defmacro Q:with [query arg & [arg2 :as more]]
+  (case (keyword arg)
+    :db       `(Q:with-temp-db ~arg2
+                 ~query)
+    :dataset  `(datasets/with-dataset ~(keyword arg2)
+                 ~query)
+    :datasets `(do ~@(for [dataset# more]
+                       `(datasets/with-dataset ~(keyword dataset#)
+                          ~query)))))
+
+(defmacro Q:return [q & args]
+  `(-> ~q ~@args))
+
+(defmacro expand-outer [token form]
+  (macroexpand-all `(symbol-macrolet [~'return Q:return
+                                      ~'run    driver/process-query
+                                      ~'with   Q:with]
+                      (-> ~form ~token))))
+
+(defmacro expand-outer* [[token & tokens] form]
+  (if-not token form
+          `(expand-outer* ~tokens (expand-outer ~token ~form))))
+
+(defmacro expand-inner [& forms]
+  {:database 'db-id
+   :type :query
+   :query `(Q* {} ~@forms)})
+
+(defmacro Q+ [form]
+  `(symbol-macrolet [~'db-id (data/db-id)
+                     ~'id data/id]
+     ~(macroexpand-all form)))
+
+(defmacro Q [& tokens]
+  (let [[outer-tokens inner-tokens] (split-with (complement (partial contains? inner-q-tokens)) tokens)
+        outer-tokens                (partition-tokens outer-q-tokens outer-tokens)
+        inner-tokens                (partition-tokens inner-q-tokens inner-tokens)
+        query                       (macroexpand-all `(expand-inner ~@inner-tokens))]
+    `(Q+ (expand-outer* ~outer-tokens
+                        (macrolet [(~'fl [f#] (let [[~'_ table# field#] (re-matches #"^(?:([^\.]+)\.)?([^\.]+)$" (name f#))]
+                                                `(~'~'id ~(if table# table#
+                                                              ~(second (:source_table (:query query))))
+                                                         ~(keyword field#))))]
+                          ~(macroexpand-all query))))))
+
+(defmacro Q* [acc & [[clause & args] & more]]
+  (if-not clause acc
+          `(Q* ~(macroexpand-all `(~(symbol (format "metabase.test.util.mql/Q:%s" clause)) ~acc ~@args)) ~@more)))
+
+
+;; ## ag
+
+(defmacro Q:ag [query & tokens]
+  (assoc query :aggregation (match (vec tokens)
+                              ['rows]        ["rows"]
+                              ['count]       ["count"]
+                              ['count id]    ["count" `(~'fl ~id)]
+                              ['avg id]      ["avg" `(~'fl ~id)]
+                              ['distinct id] ["distinct" `(~'fl ~id)]
+                              ['stddev id]   ["stddev" `(~'fl ~id)]
+                              ['sum id]      ["sum" `(~'fl ~id)]
+                              ['cum-sum id]  ["cum_sum" `(~'fl ~id)])))
+
+
+;; ## breakout
+
+(defmacro Q:breakout [query & fields]
+  (assoc query :breakout (vec (for [field fields]
+                                `(~'fl ~field)))))
+
+
+;; ## fields
+
+(defmacro Q:fields [query & fields]
+  (assoc query :fields (vec (for [field fields]
+                              `(~'fl ~field)))))
+
+
+;; ## filter
+
+(def ^:private ^:const filter-tokens
+  '#{inside not-null is-null between = != < > <= >=})
+
+(defmacro Q:filter [query & tokens]
+  (assoc query :filter `(Q:filter* ~tokens)))
+
+(defmacro Q:filter* [[subclause & [arg arg2 :as args]]]
+  (case (keyword subclause)
+    :and      `["AND" ~@(for [cl (partition-tokens filter-tokens args)]
+                          `(Q:filter* ~cl))]
+    :or       `["OR"  ~@(for [cl (partition-tokens filter-tokens args)]
+                          `(Q:filter* ~cl))]
+    :inside   (let [{:keys [lat lon]} arg]
+                ["INSIDE" `(~'fl ~(:field lat)) `(~'fl ~(:field lon)) (:max lat) (:min lon) (:min lat) (:max lon)])
+    :not-null ["NOT_NULL" `(~'fl ~arg)]
+    :is-null  ["IS_NULL" `(~'fl ~arg)]
+    :between  (let [[id min max] args]
+                ["BETWEEN" `(~'fl ~id) ~min ~max])
+    :=        ["="  `(~'fl ~arg) arg2]
+    :!=       ["!=" `(~'fl ~arg) arg2]
+    :<        ["<"  `(~'fl ~arg) arg2]
+    :>        [">"  `(~'fl ~arg) arg2]
+    :<=       ["<=" `(~'fl ~arg) arg2]
+    :>=       [">=" `(~'fl ~arg) arg2]))
+
+
+;; ## lim
+
+(defmacro Q:lim [query lim]
+  (assoc query :limit lim))
+
+;; ## order
+(defmacro Q:order [query & fields]
+  (assoc query :order_by (vec (for [field fields]
+                                `(Q:order* ~field)))))
+
+(defmacro Q:order* [field]
+  (let [[_ field +-] (re-matches #"^([^\-+]+)([\-+])?$" (name field))]
+    [`(~'fl ~(symbol field)) (case (keyword (or +- '+))
+                               :+ "ascending"
+                               :- "descending")]))
+
+;; ## page
+(defmacro Q:page [query page items]
+  (assoc query :page {:page page
+                      :items items}))
+
+
+;; ## tbl
+
+(defmacro Q:tbl [query table]
+  (assoc query :source_table `(~'id ~(keyword table))))


STORM-205. Add REST API to Storm UI. removed empty topologies element from cluster-summary.

--- storm-core/src/clj/backtype/storm/ui/core.clj
+++ storm-core/src/clj/backtype/storm/ui/core.clj
@@ -331,7 +331,6 @@
        { "stormVersion" (read-storm-version)
          "nimbusUptime" (pretty-uptime-sec (.get_nimbus_uptime_secs summ))
          "supervisors" (count sups)
-         "topologies" ""
          "slotsTotal" total-slots
          "slotsUsed"  used-slots
          "slotsFree" free-slots


fixes broken assuming we are getting body vs. entire response from API call

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/election-notification-works.git/'


cljs side pixelfont begun

cljs side pixelfont begun

error: pathspec 'src/cljs/infinitelives/pixi/pixelfont.cljs' did not match any file(s) known to git

--- src/cljs/infinitelives/pixi/pixelfont.cljs
+++ src/cljs/infinitelives/pixi/pixelfont.cljs
@@ -0,0 +1,6 @@
+(ns infinitelives.pixi.pixelfont)
+
+(defn load-pixel-font
+  [pixel-font-name texture-key layout]
+
+)


stats

stats

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/clojure-ml/cml.git/'


Refactor: inline item-text-input

Refactor: inline item-text-input

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Reefersleep/sleepydo.git/'


More empty placeholders

More empty placeholders

--- src-cljs/acha.cljs
+++ src-cljs/acha.cljs
@@ -121,8 +121,8 @@
         class  (str "tag repo__status repo__status_" (name status))
         text   (str/capitalize (name status))]
     (s/html
-      [:span {:class class
-              :title (:repo/reason repo text)}
+      [:span (cond-> {:class class}
+               (:repo/reason repo) (assoc :title (:repo/reason repo)))
         text])))

 (r/defc repo [repo]
@@ -211,10 +211,12 @@
         [:form.add_repo {:on-submit (fn [e] (add-repo) (.preventDefault e))}
           [:input {:id "add_repo__input" :type :text :placeholder "Clone URL"}]
          ]
-        [:h1 {:style {:margin-top 100 :margin-bottom 40}} "Last 10 achievements"]
-        [:.laches
-          (for [ach last-aches]
-            (last-ach (d/entity db (.-e ach))))]
+        (when (not-empty last-aches)
+          (list
+            [:h1 {:style {:margin-top 100 :margin-bottom 40}} "Last 10 achievements"]
+            [:.laches
+              (for [ach last-aches]
+                (last-ach (d/entity db (.-e ach))))]))
     ])))

 (r/defc repo-profile [repo aches]
@@ -267,8 +269,11 @@
     (s/html
       [:.users_pane.pane
         [:h1 "Users"]
-        [:ul
-          (map (fn [u] [:li {:key (:db/id u)} (user u (ach-cnt (:db/id u)))]) users)]])))
+        (if (not-empty users)
+          [:ul
+            (map (fn [u] [:li {:key (:db/id u)} (user u (ach-cnt (:db/id u)))]) users)]
+          [:.empty "Nobody achieved anything yet"]
+          )])))

 (r/defc user-achent [achent aches]


add button component

add button component

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/starcity-properties/odin.git/'


Testing JUnit fixtures

Testing JUnit fixtures

--- jvm-runner/test/codewars/runner/java_test.clj
+++ jvm-runner/test/codewars/runner/java_test.clj
@@ -1,10 +1,11 @@
 (ns codewars.runner.java-test
   (:require [clojure.test :refer :all]
             [codewars.core :refer [-main]]
-            [cheshire.core :as json]
-            [codewars.runner :refer [run]])
-  (:import [org.apache.commons.io.output WriterOutputStream]
-           [java.io PrintStream ByteArrayOutputStream]))
+            [cheshire.core :as json])
+  (:import [java.io PrintStream ByteArrayOutputStream]))
+
+(defn subseq? [a b]
+  (some #{a} (partition (count a) 1 b)))

 (defmacro with-java-out-str [& body]
   `(let [original-out# (PrintStream. (. System out))
@@ -39,3 +40,25 @@
        {:language "java"
         :solution "public class Hello {public static void main() {System.out.print(\"Hellooo!\");}}"})
       (is (= "Hellooo!" (with-java-out-str (-main)))))))
+
+(deftest java-test-fixture
+  (testing "-main can handle a junit test"
+    (with-in-str
+      (json/generate-string
+       {:language "java"
+        :solution "public class Solution {
+                   public Solution(){}
+                   public int testthing(){return 3;}}",
+        :fixture "import static org.junit.Assert.assertEquals;
+                  import org.junit.Test;
+                  import org.junit.runners.JUnit4;
+                  public class TestFixture {
+                     public TestFixture(){}
+                     @Test public void myTestFunction(){
+                        Solution s = new Solution();
+                         assertEquals(\"wow\", 3, s.testthing());
+                         System.out.println(\"test out\");}}"})
+      (let [test-out-string (with-java-out-str (-main))]
+        (is (.contains test-out-string "<DESCRIBE::>myTestFunction(TestFixture)"))
+        (is (.contains test-out-string "test out"))
+        (is (.contains test-out-string "<PASSED::>Test Passed<:LF:>"))))))


Another missing file

Another missing file

error: pathspec 'backend/src/circle/util/mongo.clj' did not match any file(s) known to git

--- backend/src/circle/util/mongo.clj
+++ backend/src/circle/util/mongo.clj
@@ -0,0 +1,29 @@
+(ns circle.util.mongo
+  "Fns for working with mongo"
+  (:import org.bson.types.ObjectId)
+  (:use [arohner.utils :only (inspect)]))
+
+(defn object-id
+  "Generate a new object id, return it."
+  []
+  (ObjectId.))
+
+(defn object-id?
+  "True if map m has a mongo id"
+  [m]
+  (boolean (-> m :_id)))
+
+(defn ensure-object-id
+  "Adds a mongo id to m, a clojure map, if it doesn't have one."
+  [coll m]
+  {:post [(identity %)]}
+  (if (not (object-id? m))
+    (assoc m :_id (object-id))
+    m))
+
+(defn ensure-object-id-ref
+  "Same as ensure-object-id, but works on refs of maps."
+  [coll m]
+  (dosync
+   (when (not (object-id? @m))
+     (alter m (constantly (ensure-object-id coll @m))))))


Try a HUGE buffer on the transaction channel

Because why not?

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/scheduled-message-works.git/'


Eliminate unused refers in transactions ns


handle primitive return and paramter types by inlining the form to resolve the primitive type at macroexpansion time

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/aamedina/clojure.llvm.git/'


add nickname to schema

add nickname to schema

Because of the s/Any bit of the schema, this isn't
strictly needed for nicknames to work, but since
we explicitly look for it later, best to have it
here so a developer can see that it can be used.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/election-mail-works.git/'


find reaction nodes

find reaction nodes

error: pathspec 'src/clj/ceres_analytics/cascade.clj' did not match any file(s) known to git

--- src/clj/ceres_analytics/cascade.clj
+++ src/clj/ceres_analytics/cascade.clj
@@ -0,0 +1,54 @@
+(ns ceres-analytics.cascade
+  (:refer-clojure :exclude [find sort])
+  (:require [monger.collection :as mc]
+            [aprint.core :refer [aprint]]
+            [monger.joda-time]
+            [monger.operators :refer :all]
+            [monger.query :refer :all]
+            [ceres-analytics.core :refer [db]]
+            [clj-time.core :as t]))
+
+
+
+(defn find-publications
+  "Find all messages published by user in specific interval"
+  [uid [start end]]
+  (map
+   (fn [{:keys [target]}]
+     (assoc (mc/find-map-by-id @db "messages" target) :type :source))
+   (mc/find-maps @db "pubs" {:source uid
+                             :ts {$gt (t/date-time 2015 3 26 start )
+                                  $lt (t/date-time 2015 3 26 end)}})))
+
+
+(defn find-reactions
+  "doc-string"
+  [mid]
+  (let [group {"replies" 3 "retweets" 4 "shares" 5}]
+    [mid
+     (map
+      (fn [coll]
+        (map
+         (comp find-reactions :source)
+         (mc/find-maps @db coll {:target mid})))
+      (keys group))]))
+
+
+(let [articles (->> (mc/find-maps @db "sources" {:ts {$gt (t/date-time 2015 3 26 12)
+                                                      $lt (t/date-time 2015 3 26 18)}})
+                    (map #(mc/find-map-by-id @db "messages" (:target %))))
+      pubs (->> articles
+                (map
+                 (fn [a]
+                   { (->> {:target (:_id a)}
+                          (mc/find-one-as-map @db "pubs" )
+                          :source
+                          (mc/find-map-by-id @db "users" )
+                          :name)
+                     (vector (:_id a))}))
+                (apply merge-with (comp vec concat)))]
+  (time (count (vec (map
+                     (fn
+                       [[u ps]]
+                       [u (apply merge (map find-reactions ps))])
+                     pubs)))))


Fixed typo.

Fixed typo.

error: pathspec 'src/cljc/cmr/client/graph/impl.cljc' did not match any file(s) known to git

--- src/cljc/cmr/client/graph/impl.cljc
+++ src/cljc/cmr/client/graph/impl.cljc
@@ -0,0 +1,39 @@
+(ns cmr.client.graph.impl
+  "This namespace defines the implementation of the CMR graph client
+  protocols.
+
+  Note that the implementation includes the definitions of the data records
+  used for storing client-specific state."
+ (:require
+   [cmr.client.http.util :as http-util]
+   [cmr.client.http.core :as http]
+   #?(:clj [cmr.client.base :as base]
+      :cljs [cmr.client.base.impl :as base])))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;   Implementation   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defrecord CMRGraphClientData [
+  endpoint
+  token
+  options
+  http-client])
+
+(defn get-movie
+  "See protocol defintion for docstring."
+  ([this query-str]
+   (get-movie this query-str {}))
+  ([this query-str http-options]
+   (-> this
+       :http-client
+       (http/get (base/get-url this (str "/demo/movie/search?q=" query-str))
+                 (http-util/merge-header
+                   http-options (base/get-token-header this))))))
+
+#?(:clj
+(def client-behaviour
+  "A map of method names to implementations.
+
+  Intended for use by the `extend` protocol function."
+  {:get-movie get-movie}))


strips planning works faster

strips planning works faster

git-svn-id: 90c135e2b654d5d39218b235c725b90ec5779e48@385 cd74b5cd-e609-0410-a199-9e5d10d28226

error: pathspec 'src/edu/berkeley/angel/planning.clj' did not match any file(s) known to git

--- src/edu/berkeley/angel/planning.clj
+++ src/edu/berkeley/angel/planning.clj
@@ -0,0 +1,6 @@
+(ns edu.berkeley.angel.planning
+ (:refer-clojure)
+ (:use edu.berkeley.angel.util edu.berkeley.angel.search)
+ (:require (edu.berkeley.angel.planning planning strips))
+ )
+


Work on auto-midi setup.

Work on auto-midi setup.

* Ensure evaluating ns multiple times doesn't have any unwanted side effects by using defence where appropriate.
* Fix issues where midi code is written for an unreleased version of midi-clj
* Create additional midi-device specific event for handling events from a specific device
* Add scheduled fn description

--- src/overtone/studio/midi.clj
+++ src/overtone/studio/midi.clj
@@ -5,50 +5,55 @@
         [overtone.libs.event])
   (:require [overtone.config.log :as log]))

-(def MIDI-POOL (mk-pool))
+(defonce MIDI-POOL (mk-pool))
+(defonce midi-devices* (atom {}))

 (def EXCLUDED-DEVICES #{"Real Time Sequencer" "Java Sound Synthesizer"})

-(def midi-devices* (atom {}))
-
 (defn midi-event
   "Trigger a global midi event."
-  [msg ts]
-  (event [:midi (:command msg)] msg))
+  [dev msg ts]
+  (event [:midi (msg :command)] msg)
+  (event [:midi-device (dev :vendor) (dev :name) (dev :description) (msg :command)] msg))

 (defn- detect-midi-devices
+  "Designed to run periodically and update the midi-devices* atom with
+  the latest list of midi sources."
   []
   (try
-    (let [old-devs (set (keys @midi-devices*))
-          devs (midi-sources)
-          devs (filter #(not (old-devs (:device %))) devs)
-          receivers (doall (filter
-                             (fn [dev]
-                               (try
-                                 (midi-handle-events (midi-in dev) #'midi-event)
-                                 (catch Exception e
-                                   (log/warn "Can't listen to midi devicee: " dev "\n" e)
-                                   false)))
-                             devs))
+    (let [old-devs     (set (keys @midi-devices*))
+          devs         (midi-sources)
+          devs         (filter #(not (old-devs (:device %))) devs)
+          receivers    (doall (filter
+                               (fn [dev]
+                                 (try
+                                   (midi-handle-events (midi-in dev) #(midi-event dev %1 %2))
+                                   true
+                                   (catch Exception e
+                                     (log/warn "Can't listen to midi device: " dev "\n" e)
+                                     false)))
+                               devs))
           device-names (map :name devs)
-          n-devs (count device-names)
-          dev-map (apply hash-map (interleave (map :device devs) receivers))]
+          n-devs       (count device-names)
+          dev-map      (apply hash-map (interleave (map :device devs) receivers))]
       (swap! midi-devices* merge dev-map)
       (when (pos? n-devs)
-        (log/info "Connected " n-devs " midi devices: " device-names)))
+         (log/info "Connected " n-devs " midi devices: " device-names)))
     (catch Exception ex
       (println "Got exception in detect-midi-devices!" ex))))

 ; The rate at which we poll for new midi devices
 (def MIDI-POLL-RATE 2000)

-(def device-poller (every MIDI-POLL-RATE #'detect-midi-devices MIDI-POOL))
+(defonce __DEVICE-POLLER__
+  (every MIDI-POLL-RATE #'detect-midi-devices MIDI-POOL :desc "Check for new midi devices"))

 (defn midi-poly-player
-  "Sets up the event handlers and manages synth instances to easily play a polyphonic
-  instrument with a midi controller.  The play-fn should take the note and velocity as
-  the only two arguments, and the synth should have a gate parameter that can be set to
-  zero when a :note-off event is received.
+  "Sets up the event handlers and manages synth instances to easily play
+  a polyphonic instrument with a midi controller.  The play-fn should
+  take the note and velocity as the only two arguments, and the synth
+  should have a gate parameter that can be set to zero when a :note-off
+  event is received.

     (definst ding
       [note 60 velocity 100 gate 1]
@@ -58,8 +63,7 @@
             env  (env-gen (adsr 0.001 0.1 0.6 0.3) gate :action FREE)]
         (* amp env snd)))

-    (def dinger (midi-poly-player ding))
-  "
+    (def dinger (midi-poly-player ding))"
   [play-fn]
   (let [notes*  (atom {})
         on-key  (keyword (gensym 'note-on))


add core namespace

add core namespace

error: pathspec 'src/main/clojure/telegenic/core.clj' did not match any file(s) known to git

--- src/main/clojure/telegenic/core.clj
+++ src/main/clojure/telegenic/core.clj
@@ -0,0 +1,3 @@
+(ns telegenic.core
+  (:import [org.jcodec.api FrameGrab]))
+


tail recursion

tail recursion

error: pathspec 'src/sandbox/tr/recursion.clj' did not match any file(s) known to git

--- src/sandbox/tr/recursion.clj
+++ src/sandbox/tr/recursion.clj
@@ -0,0 +1,16 @@
+(ns sandbox.tr.recursion)
+
+(defn make-people [first-names last-names]
+  (loop [first-names first-names last-names last-names people []]
+    (if (seq first-names)
+      (recur
+       (rest first-names)
+       (rest last-names)
+       (conj people
+             {:first (first first-names) :last (first last-names)}))
+      people)))
+
+
+
+(def first-names ["1" "2" "3"])
+(def last-names ["A" "B" "C"])


deploy

deploy


Set content-types for files uploaded to s3

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tobias/clojars-web.git/'


La til Clojure-løsning på Cryptocraphic Cipher

error: pathspec 'cryptocraphic_cipher/larstvei.clj' did not match any file(s) known to git

--- cryptocraphic_cipher/larstvei.clj
+++ cryptocraphic_cipher/larstvei.clj
@@ -0,0 +1,45 @@
+(import 'java.util.Base64)
+
+(def signature [0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A])
+
+(defn decode64 [s]
+  (->> (.decode (Base64/getMimeDecoder) s)
+       (map (comp #(mod % 256) (partial + 256)))))
+
+;; From https://github.com/clojure/math.combinatorics
+(defn cartesian-product [& seqs]
+  (let [v-original-seqs (vec seqs)
+        step
+        (fn step [v-seqs]
+          (let [increment
+                (fn [v-seqs]
+                  (loop [i (dec (count v-seqs)), v-seqs v-seqs]
+                    (if (= i -1) nil
+                      (if-let [rst (next (v-seqs i))]
+                        (assoc v-seqs i rst)
+                        (recur (dec i) (assoc v-seqs i (v-original-seqs i)))))))]
+            (when v-seqs
+              (cons (map first v-seqs)
+                    (lazy-seq (step (increment v-seqs)))))))]
+    (when (every? seq seqs)
+      (lazy-seq (step v-original-seqs)))))
+
+(defn matches? [img k]
+  (= signature
+     (map bit-xor (cycle k) img)))
+
+(defn get-key [img]
+  (let [alphabet (map (partial + 97) (range 26))
+        keys ((fn ! [n] (lazy-cat (->> alphabet (repeat n)
+                                      (apply cartesian-product))
+                          (! (inc n)))) 1)]
+    (->> (filter (partial matches? (take 8 img)) keys) first)))
+
+(defn decode [img key]
+  (map bit-xor (cycle key) img))
+
+(let [img (decode64 (slurp *in*))
+      key (get-key img)]
+  (println (apply str (map char key)))
+  (with-open [w (clojure.java.io/output-stream "out.png")]
+    (.write w (byte-array (decode img key)))))


Add in the device Ids to the configuration for the app

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/MitchellJThomas/medir.git/'


defturtle working

defturtle working

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tiagoantao/turtle.git/'


Add acker that does not ack dupes until acks

error: pathspec 'src/onyx/state/ack.clj' did not match any file(s) known to git

--- src/onyx/state/ack.clj
+++ src/onyx/state/ack.clj
@@ -0,0 +1,63 @@
+(ns ^:no-doc onyx.state.ack
+  (:require [taoensso.timbre :refer [info error warn trace fatal] :as timbre]
+            [onyx.extensions :as extensions]
+            [onyx.types :refer [dec-count! inc-count!]]
+            [onyx.static.swap-pair :refer [swap-pair!]]
+            [onyx.log.commands.peer-replica-view :refer [peer-site]]))
+
+(defprotocol AckState
+  (prepare [this id ack-val])
+  (defer [this id ack-val])
+  (ack [this id ack-val]))
+
+(defrecord StandardAcker [peer-replica-view messenger]
+  AckState
+  (prepare [this _ ack-val]
+    (inc-count! ack-val)
+    this)
+
+  (defer [this _ ack-val]
+    this)
+
+  (ack [this _ ack-val]
+    (when (dec-count! ack-val)
+      (when-let [site (peer-site peer-replica-view (:completion-id ack-val))]
+        (extensions/internal-ack-segment messenger site ack-val)))
+    this))
+
+(defrecord DeduplicationAckState [ack-state peer-replica-view messenger]
+  AckState
+  (prepare [this id ack-val]
+    (let [[old-val new-val] (swap-pair! ack-state
+                                        (fn [s]
+                                          (if (s id)
+                                            s
+                                            (assoc s id (list ack-val)))))]
+      (when-not (= old-val new-val)
+        (inc-count! ack-val)))
+    this)
+
+  (defer [this id ack-val]
+    (let [[old-val new-val] (swap-pair! ack-state
+                                        (fn [s]
+                                          (if (s id)
+                                            (update s id conj ack-val)
+                                            s)))]
+      (when-not (= old-val new-val)
+        (inc-count! ack-val))
+      this))
+
+  (ack [this id _]
+    (let [[old-val new-val] (swap-pair! ack-state (fn [s] (dissoc s id)))]
+      (when-not (= old-val new-val)
+        (run! (fn [ack-val]
+                (when (dec-count! ack-val)
+                  (when-let [site (peer-site peer-replica-view (:completion-id ack-val))]
+                    (extensions/internal-ack-segment messenger site ack-val))))
+              (old-val id)))
+      this)))
+
+(defn new-ack-state [task-map peer-replica-view messenger]
+  (if (contains? task-map :onyx/uniqueness-key)
+    (->DeduplicationAckState (atom {}) peer-replica-view messenger)
+    (->StandardAcker peer-replica-view messenger)))


Added tutorial-worksheet, updated for error functions that take/return individuals.

error: pathspec 'tutorial-worksheet.clj' did not match any file(s) known to git

--- tutorial-worksheet.clj
+++ tutorial-worksheet.clj
@@ -0,0 +1,530 @@
+;; gorilla-repl.fileformat = 1
+
+;; **
+;;; # Clojush Tutorial
+;;;
+;;; Lee Spector, lspector@hampshire.edu
+;;;
+;;; This tutorial shows how to use Clojush, a Clojure implementation of the [Push programming language](http://pushlanguage.org) and the PushGP genetic programming system, as a library in your own projects. To download the full system and for instructions for running the examples that are included with it, see the [Clojush github page](https://github.com/lspector/Clojush/tree/c6e9bc5e9835ed3c57703509e5b9fb988ea5f081).
+;;;
+;;; This tutorial was created with [Gorilla REPL](http://gorilla-repl.org). To run this worksheet, or to use the code that it contains in some other worksheet or project, you must include the Clojush dependency in your project's `project.clj` file. This tutorial was created with the dependency of [clojush "2.0.60"].
+;;;
+;;; First, we create a namespace for the code that we will run:
+;; **
+
+;; @@
+(ns tutorial-worksheet)
+;; @@
+;; =>
+;;; {"type":"html","content":"nil","value":"nil"}
+;; <=
+
+;; **
+;;; These expressions provide access to *all* Clojush namespaces:
+;; **
+
+;; @@
+(use 'clojush.ns)
+(use-clojush)
+;; @@
+;; =>
+;;; {"type":"html","content":"nil","value":"nil"}
+;; <=
+
+;; **
+;;; Clojush is an implementation of the Push programming for evolutionary computation, and of the PushGP genetic programming system that evolves Push programs.
+;;;
+;;; Push programs operate on data stacks, with a separate stack for each data type.
+;;;
+;;; A "Push state" is a complete set of data stacks, and the `make-push-state` function returns a Push state with all stacks empty:
+;; **
+
+;; @@
+(make-push-state)
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"html","content":"nil","value":"nil"}],"value":"[:exec nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"html","content":"nil","value":"nil"}],"value":"[:integer nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":char","value":":char"},{"type":"html","content":"nil","value":"nil"}],"value":"[:char nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":string","value":":string"},{"type":"html","content":"nil","value":"nil"}],"value":"[:string nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":zip","value":":zip"},{"type":"html","content":"nil","value":"nil"}],"value":"[:zip nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_integer","value":":vector_integer"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_integer nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_float","value":":vector_float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_boolean","value":":vector_boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_boolean nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_string","value":":vector_string"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_string nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":input","value":":input"},{"type":"html","content":"nil","value":"nil"}],"value":"[:input nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":output","value":":output"},{"type":"html","content":"nil","value":"nil"}],"value":"[:output nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":auxiliary","value":":auxiliary"},{"type":"html","content":"nil","value":"nil"}],"value":"[:auxiliary nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":tag","value":":tag"},{"type":"html","content":"nil","value":"nil"}],"value":"[:tag nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":return","value":":return"},{"type":"html","content":"nil","value":"nil"}],"value":"[:return nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":environment","value":":environment"},{"type":"html","content":"nil","value":"nil"}],"value":"[:environment nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":genome","value":":genome"},{"type":"html","content":"nil","value":"nil"}],"value":"[:genome nil]"}],"value":"#clojush.pushstate.PushState{:exec nil, :code nil, :integer nil, :float nil, :boolean nil, :char nil, :string nil, :zip nil, :vector_integer nil, :vector_float nil, :vector_boolean nil, :vector_string nil, :input nil, :output nil, :auxiliary nil, :tag nil, :return nil, :environment nil, :genome nil}"}
+;; <=
+
+;; **
+;;; What you see here are all of the data stacks included by default in the current version of Clojush.
+;;;
+;;; You can ignore most of them for now. The `:exec` stack is the most important one, since it stores a program while it is being run.
+;;;
+;;; For the sake of this tutorial we'll only be using `:exec` and a few others, so here's a function that shows us just the ones we want:
+;; **
+
+;; @@
+(defn stks
+  "Return a map with just a few of the stacks in a Push state."
+  [push-state]
+  (select-keys push-state
+               [:exec :code :integer :float :boolean]))
+;; @@
+;; =>
+;;; {"type":"html","content":"#'tutorial-worksheet/stks","value":"#'tutorial-worksheet/stks"}
+;; <=
+
+;; @@
+(stks (make-push-state))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"html","content":"nil","value":"nil"}],"value":"[:exec nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"html","content":"nil","value":"nil"}],"value":"[:integer nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"}],"value":"{:exec nil, :code nil, :integer nil, :float nil, :boolean nil}"}
+;; <=
+
+;; **
+;;; Now let's actually run a Push program.
+;;;
+;;; Push is a stack-based language, which means that when the interpreter sees a value it just pushes it on the appropriate stack, and when it sees an instruction it pops any needed arguments from the stacks, executes the instruction, and pushes results back on the appropriate stacks.
+;;;
+;;; Here we run the Push program `(1 2 integer_add)` on an initially empty Push state and return the resulting Push state (with just the stacks we care about):
+;; **
+
+;; @@
+(stks (run-push '(1 2 integer_add)
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"3","value":"3"}],"value":"(3)"}],"value":"[:integer (3)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"}],"value":"{:exec (), :code nil, :integer (3), :float nil, :boolean nil}"}
+;; <=
+
+;; **
+;;; You can see that `3` is on the `:integer` stack at the end because `1+2=3`, and because the program `(1 2 integer_add)` essentially says to first push `1` onto the `:integer` stack, then `2`, and then execute the `integer_add` instruction, which pops two integers and then pushes their sum back on the `:integer` stack.
+;;;
+;;; If you give `run-push` a `true` third argument then it will print the (complete) Push state at each execution step. For this simple example we first see the entire program pushed on to the `:exec` stack. Then we see that the interpreter processes the program list (as it processes all lists) by pushing its elements individually back onto the `:exec` stack (notice that a layer of parentheses is removed in the first step). Then we see the `1` being processed (notice that it moves to the `:integer` stack), and then the `2`, and finally `integer_add`. Then the `:exec` stack is empty and execution terminates:
+;; **
+
+;; @@
+(stks (run-push '(1 2 integer_add)
+                (make-push-state)
+                true))
+;; @@
+;; ->
+;;;
+;;; State after 0 steps:
+;;; :exec = ((1 2 integer_add))
+;;; :code = nil
+;;; :integer = nil
+;;; :float = nil
+;;; :boolean = nil
+;;; :char = nil
+;;; :string = nil
+;;; :zip = nil
+;;; :vector_integer = nil
+;;; :vector_float = nil
+;;; :vector_boolean = nil
+;;; :vector_string = nil
+;;; :input = nil
+;;; :output = nil
+;;; :auxiliary = nil
+;;; :tag = nil
+;;; :return = nil
+;;; :environment = nil
+;;; :genome = nil
+;;;
+;;; State after 1 steps (last step: (...)):
+;;; :exec = (1 2 integer_add)
+;;; :code = nil
+;;; :integer = nil
+;;; :float = nil
+;;; :boolean = nil
+;;; :char = nil
+;;; :string = nil
+;;; :zip = nil
+;;; :vector_integer = nil
+;;; :vector_float = nil
+;;; :vector_boolean = nil
+;;; :vector_string = nil
+;;; :input = nil
+;;; :output = nil
+;;; :auxiliary = nil
+;;; :tag = nil
+;;; :return = nil
+;;; :environment = nil
+;;; :genome = nil
+;;;
+;;; State after 2 steps (last step: 1):
+;;; :exec = (2 integer_add)
+;;; :code = nil
+;;; :integer = (1)
+;;; :float = nil
+;;; :boolean = nil
+;;; :char = nil
+;;; :string = nil
+;;; :zip = nil
+;;; :vector_integer = nil
+;;; :vector_float = nil
+;;; :vector_boolean = nil
+;;; :vector_string = nil
+;;; :input = nil
+;;; :output = nil
+;;; :auxiliary = nil
+;;; :tag = nil
+;;; :return = nil
+;;; :environment = nil
+;;; :genome = nil
+;;;
+;;; State after 3 steps (last step: 2):
+;;; :exec = (integer_add)
+;;; :code = nil
+;;; :integer = (2 1)
+;;; :float = nil
+;;; :boolean = nil
+;;; :char = nil
+;;; :string = nil
+;;; :zip = nil
+;;; :vector_integer = nil
+;;; :vector_float = nil
+;;; :vector_boolean = nil
+;;; :vector_string = nil
+;;; :input = nil
+;;; :output = nil
+;;; :auxiliary = nil
+;;; :tag = nil
+;;; :return = nil
+;;; :environment = nil
+;;; :genome = nil
+;;;
+;;; State after 4 steps (last step: integer_add):
+;;; :exec = ()
+;;; :code = nil
+;;; :integer = (3)
+;;; :float = nil
+;;; :boolean = nil
+;;; :char = nil
+;;; :string = nil
+;;; :zip = nil
+;;; :vector_integer = nil
+;;; :vector_float = nil
+;;; :vector_boolean = nil
+;;; :vector_string = nil
+;;; :input = nil
+;;; :output = nil
+;;; :auxiliary = nil
+;;; :tag = nil
+;;; :return = nil
+;;; :environment = nil
+;;; :genome = nil
+;;;
+;; <-
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"3","value":"3"}],"value":"(3)"}],"value":"[:integer (3)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"}],"value":"{:exec (), :code nil, :integer (3), :float nil, :boolean nil}"}
+;; <=
+
+;; **
+;;; To summarize, when the interpreter sees a value it pushes it onto the appropriate stack. When it sees an instruction it pops the needed arguments and pushes the results onto the appropriate stacks. If there are not sufficient arguments on the stacks then the instruction **does nothing**. And when the interpreter sees a list it simply pushes the contents of the list back onto the `:exec` stack individually.
+;;;
+;;; That's pretty much all you need to know about how the Push interpreter works. Some instructions can do complicated things, including manipulating code on the `:exec` stack (which can create loops and conditionals, etc.), but the Push interpreter just follows the simple rules sketched here and all instructions take values from stacks and push results from stacks.
+;;;
+;;; Here is a slightly more complicated example:
+;; **
+
+;; @@
+(stks (run-push '(5 1.23 integer_add (4) integer_sub
+                  5.67 float_mult)
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"1","value":"1"}],"value":"(1)"}],"value":"[:integer (1)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"6.9741","value":"6.9741"}],"value":"(6.9741)"}],"value":"[:float (6.9741)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"}],"value":"{:exec (), :code nil, :integer (1), :float (6.9741), :boolean nil}"}
+;; <=
+
+;; **
+;;; Notice that the integer and float operations are interleaved, that `integer_add` has no effect because there is only one integer on the stack when it is executed, and that the parentheses around the `4` have no effect.
+;;;
+;;; For every type, there are standard stack manipulation instructions including `dup` (which duplicates the top element),  `pop` (which throws away the top element), `swap` (which exchanges the top two elements), `rot` (which rotates the top three elements, inserting the top element beneath the next two), and `flush` (which empties the stack).
+;;;
+;;; Here's a simple example with `integer_dup`:
+;; **
+
+;; @@
+(stks (run-push '(5 integer_dup integer_mult)
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"25","value":"25"}],"value":"(25)"}],"value":"[:integer (25)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"}],"value":"{:exec (), :code nil, :integer (25), :float nil, :boolean nil}"}
+;; <=
+
+;; **
+;;; These instructions work on the `:exec` stack too, which lets us do things like this:
+;; **
+
+;; @@
+(stks (run-push '(5 10 20 exec_dup integer_mult)
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"1000","value":"1000"}],"value":"(1000)"}],"value":"[:integer (1000)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"}],"value":"{:exec (), :code nil, :integer (1000), :float nil, :boolean nil}"}
+;; <=
+
+;; **
+;;; This might be confusing, because while most Push instructions operate on the things that come before them in the program (looking like "postfix" operations), the `exec_dup` instruction looks like it operates on something that comes after it (like a "prefix" operation).
+;;;
+;;; But this makes sense when you consider how the Push interpreter executes programs, using the `:exec` stack: when `exec_dup` is being executed, `integer_mult` will be on top of the `:exec` stack, so that is what will be duplicated (and subsequently executed).
+;;;
+;;; Now we can also see how parentheses can matter for program execution:
+;; **
+
+;; @@
+(stks (run-push '(5 exec_dup (3 integer_mult))
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"45","value":"45"}],"value":"(45)"}],"value":"[:integer (45)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"}],"value":"{:exec (), :code nil, :integer (45), :float nil, :boolean nil}"}
+;; <=
+
+;; **
+;;; What's going on here is that `exec_dup` duplicates the entire `(3 integer_mult)` expression, so that whole thing ends up getting executed twice.
+;;;
+;;; Manipulating the `:exec` stack provides a lot of power, because a program can grow or change itself as it runs.
+;;;
+;;; Even more fancy code-self-manipulation stuff can be done using the `:code` stack, for which there are many high-level list-processing instructions.
+;;;
+;;; Here's a simple example:
+;; **
+
+;; @@
+(stks (run-push '(code_quote 20 code_quote 2 code_quote
+                  (2 3 integer_mult) code_subst
+                  code_do)
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:code ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"60","value":"60"}],"value":"(60)"}],"value":"[:integer (60)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"}],"value":"{:exec (), :code (), :integer (60), :float nil, :boolean nil}"}
+;; <=
+
+;; **
+;;; What happened here is that `code_subst` substituted `20` for `2` in a piece of code, `(2 3 integer_mult)`, and then `code_do` executed it (by copying it to the `:exec` stack). This is a pretty silly example, but it demonstrates how code it's possible to manipulate code and then execute the manipulated code.
+;;;
+;;; Some instructions may take data from multiple stacks, or push results onto multiple stacks. A simple example of the former are the `eq` instructions, which are implemented for many types. These take two items of the specified type and push `true` on the `:boolean` stack if they are equal, or `false` if they are not:
+;; **
+
+;; @@
+(stks (run-push '(1 2 integer_eq)
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:integer ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"false","value":"false"}],"value":"(false)"}],"value":"[:boolean (false)]"}],"value":"{:exec (), :code nil, :integer (), :float nil, :boolean (false)}"}
+;; <=
+
+;; @@
+(stks (run-push '(1 1 integer_eq)
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:integer ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"true","value":"true"}],"value":"(true)"}],"value":"[:boolean (true)]"}],"value":"{:exec (), :code nil, :integer (), :float nil, :boolean (true)}"}
+;; <=
+
+;; **
+;;; What can you do with those boolean values? Well, there are boolean instructions like `boolean_and`, `boolean_or`, and `boolean_not`, but there are also handy things like `exec_if`:
+;; **
+
+;; @@
+(stks (run-push '(1 2 integer_eq exec_if 123 99.6)
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:integer ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"99.6","value":"99.6"}],"value":"(99.6)"}],"value":"[:float (99.6)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:boolean ()]"}],"value":"{:exec (), :code nil, :integer (), :float (99.6), :boolean ()}"}
+;; <=
+
+;; **
+;;; What happened there? After executing `integer_eq` there was a `false` on top of the `:boolean` stack. The `exec_if` instruction takes the top element of the `:boolean` stack and if it's false then it also removes the top element of the `:exec` stack (which in this case was `123`). If it's `true` then it leaves the top element of the `:exec` stack but removes the *second* element. This means that only one of them will be executed, depending on the answer of the previous boolean expression. Here each branch of the conditional expression was just a single number (one, an integer, and the other, a float), but you could just as well have complex programs in each branch, in parentheses.
+;;;
+;;; Just for kicks, and to show that it can be done, here's a pretty messy program that computes the factorial of a number (`8` in the example) using recursion on the `:code` stack.
+;;;
+;; **
+
+;; @@
+(stks (run-push '(code_quote
+                   (code_quote (integer_pop 1)
+                    code_quote (code_dup integer_dup
+                                1 integer_sub code_do
+                                integer_mult)
+                    integer_dup 2 integer_lt code_if)
+                  code_dup
+                  8
+                  code_do)
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"code_quote","value":"code_quote"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"integer_pop","value":"integer_pop"},{"type":"html","content":"1","value":"1"}],"value":"(integer_pop 1)"},{"type":"html","content":"code_quote","value":"code_quote"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"code_dup","value":"code_dup"},{"type":"html","content":"integer_dup","value":"integer_dup"},{"type":"html","content":"1","value":"1"},{"type":"html","content":"integer_sub","value":"integer_sub"},{"type":"html","content":"code_do","value":"code_do"},{"type":"html","content":"integer_mult","value":"integer_mult"}],"value":"(code_dup integer_dup 1 integer_sub code_do integer_mult)"},{"type":"html","content":"integer_dup","value":"integer_dup"},{"type":"html","content":"2","value":"2"},{"type":"html","content":"integer_lt","value":"integer_lt"},{"type":"html","content":"code_if","value":"code_if"}],"value":"(code_quote (integer_pop 1) code_quote (code_dup integer_dup 1 integer_sub code_do integer_mult) integer_dup 2 integer_lt code_if)"}],"value":"((code_quote (integer_pop 1) code_quote (code_dup integer_dup 1 integer_sub code_do integer_mult) integer_dup 2 integer_lt code_if))"}],"value":"[:code ((code_quote (integer_pop 1) code_quote (code_dup integer_dup 1 integer_sub code_do integer_mult) integer_dup 2 integer_lt code_if))]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"40320","value":"40320"}],"value":"(40320)"}],"value":"[:integer (40320)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:boolean ()]"}],"value":"{:exec (), :code ((code_quote (integer_pop 1) code_quote (code_dup integer_dup 1 integer_sub code_do integer_mult) integer_dup 2 integer_lt code_if)), :integer (40320), :float nil, :boolean ()}"}
+;; <=
+
+;; **
+;;; How does it work? It first pushes a bunch of stuff (let's call this the *recursive definition*) onto the `:code` stack, then duplicates it, then pushes `8` onto the `:integer` stack, and then finally executes `code_do` which will move the top copy of the recursive definition from the `:code` stack to the `:exec` stack, from where it will then be executed. I won't walk through the rest of the process in full detail, but the key thing to notice is that the recursive definition first pushes two bodies of code to the `:code` stack, one for the "base case" of the recursion and one for the "recursive case," and that it then compares the top `:integer` to 2 to decide which of the branches to execute. You can also notice that the first thing in the recursive branch is another call to `code_dup`, which ensures that there will be another copy of the recursive definition on the `:code` stack for further recursion if necessary.
+;;;
+;;; This provides an example of recursion on the `:code` stack, but happily, there are also much simpler ways to compute factorials in Push, for example:
+;;;
+;;;
+;; **
+
+;; @@
+(stks (run-push '(1 8 exec_do*range integer_mult)
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"40320","value":"40320"}],"value":"(40320)"}],"value":"[:integer (40320)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"}],"value":"{:exec (), :code nil, :integer (40320), :float nil, :boolean nil}"}
+;; <=
+
+;; **
+;;; This example uses `exec_do*range`, which is an instruction that loops a body of code that it finds on the `:exec` stack, pushing a counter onto the integer stack before each loop body execution. There are other, related functions too, like `exec_do*count`, `exec_while`, etc.
+;;;
+;;; Since we can do looping and recursion, it's possible to produce code that will run for a very long time, possibly infinitely. Push handles this by imposing an execution step limit:
+;; **
+
+;; @@
+(stks (run-push '(0 true exec_while
+                  (1 integer_add true))
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"1","value":"1"},{"type":"html","content":"integer_add","value":"integer_add"},{"type":"html","content":"true","value":"true"},{"type":"html","content":"exec_while","value":"exec_while"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"1","value":"1"},{"type":"html","content":"integer_add","value":"integer_add"},{"type":"html","content":"true","value":"true"}],"value":"(1 integer_add true)"}],"value":"(1 integer_add true exec_while (1 integer_add true))"}],"value":"[:exec (1 integer_add true exec_while (1 integer_add true))]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"29","value":"29"}],"value":"(29)"}],"value":"[:integer (29)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:boolean ()]"}],"value":"{:exec (1 integer_add true exec_while (1 integer_add true)), :code nil, :integer (29), :float nil, :boolean ()}"}
+;; <=
+
+;; **
+;;; This program pushes `0` on the `:integer` stack, then `true` on the `:boolean` stack, and then starts running a "while" loop that will keep executing as long as it finds `true` on top of the `:boolean` stack. Since the body of the loop itself pushes another `true` (along with adding `1` to the top integer), it will never stop.
+;;;
+;;; But it did stop! And the top integer only got up to `29`. What's going on?
+;;;
+;;; The answer is that it hit the step limit, and returned the state at that point.
+;;;
+;;; The step limit is stored in an atom that we can query this way:
+;; **
+
+;; @@
+@global-evalpush-limit
+;; @@
+;; =>
+;;; {"type":"html","content":"150","value":"150"}
+;; <=
+
+;; **
+;;; So currently it will just run for 150 steps. As for why that gets us only up to `29`, that has to do with the steps required for the other parts of the program and the mechanics of `exec_while`, which does its work by pushing stuff to the `:exec` stack and executing it.
+;;;
+;;; We can change the step limit like this:
+;; **
+
+;; @@
+(reset! global-evalpush-limit 1000)
+;; @@
+;; =>
+;;; {"type":"html","content":"1000","value":"1000"}
+;; <=
+
+;; **
+;;; And then it'll get further before stopping:
+;; **
+
+;; @@
+(stks (run-push '(0 true exec_while
+                  (1 integer_add true))
+                (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"1","value":"1"},{"type":"html","content":"integer_add","value":"integer_add"},{"type":"html","content":"true","value":"true"},{"type":"html","content":"exec_while","value":"exec_while"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"1","value":"1"},{"type":"html","content":"integer_add","value":"integer_add"},{"type":"html","content":"true","value":"true"}],"value":"(1 integer_add true)"}],"value":"(1 integer_add true exec_while (1 integer_add true))"}],"value":"[:exec (1 integer_add true exec_while (1 integer_add true))]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"199","value":"199"}],"value":"(199)"}],"value":"[:integer (199)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:boolean ()]"}],"value":"{:exec (1 integer_add true exec_while (1 integer_add true)), :code nil, :integer (199), :float nil, :boolean ()}"}
+;; <=
+
+;; **
+;;; Incidentally, you can tell whether a call to run-push terminated normally or by hitting the step limit by looking at the `:termination` of the returned Push state. We've been hiding this with our `stks` function, but here's that same call without `stks`, where you can see that the `:termination` is `:abnormal`:
+;; **
+
+;; @@
+(run-push '(0 true exec_while (1 integer_add true))
+          (make-push-state))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"1","value":"1"},{"type":"html","content":"integer_add","value":"integer_add"},{"type":"html","content":"true","value":"true"},{"type":"html","content":"exec_while","value":"exec_while"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"1","value":"1"},{"type":"html","content":"integer_add","value":"integer_add"},{"type":"html","content":"true","value":"true"}],"value":"(1 integer_add true)"}],"value":"(1 integer_add true exec_while (1 integer_add true))"}],"value":"[:exec (1 integer_add true exec_while (1 integer_add true))]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"199","value":"199"}],"value":"(199)"}],"value":"[:integer (199)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:boolean ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":char","value":":char"},{"type":"html","content":"nil","value":"nil"}],"value":"[:char nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":string","value":":string"},{"type":"html","content":"nil","value":"nil"}],"value":"[:string nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":zip","value":":zip"},{"type":"html","content":"nil","value":"nil"}],"value":"[:zip nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_integer","value":":vector_integer"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_integer nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_float","value":":vector_float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_boolean","value":":vector_boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_boolean nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_string","value":":vector_string"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_string nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":input","value":":input"},{"type":"html","content":"nil","value":"nil"}],"value":"[:input nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":output","value":":output"},{"type":"html","content":"nil","value":"nil"}],"value":"[:output nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":auxiliary","value":":auxiliary"},{"type":"html","content":"nil","value":"nil"}],"value":"[:auxiliary nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":tag","value":":tag"},{"type":"html","content":"nil","value":"nil"}],"value":"[:tag nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":return","value":":return"},{"type":"html","content":"nil","value":"nil"}],"value":"[:return nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":environment","value":":environment"},{"type":"html","content":"nil","value":"nil"}],"value":"[:environment nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":genome","value":":genome"},{"type":"html","content":"nil","value":"nil"}],"value":"[:genome nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":termination","value":":termination"},{"type":"html","content":":abnormal","value":":abnormal"}],"value":"[:termination :abnormal]"}],"value":"#clojush.pushstate.PushState{:exec (1 integer_add true exec_while (1 integer_add true)), :code nil, :integer (199), :float nil, :boolean (), :char nil, :string nil, :zip nil, :vector_integer nil, :vector_float nil, :vector_boolean nil, :vector_string nil, :input nil, :output nil, :auxiliary nil, :tag nil, :return nil, :environment nil, :genome nil, :termination :abnormal}"}
+;; <=
+
+;; **
+;;; All of the Push programs we've seen so far have been completely self-contained in the sense that the data they process is encoded directly within them. How can you give a program *inputs*?
+;;;
+;;; One way is to push them onto stacks before you run the program. The `push-item` utility function makes this easy. For example:
+;; **
+
+;; @@
+(stks (run-push '(float_dup float_mult
+                  3.141592 float_mult)
+                (push-item 2.5
+                           :float
+                           (make-push-state))))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"html","content":"nil","value":"nil"}],"value":"[:integer nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"19.63495","value":"19.63495"}],"value":"(19.63495)"}],"value":"[:float (19.63495)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"}],"value":"{:exec (), :code nil, :integer nil, :float (19.63495), :boolean nil}"}
+;; <=
+
+;; **
+;;; Here we pushed `2.5` onto the `:float` stack before we ran the Push program. The push program squared the initial value (by dulicating it and then multiplying the two copies), and then multiplied it by @@\pi@@. So it computed the area of a circle from a radius. You could call the same program on different initial states to compute different circle areas.
+;;;
+;;; Sometimes it's even more convenient to have instructions that push inputs. That way the program can refer to them whenever it wants, without keeping track of where the initially-pushed items are on the stacks.
+;;;
+;;; This is the job of Clojush's "input instructions," which work with the `:input` stack. The idea is that you push the inputs onto the `:input` stack (rather than the `:float` or other stacks), and then instructions like `in1`, `in2`, etc. can be used to push those values.
+;;;
+;;; Here's a simple example:
+;; **
+
+;; @@
+(run-push '(in1 in1 float_mult 3.141592 float_mult)
+          (push-item 2.5 :input (make-push-state)))
+;; @@
+;; =>
+;;; {"type":"list-like","open":"{","close":"}","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":exec","value":":exec"},{"type":"list-like","open":"(","close":")","separator":" ","items":[],"value":"()"}],"value":"[:exec ()]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":code","value":":code"},{"type":"html","content":"nil","value":"nil"}],"value":"[:code nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":integer","value":":integer"},{"type":"html","content":"nil","value":"nil"}],"value":"[:integer nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":float","value":":float"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"19.63495","value":"19.63495"}],"value":"(19.63495)"}],"value":"[:float (19.63495)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":boolean","value":":boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:boolean nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":char","value":":char"},{"type":"html","content":"nil","value":"nil"}],"value":"[:char nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":string","value":":string"},{"type":"html","content":"nil","value":"nil"}],"value":"[:string nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":zip","value":":zip"},{"type":"html","content":"nil","value":"nil"}],"value":"[:zip nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_integer","value":":vector_integer"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_integer nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_float","value":":vector_float"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_float nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_boolean","value":":vector_boolean"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_boolean nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":vector_string","value":":vector_string"},{"type":"html","content":"nil","value":"nil"}],"value":"[:vector_string nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":input","value":":input"},{"type":"list-like","open":"(","close":")","separator":" ","items":[{"type":"html","content":"2.5","value":"2.5"}],"value":"(2.5)"}],"value":"[:input (2.5)]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":output","value":":output"},{"type":"html","content":"nil","value":"nil"}],"value":"[:output nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":auxiliary","value":":auxiliary"},{"type":"html","content":"nil","value":"nil"}],"value":"[:auxiliary nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":tag","value":":tag"},{"type":"html","content":"nil","value":"nil"}],"value":"[:tag nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":return","value":":return"},{"type":"html","content":"nil","value":"nil"}],"value":"[:return nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":environment","value":":environment"},{"type":"html","content":"nil","value":"nil"}],"value":"[:environment nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":genome","value":":genome"},{"type":"html","content":"nil","value":"nil"}],"value":"[:genome nil]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":":termination","value":":termination"},{"type":"html","content":":normal","value":":normal"}],"value":"[:termination :normal]"}],"value":"#clojush.pushstate.PushState{:exec (), :code nil, :integer nil, :float (19.63495), :boolean nil, :char nil, :string nil, :zip nil, :vector_integer nil, :vector_float nil, :vector_boolean nil, :vector_string nil, :input (2.5), :output nil, :auxiliary nil, :tag nil, :return nil, :environment nil, :genome nil, :termination :normal}"}
+;; <=
+
+;; **
+;;; Here again I didn't use `stks` because I wanted to show the `:input` stack, so you can see that it contains one item, `2.5`. The `:input` stack is a stack like any other, but there aren't any instructions defined for it except the input instructions `in1`, `in2`, etc. So it never changes, aside from when you manually stick stuff on it before running your Push program.
+;;;
+;;; There are a *lot* more instructions and features in Clojush, but this is enough to get see how things work in general, and it's time to move on to using the `pushgp` function to evolve Push programs.
+;;;
+;;; The `pushgp` function takes a single argument which should be a map containing key/value pairs for any or all of the arguments listed in Clojush's [pushgp.clj](https://github.com/lspector/Clojush/blob/c6e9bc5e9835ed3c57703509e5b9fb988ea5f081/src/clojush/pushgp/pushgp.clj) file.
+;;;
+;;; The only argument that is absolutely necessary is `:error-function` which should be a function that takes a Push program and returns a vector of errors (with lower being better and `0` being perfect). The reason it's a vector and not a single value is because you'll often want to run your program on a bunch of inputs, and this lets you return all of the individual test case errors, which might later be combined in various ways, depending on other options. If you have only one test case you should still have your error function return this in a vector.
+;;;
+;;; In the example below I've specied an `:error-function` that evaluates the program for integer inputs from `0` to `9`, and for each input there's an error indicating how far the output is from @@x^3-2x^2-x@@, where the input is @@x@@. If there's nothing on the `:float` stack after the program runs (in which case `top-item` will return `:no-stack-item` rather than a number), then the error will be `1000000` (so, really bad).
+;;;
+;;; The other arguments I've specified in the example below are `:atom-generators`, `:population-size`, `:parent-selection`, and `:use-single-thread`.
+;;;
+;;; The `:atom-generators` argument specifies what's in the "primordial ooze"; that is, what ingredients can occur in evolving programs. By default this will be all known instructions, including some that generate random values, and you usually don't want all of those. So you'll usually want to provide your own value for this too.
+;;;
+;;; For `:population-size` I supplied the value `100`, simply because the default of `1000` runs a little more slowly that I wanted for a tutorial.
+;;;
+;;; For `:parent-selection` I supplied the value `:tournament`, which means that parents will be selected using tournament selection with the default tournament size (which happens to be 7).
+;;;
+;;; Finally, I included `:use-single-thread true`. Why? By default, Clojush will run in a multi-threaded mode and use all available cores, which should make it run faster. But if you do something wrong, and cause an exception to be raised in one of the threads, Clojush will exit unceremoniously and without providing helpful feedback. (And if you're working in Gorilla REPL it will kill the server and you'll have to restart it, and you might have to jump through hoops to avoid losing unsaved changes to your worksheet.) The reasons for this are too boring to recount here, but the bottom line is that `:use-single-thread true` will prevent the exit, and you'll see normal error messages. I recommend running in this mode until you're confident that everything is working, and then run with `:use-single-thread false` (which is the default if you don't provide this argument at all) for better performance.
+;;;
+;;; The following call to pushgp is the last thing in this tutorial. It's **long** because Clojush prints **lots** of info about the run as it proceeds, so that we can study how it is working and try to improve it. Many of the things printed won't make much sense without reading either more of the code base or publications linked to http://pushlanguage.org. But you can see the final result of the run near the bottom of the file.
+;;;
+;; **
+
+;; @@
+(pushgp
+  {:error-function
+   (fn [{:keys [program] :as individual}]
+     (assoc individual
+       :errors
+       (vec
+         (for [input (mapv float (range 10))]
+           (let [output (->> (make-push-state)
+                             (push-item input :input)
+                             (run-push program)
+                             (top-item :float))]
+             (if (number? output)
+               (Math/abs (float (- output
+                                   (- (* input
+                                         input
+                                         input)
+                                      (* 2 input input)
+                                      input))))
+               1000000))))))
+   :atom-generators (list 'in1
+                          'float_div
+                          'float_mult
+                          'float_add
+                          'float_sub)
+   :population-size 100
+   :parent-selection :tournament
+   :use-single-thread true})
+;; @@
+
+;; @@
+
+;; @@


wip commit

wip commit

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/expez/jada.git/'


Adjusted the home banner image to be viewed well on all screen sizes.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/CommonCreative/vbn-website.git/'


Brutal no cache.

Brutal no cache.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mtravers/incidents.git/'


Just a thread call

Just a thread call

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/physion/ovation-webapi.git/'


Clojure numeric examples

Clojure numeric examples

error: pathspec 'clojure/numeric_examples.clj' did not match any file(s) known to git

--- clojure/numeric_examples.clj
+++ clojure/numeric_examples.clj
@@ -0,0 +1,9 @@
+(use 'clojure.test)
+(def x (long 1E15))
+(is (thrown? ArithmeticException (* x x)))
+(is (= (*' x x) (bigint 1E30)))
+
+(is (= (type (int 3)) Integer))
+(is (= (type (/ 3 9)) clojure.lang.Ratio))
+(is (= (type (/ 8 4)) Long))
+(is (= (type (/ 3.0 9)) Double))


Writing out clj files from K Lambda

Writing out clj files from K Lambda

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/michaelsbradleyjr/shen.clj.git/'


Add tests/trials.clj

Add tests/trials.clj

error: pathspec 'tests/trials.clj' did not match any file(s) known to git

--- tests/trials.clj
+++ tests/trials.clj
@@ -0,0 +1 @@
+(+ 1 2)