Todomvc still busted -- will fix that next.

--- examples/todomvc/src/todomvc/core.cljs
+++ examples/todomvc/src/todomvc/core.cljs
@@ -27,6 +27,19 @@
     0
     (inc (apply max (keys todos)))))  ;; hillariously inefficient, but yeah

+
+(defn filter-fn-for
+  [showing-kw]
+  (case showing-kw
+    :active (complement :done)
+    :done   :done
+    :all    identity))
+
+
+(defn completed-count
+  [todos]
+  (count (filter :done todos)))
+
 ;; -- Middleware -------------
 ;;
 ;; Handlers can be wrapped in middleware.
@@ -50,8 +63,9 @@
 ;;
 ;; Middleware means our handlers are pure and simple.
 ;;
-(def todo-middleware (comp (path [:todos]) trim-v))
-
+(def todo-middleware (comp (path [:todos])
+                           debug
+                           trim-v ))

 ;; -- Handlers -------------

@@ -65,7 +79,7 @@

 (register-pure-handler
   :set-showing
-  trim-v
+  (comp debug trim-v)
   (fn
     [db [filter-kw]]
     (assoc db :showing filter-kw)))
@@ -113,12 +127,10 @@
   todo-middleware
   (fn
     [todos _]
-    (let [completed-ids (->> (vals todos)     ;; use a transducer XXX
-                             (remove :done)
-                             (map :id))]
-      (reduce #(dissoc %1 %2)
-              todos
-              completed-ids))))
+    (->> (vals todos)
+         (remove :done)
+         (map :id)
+         (reduce dissoc todos))))

 ;; -- Subscriptions ---------

@@ -133,34 +145,41 @@
   :visible-todos
   (fn
     [db _]
-
     (let [todos     (reaction (:todos @db))
-          showing   (reaction (:showing @db))
-          _         (println @showing)
-          filter-fn (case @showing
-                      :active (complement :done)
-                      :done :done
-                      :all identity)]
-    (reaction (filter filter-fn (vals @todos))))))
+          showing   (reaction (:showing @db))]
+    (reaction (filter (filter-fn-for @showing)
+                      (vals @todos))))))

 (register-sub
   :completed-count
   (fn
     [db _]
-    (reaction (->> (:todos @db)
-                   (filter :done)
-                   count))))
-
-(register-sub
+    (reaction (completed-count (:todos @db)))))
+
+
+#_(register-sub
   :footer-stats
   (fn
     [db _]
     (let [todos (reaction (:todos @db))
           completed-count (subscribe [:completed-count])
-          active-count    (reaction (- (count @todos) @completed-count))
+          active-count    (reaction (- (count (vals @todos)) @completed-count))
           showing         (reaction (:showing @db))]
-      (reaction [@active-count @completed-count @showing]))))  ;; tuple
+      (reaction
+        [@active-count @completed-count @showing]))))  ;; tuple
+
+(register-sub
+  :footer-stats
+  (fn
+    [db _]
+    (reaction
+      (let [todos (:todos @db)
+            completed-count (completed-count todos)
+            active-count    (- (count todos) completed-count)
+            showing         (:showing db)]
+        [active-count completed-count showing]))))  ;; tuple
+

 ;; -- Components ---------
@@ -187,13 +206,15 @@
 (def todo-edit (with-meta todo-input
                  {:component-did-mount #(.focus (reagent/dom-node %))}))

-(defn stats-footer []
+(defn stats-footer
+  []
   (let [footer-stats (subscribe [:footer-stats])]
     (fn []
       (let [[active done filter] @footer-stats
             props-for (fn [filter-kw]
                         {:class (if (= filter-kw filter) "selected")
                          :on-click #(dispatch [:set-showing filter-kw])})]
+        (println active done filter)
         [:footer#footer
          [:div
           [:span#todo-count
@@ -206,7 +227,8 @@
             [:button#clear-completed {:on-click #(dispatch [:clear-completed])}
              "Clear completed " done])]]))))

-(defn todo-item []
+(defn todo-item
+  []
   (let [editing (atom false)]
     (fn [{:keys [id done title]}]
       [:li {:class (str (if done "completed ")
@@ -228,7 +250,8 @@
      ^{:key (:id todo)} [todo-item todo])])

-(defn todo-app []
+(defn todo-app
+  []
   (let [visible-todos   (subscribe [:visible-todos])
         completed-count (subscribe [:completed-count])]
     (fn []
@@ -245,7 +268,7 @@
             [:input#toggle-all
              {:type "checkbox"
               :checked (pos? @completed-count)
-              :on-change #(dispatch [:complete-all (zero? @completed-count)])}]
+              :on-change #(dispatch [:complete-all (pos? @completed-count)])}]
             [:label {:for "toggle-all"} "Mark all as complete"]
             [todo-list visible-todos]]
            [stats-footer]])]


Tidy up

Tidy up

--- frontend/src/cruncher/communication/main.cljs
+++ frontend/src/cruncher/communication/main.cljs
@@ -43,5 +43,4 @@
   [key]
   (cond
     (= :init key) (ajax-get (:init config/api))
-    (= :get-all-pokemon key) (ajax-get (:get-all-pokemon config/api))
-    (= :crunch-selected-pokemon key) (cruncher.shredder.main/power-on)))+    (= :get-all-pokemon key) (ajax-get (:get-all-pokemon config/api))))


Add shutdown fn.

Add shutdown fn.

--- src/dsbdp/main.clj
+++ src/dsbdp/main.clj
@@ -88,5 +88,6 @@
                              (stats-fn)
                              (thread-info-fn) (println)
                              )
-                1000)))
+                1000)
+    (run-once (executor) (fn [] (System/exit 0) 120000))))


Period at end of sentence.

Period at end of sentence.

--- src-cljs/frontend/components/integrations.cljs
+++ src-cljs/frontend/components/integrations.cljs
@@ -128,7 +128,7 @@
                                "different branches to different Heroku apps (e.g. one for staging "
                                "and one for production)."]}
                        {:type :text
-                        :title "Watch how to get started in minutes"
+                        :title "Watch how to get started in minutes."
                         :icon "play-1"
                         :text [:p
                                "This video shows step-by-step how to configure CircleCI to test "


Make the button flat instead of secondary

--- src-cljs/frontend/components/org_settings.cljs
+++ src-cljs/frontend/components/org_settings.cljs
@@ -1014,7 +1014,7 @@
                                                      :on-click #(raise! owner [:resend-invoice-clicked
                                                                                {:invoice-id (:id invoice)}])
                                                      :size :medium
-                                                     :kind :secondary}
+                                                     :kind :flat}
                                                     "Resend"))}]})])))))))

 (defn billing [app owner]


safer first move

safer first move

--- cljs/puzzle/src/problem.cljs
+++ cljs/puzzle/src/problem.cljs
@@ -8,30 +8,29 @@
 (defn log-obj! [obj] (.log js/console obj))

 (def static-domain (str "http://" (clojure.string/replace (.-domain js/document) #"^\w+" "static")))
+(def puzzle-elem (sel1 "#puzzle"))
 (def chessboard-elem (sel1 "#chessboard"))
 (def initial-fen (dommy/attr chessboard-elem "data-fen"))
 (def initial-move (dommy/attr chessboard-elem "data-move"))
-(log! initial-fen)
 (def lines (js->clj (js/JSON.parse (dommy/attr chessboard-elem "data-lines"))))
 (def drop-chan (chan))
 (def animation-delay 300)
 (def chess (new js/Chess initial-fen))

-(defn playing [] (not (dommy/has-class? (sel1 "#puzzle") "complete")))
+(defn playing [] (dommy/has-class? puzzle-elem "playing"))

-(defn make-move
-  ([orig, dest] {:from orig :to dest})
-  ([move] (let [[a, b, c, d] (seq move)] (make-move (str a b) (str c d)))))
+(defn apply-move
+  ([orig, dest] (.move chess (clj->js {:from orig :to dest})))
+  ([move] (let [[a, b, c, d] (seq move)] (apply-move (str a b) (str c d)))))

 (defn delay-chan [fun duration] (let [ch (chan)] (js/setTimeout #(put! ch (or (fun) true)) duration) ch))
 (defn await-chan [value duration] (let [ch (chan)] (js/setTimeout #(put! ch value) duration) ch))
 (defn await-in [ch value duration] (js/setTimeout #(put! ch value) duration) ch)

 (defn on-drop! [orig, dest]
-  (if (and (playing) (.move chess (clj->js (make-move orig dest))))
+  (if (and (playing) (apply-move orig dest))
     (put! drop-chan (str orig dest)) "snapback"))

-(log! (.turn chess))
 (def chessboard
   (new js/ChessBoard "chessboard"
        (clj->js {:position initial-fen
@@ -52,20 +51,21 @@

 (defn ai-play! [branch]
   (let [ch (chan) move (first (first branch))]
-    (when-let [valid (.move chess (clj->js (make-move move)))]
+    (when-let [valid (apply-move move)]
       (go
         (set-position! (.fen chess))
         (await-in ch move (+ 50 animation-delay))))
     ch))

-(defn end! [result]
-  (close! drop-chan)
-  (dommy/add-class! (sel1 "#puzzle") (str "complete " result)))
+(defn end! [result] (-> puzzle-elem
+                        (dommy/add-class! (str "complete " result))
+                        (dommy/remove-class! "playing")))

 (go
   (<! (await-chan true 1000))
-  (.move chess (clj->js (make-move initial-move)))
+  (apply-move initial-move)
   (set-position! (.fen chess))
+  (dommy/add-class! puzzle-elem "playing")
   (loop [progress [] fen (.fen chess)]
     (let [move (<! drop-chan)]
       (if-let [[new-progress new-lines] (try-move progress move)]


Weights in merge-clusters

Weights in merge-clusters

--- src/polismath/clusters.clj
+++ src/polismath/clusters.clj
@@ -170,7 +170,8 @@
   (let [new-id (:id (max-key #(count (:members %)) clst1 clst2))]
     {:id new-id
      :members (into (:members clst1) (:members clst2))
-     :center (weighted-mean (map :center [clst1 clst2]))}))
+     :center (weighted-mean (map :center [clst1 clst2])
+                            :weights (map (comp count :members) [clst1 clst2]))}))

 (defn most-distal


[#1193] Fix merge issue WIP

[#1193] Fix merge issue WIP

--- backend/src/akvo/lumen/transformation/merge_datasets.clj
+++ backend/src/akvo/lumen/transformation/merge_datasets.clj
@@ -4,7 +4,8 @@
             [clojure.set :as set]
             [clojure.string :as s]
             [hugsql.core :as hugsql])
-  (:import [java.sql Timestamp]))
+  (:import [akvo.lumen.import.common Geoshape Geopoint]
+           [java.sql Timestamp]))

 (hugsql/def-db-fns "akvo/lumen/transformation.sql")
 (hugsql/def-db-fns "akvo/lumen/transformation/engine.sql")
@@ -45,13 +46,26 @@
           (or aggregationColumn mergeColumn)
           aggregationDirection))

+#_(defn to-sql-types [row merge-columns]
+    ;; For now we only need to change date types.
+    (let [date-columns (filter #(= "date" (get % "type")) merge-columns)]
+      (reduce (fn [result-row {:strs [columnName]}]
+                (update result-row columnName #(when % (Timestamp. %))))
+              row
+              date-columns)))
+
 (defn to-sql-types [row merge-columns]
-  ;; For now we only need to change date types.
-  (let [date-columns (filter #(= "date" (get % "type")) merge-columns)]
-    (reduce (fn [result-row {:strs [columnName]}]
-              (update result-row columnName #(when % (Timestamp. %))))
+  (let [columns-requiring-cast (filter #(contains? #{"date" "geoshape" "geopoint" }
+                                                   (get % "type"))
+                                       merge-columns)]
+    (reduce (fn [result-row {:strs [columnName type]}]
+              (update result-row columnName (fn [v]
+                                              (when v (case type
+                                                        "date" (Timestamp. v)
+                                                        "geoshape" (Geoshape. v)
+                                                        "geopoint" (Geopoint. v))))))
             row
-            date-columns)))
+            columns-requiring-cast)))

 (defn fetch-data
   "Fetch data from the source dataset and returns a map with the shape
@@ -78,9 +92,11 @@
     (add-column conn {:table-name table-name
                       :new-column-name (get column "columnName")
                       :column-type (condp = (get column "type")
-                                     "text" "text"
+                                     "date" "timestamptz"
+                                     "geopoint" "geometry(POINT, 4326)"
+                                     "geoshape" "geometry(GEOMETRY, 4326)"
                                      "number" "double precision"
-                                     "date" "timestamptz")})))
+                                     "text" "text")})))

 (defn insert-merged-data
   "Insert the merged values into the target dataset"


Comparing PartialFn to nil is false/unexceptional #385

--- src/reagent/impl/util.cljs
+++ src/reagent/impl/util.cljs
@@ -114,7 +114,9 @@
     (apply pfn a b c d e f g h i j k l m n o p q r s t rest))
   IEquiv
   (-equiv [_ other]
-    (and (= f (.-f other)) (= args (.-args other))))
+    (and (instance? PartialFn other)
+         (= f (.-f other))
+         (= args (.-args other))))
   IHash
   (-hash [_] (hash [f args])))


change blink brightness depending on time of day

--- iwaswhere-web/src/clj/iwaswhere_web/blink.clj
+++ iwaswhere-web/src/clj/iwaswhere_web/blink.clj
@@ -5,10 +5,12 @@
   (:require [matthiasn.systems-toolbox.component :as st]
             [clojure.java.shell :refer [sh]]
             [me.raynes.fs :as fs]
+            [clj-time.core :as ct]
+            [clj-time.local :as ctl]
             [clojure.tools.logging :as log]))

-(def red "--hsb=265,255,100")
-(def green "--hsb=65,255,100")
+(def red {:day "--hsb=265,255,255" :night "--hsb=265,255,100"})
+(def green {:day "--hsb=65,255,255" :night "--hsb=65,255,100"})

 (defn blink
   "Calls the blink1 command line tool, which can for example be installed via
@@ -28,22 +30,29 @@
                                 :repeat  true}])
     {:state state}))

+(defn day-night?
+  []
+  (let [h (ct/hour (ctl/local-now))]
+    (if (or (< h 8) (> h 18)) :night :day)))
+
 (defn blink-fn
   "Called with each heartbeat. Sets color to green when last busy timestamp is
    longer ago than one second."
   [{:keys [current-state]}]
   (let [now (st/now)
+        k (day-night?)
         last-busy (get-in current-state [:last-busy])]
     (when (> (- now last-busy) 1000)
       (log/debug "blink green")
-      (blink green))))
+      (blink (k green)))))

 (defn blink-busy
   "Set light to red when busy and save last busy timestamp."
   [{:keys [current-state]}]
-  (let [ts (st/now)]
+  (let [ts (st/now)
+        k (day-night?)]
     (log/debug "blink red")
-    (blink red)
+    (blink (k red))
     {:new-state (assoc-in current-state [:last-busy] ts)}))

 (defn cmp-map


Remove cake plugin from project.clj

Remove cake plugin from project.clj

--- reimann/project.clj
+++ reimann/project.clj
@@ -8,9 +8,6 @@
   :dev-dependencies [
     [protobuf "0.6.0-beta4"]
   ]
-  :cake-plugins [
-    [cake-protobuf "0.5.0-beta1"]
-  ]
   :aot [reimann.bin]
   :main reimann.bin
   :disable-implicit-clean true


breaking commit change

breaking commit change

--- kafka-clj/src/kafka_clj/consumer/consumer.clj
+++ kafka-clj/src/kafka_clj/consumer/consumer.clj
@@ -3,8 +3,9 @@
   (:require
     [taoensso.carmine :as car :refer [wcar]]
     [thread-load.core :as load]
-    [clojure.core.async :refer [go alts!! >! <! timeout]]
+    [clojure.core.async :refer [go alts!! >!! >! <! timeout]]
     [kafka-clj.fetch :refer [create-fetch-producer send-fetch read-fetch]]
+    [thread-load.core :as tl]
     [clj-tuple :refer [tuple]]
     [fun-utils.core :refer [go-seq]]
     [clojure.tools.logging :refer [info error]])
@@ -23,7 +24,7 @@
 ;(publish-work consumer {:producer {:host "localhost" :port 9092} :topic "ping" :partition 0 :offset 0 :len 10})
 ;
 ;
-;(def res (do-work-unit! consumer))
+;(def res (wait-and-do-work-unit! consumer))
 ;
 ;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -111,12 +112,13 @@
   (car/wcar redis-conn
     (car/brpoplpush queue working-queue 0)))

-(defn consumer-start [{:keys [redis-conf] :as state}]
+(defn consumer-start [{:keys [redis-conf conf] :as state}]
   {:pre [(and
            (:work-queue state) (:working-queue state) (:complete-queue state)
            (:redis-conf state) (:conf state))]}
   (merge state
-    {:redis-conn (merge redis-conf {:host (get redis-conf :redis-host (get redis-conf :host))})
+    {:redis-conn (merge redis-conf {:host (get redis-conf :redis-host (get redis-conf :host))})
+     :load-pool (tl/create-pool (get conf :consumer-queue-limit 10))
     :producers {}
     :status :ok}))

@@ -195,13 +197,49 @@
   (car/wcar redis-conn
     (car/lpush work-queue work-unit)))

-
+(defn start-publish-pool-thread
+  "Start a future that will wait for a workunit and publish to the thread-pool"
+  [{:keys [load-pool] :as state}]
+  {:pre [load-pool]}
+  (future
+    (while (not (Thread/interrupted))
+	    (try
+	      (tl/publish! load-pool (get-work-unit! state))
+       (catch Exception e (error e e))))))
+
+
+(defn close-consumer! [{:keys [load-pool]}]
+  (shutdown-pool! load-pool 10000))
+
+;TODO TEST
+(defn consume!
+  "Starts the consumer consumption process, by initiating 1+consumer-threads threads, one thread is used to wait for work-units
+   from redis, and the other threads are used to process the work-unit, the resp data from each work-unit's processing result is
+   sent to the msg-ch, note that the send to msg-ch is a blocking send, meaning that the whole process will block if msg-ch is full
+   The actual consume! function returns inmediately"
+  [{:keys [conf load-pool msg-ch] :as state}]
+  {:pre [conf load-pool msg-ch]}
+  (let [f-delegate (fn [state status resp-data]
+                     (if (= (:status state) :ok)
+                       (>!! msg-ch resp-data))
+                     (assoc state :status :ok))
+
+        consumer-threads (get conf :consumer-threads 2)]
+    ;add threads that will consume from the load-pool and run f-delegate, that will in turn put data on the msg-ch
+    (dotimes [i consumer-threads]
+      (tl/add-consumer load-pool (fn [state work-unit]
+                                   (do-work-unit! state work-unit f-delegate))))
+    ;start background wait on redis, publish work-unit to pool
+    (start-publish-pool-thread state)
+    state))
+
+
 (comment

 (use 'kafka-clj.consumer.consumer :reload)
 (def consumer (consumer-start {:redis-conf {:host "localhost" :max-active 5 :timeout 1000} :working-queue "working" :complete-queue "complete" :work-queue "work" :conf {}}))
 (publish-work consumer {:producer {:host "localhost" :port 9092} :topic "ping" :partition 0 :offset 0 :len 10})
-(def res (do-work-unit! consumer (fn [state status resp-data] state)))
+(def res (wait-and-do-work-unit! consumer (fn [state status resp-data] state)))

 )


Add prepare

Add prepare

--- src/clojure/clojurewerkz/cassaforte/client.clj
+++ src/clojure/clojurewerkz/cassaforte/client.clj
@@ -249,12 +249,17 @@
   [^PreparedStatement statement values]
   (.bind statement (to-array values)))

+(defn prepare
+  [session statement values]
+  (.prepare session statement))
+
 ;; (defn execute-async)

 (defn execute
   "Executes a statement"
   ([^Session session query]
    (let [^Statement built-statement (build-statement query)]
+     ;; (println built-statement)
      (if *async*
        (AsyncResult. (.executeAsync session built-statement))
        (-> (.execute session built-statement)


better naming

better naming

--- src/alibi/domain/entry_app_svc.clj
+++ src/alibi/domain/entry_app_svc.clj
@@ -29,17 +29,18 @@

 (defn update-entry!
   [as-identity cmd]
-  (let [task-id (:task-id cmd)
+  (let [new-task-id (:task-id cmd)
         entry (entry-repo/find-entry (:entry-id cmd))]
-    (when task-id
-      (assert (valid-task? task-id)))
+    (when new-task-id
+      (assert (valid-task? new-task-id)))
     (assert (= as-identity (:user-id entry))
             "can only updates entries for yourself")
     (entry-repo/save-entry!
       (entry/update-entry
         entry (assoc cmd
                      :old-task (task-repo/get (:task-id entry))
-                     :new-task (when task-id (task-repo/get task-id)))))))
+                     :new-task (when new-task-id
+                                 (task-repo/get new-task-id)))))))

 (defn delete-entry! [as-identity {:keys [entry-id] :as cmd}]
   {:pre [(integer? entry-id)


Changed re-comp-test.time-test to re-com-test.time.test.

--- test/re-com/time_test.cljs
+++ test/re-com/time_test.cljs
@@ -1,4 +1,4 @@
-(ns re-comp-test.time-test
+(ns re-com-test.time-test
   (:require-macros [cemerick.cljs.test :refer (is are deftest with-test run-tests testing test-var)])
   (:require [cemerick.cljs.test]
             [reagent.core :as reagent]


call (dag_unify.core/get-in) where needed

--- src/babel/italiano/morphology.cljc
+++ src/babel/italiano/morphology.cljc
@@ -643,7 +643,7 @@

    (:italiano input)
    ;; get-string should always return a string, but sometimes it (incorrectly) does not (FIXME)
-   (string/trim (str (get-string (:italiano input))))
+   (string/trim (str (get-string (get-in input [:italiano]))))

    (and (map? input)
         (get-in input [:a])


Remove unused redis.core dependency.

Remove unused redis.core dependency.

--- src/circle/backend/build/queue.clj
+++ src/circle/backend/build/queue.clj
@@ -1,6 +1,5 @@
 (ns circle.backend.build.queue
   (:use [clojure.core.incubator :only (-?>)])
-  (:require [redis.core :as redis])
   (:require [resque-clojure.core :as resque])
   (:require [circle.backend.ec2 :as ec2])
   (:use [circle.util.except :only (throwf)])


lots and lots of debug statements, grep for them

--- src/clj/polis_storm/online_pca.clj
+++ src/clj/polis_storm/online_pca.clj
@@ -24,17 +24,25 @@
       (swap! ptpts conj (nth reaction 0)))
     (if (not (some #(= (nth reaction 1) %) @cmts))
       (swap! cmts conj (nth reaction 1))))
-  (reset! rating-matrix (mapv #(into % (repeat (- (count cmts) (count (get @rating-matrix 0))) 0)) @rating-matrix))
+
+  (println "expansion col diff is : " (- (count @cmts) (count (nth @rating-matrix 0))))
+  (println "pre expansion matrix is: " @rating-matrix)
+  (reset! rating-matrix (mapv #(into % (repeat (- (count @cmts) (count (nth @rating-matrix 0))) 0)) @rating-matrix))
+  (println "first expansion is : " @rating-matrix)
+  (println "expansion comment count is : " (count @cmts))
   (reset! rating-matrix (into @rating-matrix (into [] (repeat (- (count @ptpts) (count @rating-matrix) ) 0))))
+  (println "second expansion is : " @rating-matrix)
   ;; maybe could have used map below
   (doseq [reaction new-reactions]
     (let [row (.indexOf @cmts (nth reaction 1)) column (.indexOf @ptpts (nth reaction 0))]
-      (reset! rating-matrix (replace {row (replace {column (nth reaction 2)} (nth @rating-matrix row))} @rating-matrix)))))
+      (println "row is :" row "  column is :" column "  matrix is: " @rating-matrix)
+      (swap! rating-matrix assoc-in [row column] (nth reaction 2))
+      )))

 (defbolt pca ["pca"] {:prepare true}
   [conf context collector]
-  (let [rating-matrix (atom (matrix [[]])) ptpts (atom []) cmts (atom [])]
+  (let [rating-matrix (atom [[0]]) ptpts (atom []) cmts (atom [])]
     (bolt
       (execute [tuple]
         ;;storm tuple impl seems to need some unwrapping


Replace now not existing get-value with extract in exception monad ns.

--- src/cljx/cats/monad/exception.cljx
+++ src/cljx/cats/monad/exception.cljx
@@ -304,7 +304,7 @@

     (fapply [m af av]
       (if (success? af)
-        (proto/fmap m (proto/get-value af) av)
+        (proto/fmap m (proto/extract af) av)
         af))

     proto/Monad


cleanup

cleanup

--- src/clojure/zensols/cisql/spec.clj
+++ src/clojure/zensols/cisql/spec.clj
@@ -118,36 +118,6 @@
       (log/debugf "spec: %s" (pr-str spec))
       spec)))

-;; (require '[clojure.java.jdbc :as jdbc])
-;; (driver-meta "mysql")
-
-;; (db-spec {:name "csv" :database "/d"})
-
-;; (-> (db-spec {:name "csv" :database "/d"})
-;;     (jdbc/query "select * from a"))
-;; (reset)
-
-
-;; (-> (db-spec {:name "postgres" :database "puser" :password "pass" :user "puser" :host "192.168.99.100"})
-;;     (jdbc/query "select * from tmp"))
-
-;; (-> {:connection-uri "jdbc:postgresql://192.168.99.100:5432/puser"
-;;      :factory #(DriverManager/getConnection (:connection-uri %)
-;;                                             (as-properties (dissoc % :connection-url)))
-;;      :password "pass"
-;;      :user "puser"}
-;;     (jdbc/query "select * from tmp"))
-
-;; (-> (db-spec {:name "csv" :database "/d"})
-;;     (jdbc/query "select * from a")
-;;     )
-
-;; (-> {:subprotocol "relique:csv" :subname "/d" :classname "org.relique.jdbc.csv.CsvDriver"}                         ;{:name "csv" :database "/d"}
-
-;;     ;(java.net.URI.)
-;;     (jdbc/query "select * from a")
-;;     )
-
 (defn registered-names
   "Return a sequence of provided drivers.  These are the default driver
   information (not actual JDBC drivers)."
@@ -169,18 +139,6 @@
          (select-keys opts)
          (#(rename-keys % {:port :default-port}))
          (#(assoc % :group group :artifact artifact :version version)))))
-
-;; (let [opts {:name "csv"
-;;             :port 12345
-;;             :class "org.relique.jdbc.csv.CsvDriver"
-;;             :dependency "net.sourceforge.csvjdbc/csvjdbc/1.0.28"
-;;             :url "jdbc:relique:csv:%5$s"}]
-;;   (->> (opts-to-flat opts)
-;;        put-flat))
-
-;; (pref/clear)
-
-

 (defn- put-flat [flat]
   (log/debugf "adding <%s>" (pr-str flat))


fix compilation log bug

fix compilation log bug

--- src/clojure/zensols/dataset/db.clj
+++ src/clojure/zensols/dataset/db.clj
@@ -424,9 +424,9 @@
   ([id instance class-label set-type]
    (log/infof "loading instance (%s): %s => <%s>"
                id class-label
-               (let [maxlen (count s)
-                     s (pr-str instance)
-                     len (count s)]
+               (let [s (pr-str instance)
+                     len (count s)
+                     maxlen (min 80 len)]
                  (str (subs s 0 (min maxlen len))
                       (if (> len maxlen) "..."))))
    (log/debugf "instance: %s" instance)


moved flatten nodes to utils

moved flatten nodes to utils

--- src/kioo/util.cljx
+++ src/kioo/util.cljx
@@ -52,6 +52,13 @@
         (dissoc :class)
         (merge {:style style :className class-name}))))

+
+(defn flatten-nodes [nodes]
+  (reduce #(if (seq? %2)
+             (concat %2 %1)
+             (conj %1 %2))
+          '()
+          (reverse nodes)))
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;these functions were pulled from r0man / sablono hiccup style
 ;;template engine for react.


update pagination table

update pagination table

--- src_cljs/rrm/corecljs.cljs
+++ src_cljs/rrm/corecljs.cljs
@@ -992,7 +992,9 @@
                                    [:td (.-senddate mt)]
                                    [:td (.-receiveddate mt)]
                                    ]))]]
-     [:div{:class "col-xs-6 col-centered col-max"} [shared-state 0]]]]])
+     [:div{:class "col-xs-6 col-centered col-max"} ]]
+    [:div{:class "col-xs-6 col-centered col-max"} ] [shared-state 0]
+    ]])

 (defroute mutations-list "/mutations" []


fix cider nrepl issue printing everything quoted

didn't seem to like the extra message k/v pairs the ws sends

--- src/main/shadow/cljs/devtools/server/nrepl.clj
+++ src/main/shadow/cljs/devtools/server/nrepl.clj
@@ -70,7 +70,8 @@

                       repl-ns
                       (-> repl-state :current :ns)]
-                  (send msg (assoc result :ns (pr-str repl-ns)))) ;; :value is already a edn string
+                  (send msg {:value (:value result)
+                             :ns (pr-str repl-ns)}))

                 :repl/set-ns-complete
                 (let [repl-state (repl-impl/worker-repl-state worker)


Print "checking" message more gooder.

Print "checking" message more gooder.

--- src/midje/repl.clj
+++ src/midje/repl.clj
@@ -33,11 +33,13 @@
     [(set options) non-options]))

 (defn- print-fact-position [fact-function]
-  (println (or (fact-name fact-function)
+  (println (color/note
+            "Checking "
+            (or (fact-name fact-function)
                (fact-description fact-function)
                (str "fact at " (midje-position-string
                                 [(fact-file fact-function)
-                                 (fact-line fact-function)])))))
+                                 (fact-line fact-function)]))))))


Fixed some repl-compilation artifacts

Fixed some repl-compilation artifacts

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/contrib/algorithms/canonical_base.clj
+++ src/conexp/contrib/algorithms/canonical_base.clj
@@ -9,8 +9,10 @@
 (in-ns 'conexp.contrib.algorithms)

 (use 'conexp.contrib.algorithms.bitwise)
-(require '[conexp.main :as cm])
+(require '[conexp.main :as cm]
+         '[conexp.contrib.algorithms.next-closure :as nc])

+(import '[java.util BitSet])
 (import '[conexp.fca.implications Implication])

@@ -57,17 +59,15 @@
   ([ctx]
      (canonical-base ctx #{}))
   ([ctx background-knowledge]
-     (assert (context? ctx)
-             "First argument must be a formal context")
      (with-binary-context ctx
        (let [next-closure (fn [implications last]
-                            (next-closed-set object-count
-                                             attribute-count
-                                             (clop-by-implications implications)
-                                             last)),
+                            (nc/next-closed-set object-count
+                                                attribute-count
+                                                (clop-by-implications implications)
+                                                last)),
              runner       (fn runner [implications, ^BitSet candidate]
                             (when candidate
-                              (let [conclusions (bitwise-context-attribute-closure
+                              (let [conclusions (nc/bitwise-context-attribute-closure
                                                  object-count
                                                  attribute-count
                                                  incidence-matrix
@@ -80,9 +80,9 @@
                                     (cons impl
                                           (lazy-seq (runner impls (next-closure impls candidate)))))
                                   (recur implications (next-closure implications candidate))))))]
-         (map (fn [bit-impl]
-                (cm/make-implication (to-hashset attribute-vector (premise bit-impl))
-                                     (to-hashset attribute-vector (conclusion bit-impl))))
+         (map (fn [^Implication bit-impl]
+                (cm/make-implication (to-hashset attribute-vector (.premise bit-impl))
+                                     (to-hashset attribute-vector (.conclusion bit-impl))))
               (lazy-seq (runner (vec background-knowledge)
                                 (close-under-implications background-knowledge
                                                           (to-bitset attribute-vector #{})))))))))


New pending specs for subcircle governance documents.

--- spec/freefrog/lang_spec.clj
+++ spec/freefrog/lang_spec.clj
@@ -106,6 +106,11 @@
     ;part
     )

+  (describe "governing subcircles"
+    (it "won't allow multiple subcircles to be governed in one document")
+    (it "won't allow subcircle governance except as the first statement")
+    (it "will apply all governance to the mentioned subcircle"))
+
   (assert-governance
     "should be able to add roles and circles"
     sample-anchor-circle


fix ast->code list? discrepency in cljs

fix ast->code list? discrepency in cljs

--- src/pdfn/core.cljc
+++ src/pdfn/core.cljc
@@ -72,7 +72,7 @@

 (defn- ast->code [form]
   (cond (vector? form) (seq (clojure.walk/walk ast->code identity (vec (remove #{::nf} form))))
-        (list? form)   (first form)
+        (seq? form)   (if (= 1 (count form)) (first form) form)
         :else form))

 (defn- datatype? [v] (or (sequential? v) (set? v) (map? v)))


Add model/delete-from-inbox!.

Add model/delete-from-inbox!.

--- src/pepa/model.clj
+++ src/pepa/model.clj
@@ -258,8 +258,11 @@

 (defn add-to-inbox!
   "Unconditionally adds PAGES to inbox."
-  [db pages]
-  (db/insert-coll! db :inbox (for [id pages] {:page id})))
+  [db page-ids]
+  (db/insert-coll! db :inbox (for [id page-ids] {:page id})))
+
+(defn remove-from-inbox! [db page-ids]
+  (db/delete! db :inbox (db/sql+placeholders "page IN (%s)" page-ids)))

 ;;; TODO(mu): We need to cache this stuff.
 ;;; TODO(mu): We need to handle (= document file) more efficient


process page actions correctly

process page actions correctly

--- src/hypertext_ray/page_handler.clj
+++ src/hypertext_ray/page_handler.clj
@@ -7,13 +7,13 @@

 (defn action-dispatch [siteinfo action current-page]
+  (println "action:" action "page:" current-page)
   (case action
     :login (do-login siteinfo)
-    :wait (println "wait")
+    :wait (do (println "wait") siteinfo)
     :collect-data (find-data siteinfo current-page)
-    :logout (println "logout")
-    :quit (quit)
-    siteinfo
+    :logout (do (println "logout") siteinfo)
+    :quit (do (println "quit") siteinfo)
     )
   )

@@ -21,8 +21,7 @@
   (let [current-page (match-page siteinfo)
         action-list (current-page (:pageactions siteinfo))
         ]
-    (println current-page action-list)
-    (reduce #(action-dispatch % current-page) siteinfo action-list)
+    (reduce #(action-dispatch %1 %2 current-page) siteinfo action-list)

     )
   )


shouldComponentUpdate compares this.state["value"] also.

--- src/quiescent.cljs
+++ src/quiescent.cljs
@@ -20,10 +20,13 @@
   (let [m (meta renderer)
          react-map
          (cond-> #js {:shouldComponentUpdate
-                       (fn [next-props _]
+                       (fn [next-props next-state]
                          (this-as this
-                                  (not= (aget (.-props this) "value")
-                                        (aget next-props "value"))))
+                                  (or
+                                    (not= (aget (.-props this) "value")
+                                          (aget next-props "value"))
+                                    (not= (aget (.-state this) "value")
+                                          (aget next-state "value")))))
                       :render
                        (fn []
                          (this-as this


[#84] Solve reflection warning

[#84] Solve reflection warning

--- backend/src/org/akvo/dash/import/csv.clj
+++ backend/src/org/akvo/dash/import/csv.clj
@@ -103,7 +103,7 @@
         copy-manager (CopyManager. (cast BaseConnection (:connection tenant-conn)))]
     (jdbc/execute! tenant-conn [(get-create-table-sql temp-table n-cols "text" true)])
     (jdbc/execute! tenant-conn [(get-create-table-sql table-name n-cols "jsonb" false)])
-    (.copyIn copy-manager (get-copy-sql temp-table n-cols headers?) (io/input-stream path))
+    (.copyIn copy-manager ^String (get-copy-sql temp-table n-cols headers?) (io/input-stream path))
     (jdbc/execute! tenant-conn [(get-insert-sql temp-table table-name n-cols)])
     (jdbc/execute! tenant-conn [(get-drop-table-sql temp-table)])
     (jdbc/execute! tenant-conn [(get-vacuum-sql table-name)] :transaction? false)


Updated opencl tutorial test.

Updated opencl tutorial test.

--- test/uncomplicate/neanderthal/examples/guides/tutorial_opencl_test.clj
+++ test/uncomplicate/neanderthal/examples/guides/tutorial_opencl_test.clj
@@ -216,7 +216,7 @@
        "Let's try with 2^20. That's more than a million."
        (let [cnt (long (Math/pow 2 20))]
          (with-release [host-x (sv (range cnt))
-                        gpu-x (treansfer! host-x (sv-cl cnt))]
+                        gpu-x (transfer! host-x (sv-cl cnt))]

            (println "CPU:")
            (time (asum host-x)) => (float 5.49754798E11)
@@ -239,17 +239,20 @@
       (facts
        "Let's try with 2^29. That's 2GB, the maximum that Java buffers can
 currently handle. Java 9 would hopefully increase that."
-       (let [cnt (long (dec (Math/pow 2 29)))]
+       ;; I had to change it to 2^28 because the update for my GPU driver caused
+       ;; it to complain about insufficient memory, but this is probably a temporary issue.
+       ;; time reports wrong values, criterium confirms the earlier numbers.
+       (let [cnt (long (Math/pow 2 28))]
          (with-release [host-x (sv (range cnt))
                         gpu-x (transfer! host-x (sv-cl cnt))]

            (println "CPU:")
            ;; note the wrong result in the CPU vector. That's because single precision floats
-           are not enough for so many accumulations. In real life, you must use doubles where needed.
-           (time (asum host-x)) => (float 1.08086391E17)
+           ;; are not enough for so many accumulations. In real life, you must use doubles where needed.
+           (time (asum host-x)) => (float 3.6780519E16)
            (println "GPU:")
            ;; GPU engine uses doubles for this accumulation, so the result is more precise.
-           (time (asum gpu-x)) => 1.44115187270549504E17))))))
+           (time (asum gpu-x)) => 3.602879688474624E16))))))

 "$text


Rename stub Fixtures to reflect binding

Rename stub Fixtures to reflect binding

--- src/main/clojure/lazytest/stub.clj
+++ src/main/clojure/lazytest/stub.clj
@@ -3,12 +3,12 @@
   current dynamic environment."
   (:use [lazytest.fixture :only (Fixture)]))

-(deftype ThreadLocalStub [v value]
+(deftype DynamicBindingStub [v value]
   Fixture
   (setup [this] (push-thread-bindings {v value}))
   (teardown [this] (pop-thread-bindings)))

-(deftype GlobalStub [v new-value]
+(deftype RootBindingStub [v new-value]
   Fixture
   (setup [this]
     (alter-meta! v (fn [m]
@@ -32,7 +32,7 @@
   new-value."
   [v new-value]
   {:pre [(var? v)]}
-  (ThreadLocalStub. v new-value))
+  (DynamicBindingStub. v new-value))

 (defn global-stub
   "Returns a Fixture that modifies the root binding if Var v. The Var
@@ -40,4 +40,4 @@
   instead unless you need to stub the Var on all threads."
   [v new-value]
   {:pre [(var? v)]}
-  (GlobalStub. v new-value))
+  (RootBindingStub. v new-value))


adding test

adding test

--- test/cljc/ow/starbuck/message_router_test.cljc
+++ test/cljc/ow/starbuck/message_router_test.cljc
@@ -101,6 +101,12 @@
     (t/is (= (mr/advance msg example-ruleset)
              []))))

+(t/deftest route6
+  (let [msg {:route :switch-booking
+             :comp :soaihgfodser}]
+    (t/is (= (mr/advance msg example-ruleset)
+             []))))
+
 (t/deftest event1
   (let [msg {:route :switch-booking
              :notify true}]


Make random properties spec faster by limiting the random data size

--- src/main/workflo/macros/props.cljc
+++ src/main/workflo/macros/props.cljc
@@ -11,7 +11,9 @@
   symbol?)

 (s/def ::link-id
-  ::s/any)
+  (s/with-gen
+    ::s/any
+    gen/simple-type))

 (s/def ::base
   ::name)
@@ -77,7 +79,7 @@
 (s/def ::properties
   (s/with-gen
     (s/and vector? (s/+ ::property))
-    #(gen/vector (s/gen ::property))))
+    #(gen/vector (s/gen ::property) 0 5)))

 (s/def ::properties-group
   (s/cat :base ::name


minor

minor

--- examples/src/worksheets/gmm_fixed_number_of_clusters.clj
+++ examples/src/worksheets/gmm_fixed_number_of_clusters.clj
@@ -12,7 +12,7 @@
             anglican.smc
             [anglican.csis.network :refer :all]
             [anglican.inference :refer [infer]]
-            [anglican.stat :refer [collect-by collect-results]]
+            [anglican.stat :refer [collect-results]]
             [clojure.core.matrix :as m]
             [clojure.core.matrix.linear :as mlin]
             [helpers.gmm :refer [normalize move-to-unit-box gridify]]


Use remove

Use remove

--- src/advent_2017/day_20.cljc
+++ src/advent_2017/day_20.cljc
@@ -31,7 +31,7 @@
   (->> particles
     (group-by #(take 3 %))
     vals
-    (filter #(== 1 (count %)))
+    (remove #(> (count %) 1))
     (map first)))

 (def particle-count (eduction (map count)


fix(minify): use for instead of doseq to return compression results

--- src/asset_minifier/core.clj
+++ src/asset_minifier/core.clj
@@ -186,6 +186,6 @@
    [:js {:source [\"dev/res/js1\", \"dev/res/js2\"] :target \"dev/minified/js/script.min.js\"}]]"
   [config]
   {:pre [(spec/is-valid-config config)]}
-  (doseq [[asset-type opts] config]
+  (for [[asset-type opts] config]
     (let [minify-fn (get-minifier-fn-by-type asset-type)]
       (minify-fn (:source opts) (:target opts) (:opts opts)))))


Add "/admin/users" endpoint-test

Add "/admin/users" endpoint-test

--- backend/test/akvo/lumen/endpoints_test.clj
+++ backend/test/akvo/lumen/endpoints_test.clj
@@ -39,9 +39,9 @@
 (defn put* [uri body & args]
   (apply with-body :post uri body args))

-(defn get* [uri & [query-params]]
+(defn >get* [method uri & [query-params]]
   (cond->
-      {:request-method :get
+      {:request-method method
        :server-port 3030,
        :server-name "t1.lumen.local",
        :path-info uri
@@ -50,6 +50,12 @@
        :headers {"host" "t1.lumen.local:3030" "content-type" "application/json"}
        :uri uri}
     query-params (assoc :query-params query-params)))
+
+(defn get* [uri & more]
+  (>get* :get uri more))
+
+(defn del* [uri & more]
+  (>get* :delete uri more))

 (defn job-execution-dataset-id [h job-id]
   (dh/with-retry {:retry-if (fn [v e] (not v))
@@ -141,6 +147,8 @@
           :sort nil,
           :showValueLabels false}})

+(defn body-kw [res]
+  (-> res :body (json/parse-string keyword)))

 (deftest handler-test
   (let [h (:handler (:akvo.lumen.component.handler/handler *system*))]
@@ -159,6 +167,11 @@
                 :sentryDSN "dev-sentry-client-dsn"}
                (json/parse-string (:body r) keyword)))))
     (testing "/api"
+      (testing "/admin/users"
+        (let [users (-> (h (get* (api-url "/admin/users"))) body-kw :users)]
+          (is (= '("jerome@t1.lumen.localhost" "salim@t1.lumen.localhost")
+                 (sort (map :email users))))))
+
       (let [r (h (get* (api-url "/library")))]
         (is (= 200 (:status r)))
         (is (= {:dashboards []
@@ -177,7 +190,7 @@
                           :body (json/parse-string keyword) :id))))

           (is (= title* (-> (h (get* (api-url "/library")))
-                           :body (json/parse-string keyword) :collections first :title)))
+                            :body (json/parse-string keyword) :collections first :title)))
           ))
       (testing "/datasets"
         (let [title "dataset-title"


whitespace changes

whitespace changes

--- sidecar/src/figwheel_sidecar/build_middleware/injection.clj
+++ sidecar/src/figwheel_sidecar/build_middleware/injection.clj
@@ -98,14 +98,14 @@
           devcards? (get-in build [:figwheel :devcards])]
       (create-connect-script-if-needed! build)
       (-> build
-        ;; might want to add in devcards jar path here :)
-        (update-in [:source-paths] (fn [sp] (let [res (cons (connect-script-temp-dir build) sp)]
-                                             (vec (if-let [devcards-src (and devcards?
-                                                                             (cljs.env/with-compiler-env (:compiler-env build)
-                                                                               (not (ana-api/find-ns 'devcards.core)))
-                                                                             (io/resource "devcards/core.cljs"))]
-                                                    (cons devcards-src res)
-                                                    res)))))
+          ;; might want to add in devcards jar path here :)
+          (update-in [:source-paths] (fn [sp] (let [res (cons (connect-script-temp-dir build) sp)]
+                                                (vec (if-let [devcards-src (and devcards?
+                                                                                (cljs.env/with-compiler-env (:compiler-env build)
+                                                                                (not (ana-api/find-ns 'devcards.core)))
+                                                                                (io/resource "devcards/core.cljs"))]
+                                                       (cons devcards-src res)
+                                                       res)))))
         ;; this needs to be in the (:options (:compiler-env build))
         #_(update-in [:build-options] (fn [bo] (if devcards?
                                                 (assoc bo :devcards true)


[CS] Add namespace for missing-file fn calls

--- src/vip/data_processor/validation/transforms.clj
+++ src/vip/data_processor/validation/transforms.clj
@@ -27,9 +27,9 @@

 (def csv-validations
   [csv/remove-bad-filenames
-   (error-on-missing-file "election.txt")
-   (error-on-missing-file "source.txt")
-   (warn-on-missing-file "state.txt")
+   (csv/error-on-missing-file "election.txt")
+   (csv/error-on-missing-file "source.txt")
+   (csv/warn-on-missing-file "state.txt")
    csv/load-elections
    csv/load-sources
    csv/load-states])


Refactor

Refactor

--- src/hackernews/shared/scenes/detail_view/detail_view.cljs
+++ src/hackernews/shared/scenes/detail_view/detail_view.cljs
@@ -11,7 +11,9 @@

 (defn comment-row
   [comment]
-  [rn/view {:style {:padding 10}}[rn/text comment]])
+  [rn/view {:style {:padding 15}}
+   [rn/text {:style {:fontSize 18}}
+    comment]])

 (defn collect-comments
   [comment]
@@ -27,6 +29,4 @@
        {:style {:padding-top 10}}
        [sr/story-row @story]
        [l/list-view {::l/items (collect-comments @story)
-                     ::l/on-press #()
-                     ::l/render-row  comment-row
-                     ::l/on-end-reached #()}]])))
+                     ::l/render-row  comment-row}]])))


use ReactRouter API names

use ReactRouter API names

--- src/reagent_react_router/core.cljs
+++ src/reagent_react_router/core.cljs
@@ -23,7 +23,7 @@
              "handler" (reagent/reactify-component (:handler params)))
            args)))

-(defn NotFoundRoute
+(defn NotFound
   [params & args]
   (let [default (.createFactory js/React js/ReactRouter.NotFoundRoute)]
     (apply default
@@ -31,7 +31,7 @@
              "handler" (reagent/reactify-component (:handler params)))
            args)))

-(defn RedirectRoute
+(defn Redirect
   [params & args]
   (let [default (.createFactory js/React js/ReactRouter.Redirect)]
     (apply default
@@ -40,7 +40,6 @@
              "to"   (:to params)
              )
            args)))
-

 (defn- router-cbk
   [elem handler state]


Use some as requested

Use some as requested

--- src/refactor_nrepl/ns/clean_ns.clj
+++ src/refactor_nrepl/ns/clean_ns.clj
@@ -36,13 +36,10 @@
   (assert-no-exclude-clause (core/get-ns-component ns-form :use))
   ns-form)

-(defn- seek
-  "Find the first element in coll that satisfies pred?"
-  [pred? coll]
-  (reduce (fn [_ x] (when (pred? x) (reduced x))) nil coll))
-
 (defn clean-ns [{:keys [path relative-path]}]
-  (let [path (seek #(and % (.exists (io/file %)))
+  (let [path (some (fn [p]
+                     (when (and p (.exists (io/file p)))
+                       p))
                    [path relative-path])]
     (assert (core/source-file? path))
     ;; Prefix notation not supported in cljs.


Set the default print function for Rhino evaluation.

--- src/clj/cljs/repl/rhino.clj
+++ src/clj/cljs/repl/rhino.clj
@@ -13,7 +13,7 @@
             [cljs.compiler :as comp]
             [cljs.repl :as repl])
   (:import cljs.repl.IJavaScriptEnv
-           [org.mozilla.javascript Context]))
+           [org.mozilla.javascript Context ScriptableObject]))

 (def current-repl-env (atom nil))
 (def loaded-libs (atom #{}))
@@ -93,13 +93,21 @@
           (swap! loaded-libs (partial apply conj) missing)))))

 (defn rhino-setup [repl-env]
-  (let [env {:context :statement :locals {}}]
+  (let [env {:context :statement :locals {} :ns (@comp/namespaces comp/*cljs-ns*)}
+        scope (:scope repl-env)]
     (repl/load-file repl-env "cljs/core.cljs")
     (swap! loaded-libs conj "cljs.core")
     (repl/evaluate-form repl-env
-                        (assoc env :ns (@comp/namespaces comp/*cljs-ns*))
+                        env
                         "<cljs repl>"
-                        '(ns cljs.user))))
+                        '(ns cljs.user))
+    (ScriptableObject/putProperty scope
+                                  "out"
+                                  (Context/javaToJS System/out scope))
+    (repl/evaluate-form repl-env
+                        env
+                        "<cljs repl>"
+                        '(set! *print-fn* (fn [x] (.print js/out x))))))

 (extend-protocol repl/IJavaScriptEnv
   clojure.lang.IPersistentMap
@@ -143,6 +151,7 @@
   (:a {:a "hello"})
   (:a {:a :b})
   (reduce + [1 2 3 4 5])
+  (time (reduce + [1 2 3 4 5]))
   (even? :a)
   (throw (js/Error. "There was an error"))
   (load-file "clojure/string.cljs")


added reduce-fn to cogroup

added reduce-fn to cogroup

--- src/clj/datasplash/core.clj
+++ src/clj/datasplash/core.clj
@@ -231,19 +231,23 @@
                   (cogroup-transform opts))))))

 (defn cogroup-by
-  [options specs]
-  (let [operations (for [[pcoll f type] specs]
-                     [(dgroup-by f options pcoll) type])
-        required-idx (remove nil? (map-indexed (fn [idx [_ b]] (when b idx)) operations))
-        pcolls (map first operations)
-        grouped-coll (cogroup options pcolls)]
-    (if (empty? required-idx)
-      grouped-coll
-      (dfilter (fn [[_ all-vals]]
-                 (let [idx-vals (into [] all-vals)]
-                   (every? #(not (empty? (get idx-vals %))) required-idx)))
-               options
-               grouped-coll))))
+  ([options specs reduce-fn]
+   (let [operations (for [[pcoll f type] specs]
+                      [(dgroup-by f options pcoll) type])
+         required-idx (remove nil? (map-indexed (fn [idx [_ b]] (when b idx)) operations))
+         pcolls (map first operations)
+         grouped-coll (cogroup options pcolls)
+         filtered-coll (if (empty? required-idx)
+                         grouped-coll
+                         (dfilter (fn [[_ all-vals]]
+                                    (let [idx-vals (into [] all-vals)]
+                                      (every? #(not (empty? (get idx-vals %))) required-idx)))
+                                  options
+                                  grouped-coll))]
+     (if reduce-fn
+       (dmap reduce-fn options filtered-coll)
+       filtered-coll)))
+  ([options specs] (cogroup-by options specs nil)))

 (comment
   (compile 'datasplash.core))
@@ -255,7 +259,7 @@
                       (generate-input [{:key :a :foo 12} {:key :b :foo 5} {:key :a :foo 42} {:key :c :val "never"}] {:name "gengen1"}))
         second-in (->> p
                        (generate-input [{:key :a :val 10} {:key :b :val 5} {:key :a :val 42}] {:name "gengen"}))
-        final (->> (cogroup-by {:name :join} [[first-in :key] [second-in :key ]])
+        final (->> (cogroup-by {:name :join} [[first-in :key] [second-in :key :required]] (fn [[k res]] (apply merge res)))
                    (write-edn-file "tessst.edn" {:name :output-edn}))
         ;; first-in (->> p
         ;;               (generate-input [{:key :a :foo 12} {:key :b :foo 5} {:key :a :foo 42}] {:name "gengen1"})
@@ -271,5 +275,4 @@
         ;;            (dmap (fn [kv] (vector (.getKey kv) (seq (.getValue kv)))) {:name :normalize})
         ;;            (write-edn-file "gs://oscaro-test-dataflow/results/group-by.edn" {:name :output-edn}))
         ]
-
     (.run p)))


the correct number of arguments for init-app *sigh*

--- src/cljs/foosball/main.cljs
+++ src/cljs/foosball/main.cljs
@@ -46,7 +46,7 @@
                                                            [:home-location :menu-locations])}})))

 (when-not js/skipRootBind
-  (init-app false)
+  (init-app)
   (fw/watch-and-reload
    :websocket-url   "ws://localhost:3449/figwheel-ws"
    :jsload-callback (fn []


All ai decisions computed through the score heuristic

--- src/cljs/triboard/core.cljs
+++ src/cljs/triboard/core.cljs
@@ -179,11 +179,13 @@
   (apply max-key (memoize key-fn) coll))

 (defn move-strength
-  ;; TODO - Count taken is bad: select a better evaluation
-  ;; TODO - It requires however to change the initial scoring as well
-  "Compute the strength value of a move"
-  [move]
-  (count (:taken move)))
+  "Compute the strength of a move, based on the converted cells"
+  [move-filter [move converted]]
+  (transduce
+    (comp
+      (filter move-filter)
+      (map (comp count :taken)))
+    + converted))

 (defn- best-immediate-move-with
   "Return the move with the highest immediate score increase:
@@ -191,10 +193,7 @@
    * And with move scope limitation"
   [moves move-filter]
   (fast-max-key
-    (fn [[point converted]]
-      (transduce
-        (comp (filter move-filter) (map move-strength))
-        + converted))
+    (partial move-strength move-filter)
     moves))

 (defn worst-immediate-loss
@@ -205,8 +204,7 @@
   (let [move-filter #(= looser (:looser %))
         all-moves (get-in game [:moves player])
         move (best-immediate-move-with all-moves move-filter)]
-    (transduce (map (comp count :taken)) + (second move))
-    ))
+    (move-strength move-filter move)))

 (defn best-move
   "[SIMPLISTIC] Return the best move for a player based on:
@@ -214,15 +212,14 @@
    * The worse immediate lost afterwards"
   [game player]
   (let [moves (get-in game [:moves player])
-        others (remove #{player} players)
-        score (get-in game [:scores player])]
+        others (remove #{player} players)]
     (first
       (fast-max-key
-        (fn [[m converted]]
+        (fn [[m converted :as move]]
           (let [new-game (play-move game m)
-                new-score (get-in new-game [:scores player]) ;; TODO - Use score heuristic here
+                diff-score (move-strength identity move)
                 losses (map #(worst-immediate-loss new-game % player) others)]
-            (- new-score (apply max losses))))
+            (- diff-score (apply max losses))))
         moves))
     ))


Minor optimizations

Minor optimizations

--- src/cljs/triboard/core.cljs
+++ src/cljs/triboard/core.cljs
@@ -125,17 +125,16 @@
        :looser :red,
        :taken [[0 4]]})}}"
   [{:keys [board] :as game}]
-  (time
-    (merge game
-     {:moves
+  (assoc game :moves
+    (time
       (transduce
         (comp
           (filter #(= (get-in board %) :empty))
           (mapcat #(available-moves-at board %)))
         #(update-in %1 [(:winner %2) (:move %2)] conj %2)
         {}
-        all-positions)} ;; TODO - To optimize, just consider the move of the current player?
-     )))
+        all-positions)) ;; TODO - To optimize, just consider the move of the current player?
+    ))

 ;; -----------------------------------------


Style/indentation change

Style/indentation change

--- src/cljs/zetawar/views.cljs
+++ src/cljs/zetawar/views.cljs
@@ -327,8 +327,12 @@
              [:h4.media-heading
               (:unit-type/description unit-type)]
              (str "Cost: " (:unit-type/cost unit-type))]]
-           [:td ({:unit-type.armor-type/personnel [:abbr {:title "Personnel" :style {:cursor "inherit"}} "P"]
-                  :unit-type.armor-type/armored [:abbr {:title "Armored" :style {:cursor "inherit"}} "A"]}
+           [:td ({:unit-type.armor-type/personnel [:abbr {:title "Personnel"
+                                                          :style {:cursor "inherit"}}
+                                                          "P"]
+                  :unit-type.armor-type/armored [:abbr {:title "Armored"
+                                                        :style {:cursor "inherit"}}
+                                                        "A"]}
                  (get-in unit-type [:unit-type/armor-type]))]
            [:td (:unit-type/movement unit-type)]
            [:td (if (:unit-type/can-capture unit-type)


allow cljsdoc files to rename signature params to align with the custom descriptions

--- src/cljs_api_gen/result.clj
+++ src/cljs_api_gen/result.clj
@@ -35,9 +35,10 @@
 (defn add-cljsdoc
   "Merge the given item with its compiled cljsdoc, containing extra doc info."
   [item]
-  (if-let [cljsdoc (and cljsdoc-map (@cljsdoc-map (:full-name item)))]
-    (merge item (select-keys cljsdoc [:examples :related :description]))
-    item))
+  (let [cljsdoc (and cljsdoc-map (@cljsdoc-map (:full-name item)))]
+    (cond-> item
+      cljsdoc              (merge (select-keys cljsdoc [:examples :related :description]))
+      (:signature cljsdoc) (merge (select-keys cljsdoc [:signature])))))

 (defn transform-item
   [x]


Don't double close client connections.

Don't double close client connections.

Double closing client connections can create unexpected exceptions.

--- src/clojure/picard/pool.clj
+++ src/clojure/picard/pool.clj
@@ -144,7 +144,8 @@
    not returned to the pool."
   [[state] ^Channel conn]
   (debug {:msg "Closing connection" :event conn})
-  (.close conn))
+  (when-not (.isOpen conn)
+    (.close conn)))

 (def default-options
   {:keepalive                   60


add transaction dates to transaction search criteria

--- test/clj_money/permissions/transactions_test.clj
+++ test/clj_money/permissions/transactions_test.clj
@@ -59,7 +59,11 @@
         entity (find-entity context "Personal")]
     (testing "A user has permission to list transactions in his entities"
       (with-authentication john
-        (is (not= 0 (->> (apply-scope {:entity-id (:id entity)} :transaction)
+        (is (not= 0 (->> (apply-scope {:entity-id (:id entity)
+                                       :transaction-date [:between
+                                                          (t/local-date 2015 1 1)
+                                                          (t/local-date 2017 12 31)]}
+                                      :transaction)
                          (transactions/search storage-spec)
                          count))
             "The transactions are returned")))


metadata should filter on [_ meta]

metadata should filter on [_ meta]

--- kafka-clj/src/kafka_clj/metadata.clj
+++ kafka-clj/src/kafka_clj/metadata.clj
@@ -96,7 +96,7 @@
     (filter (complement nil?))
     (filter (complement #(is-blacklisted? % @blacklisted-metadata-producers-ref)))
     (map #(_get-metadata % conf blacklisted-metadata-producers-ref))
-    (filter (complement nil?))
+    (filter (fn [[_ meta] (nil? meta)]))
     first))

 (defn get-metadata [metadata-producers conf & {:keys [blacklisted-metadata-producers-ref] :or {blacklisted-metadata-producers-ref (ref {})}}]


Unwrap help docstring

Unwrap help docstring

--- src/yetibot/core/commands/help.clj
+++ src/yetibot/core/commands/help.clj
@@ -14,8 +14,7 @@
                (sort (keys (get-docs))))))

 (defn help-for-topic
-  "help <topic> # get help for <topic>. If no exact matches are found for topic,
-   it will fallback to the topic with the smallest Levenshtein distance < 2"
+  "help <topic> # get help for <topic>. If no exact matches are found for topic, it will fallback to the topic with the smallest Levenshtein distance < 2"
   [{prefix :args}]
   (or
     (seq (get-docs-for prefix))


Fix invalid response test

Fix invalid response test

--- test/com/wsscode/pathom/connect/planner_readers_test.cljc
+++ test/com/wsscode/pathom/connect/planner_readers_test.cljc
@@ -72,8 +72,8 @@
                                {::pc/output [:a]}
                                (fn [_ _] (throw (ex-info "Error" {:error "detail"}))))]
                 ::query     [:a]})
-             {:a                              :com.wsscode.pathom.core/reader-error
-              :com.wsscode.pathom.core/errors {[:a] "class clojure.lang.ExceptionInfo: Error - {:error \"detail\"}"}})))
+             {:a         ::p/reader-error
+              ::p/errors {[:a] "class clojure.lang.ExceptionInfo: Error - {:error \"detail\"}"}})))

     (testing "invalid response"
       (is (= (run-parser
@@ -81,8 +81,7 @@
                                {::pc/output [:a]}
                                (fn [_ _] 42))]
                 ::query     [:a]})
-             {:a                              :com.wsscode.pathom.core/reader-error,
-              :com.wsscode.pathom.core/errors {[:a] "class clojure.lang.ExceptionInfo: Invalid resolve response - #:com.wsscode.pathom.parser{:response-value 42}"}}))))
+             {:a ::p/not-found}))))

   (testing "multiple attributes on the same resolver"
     (is (= (run-parser


(maint) Fix indentation

(maint) Fix indentation

--- test/unit/puppetlabs/services/master/master_core_test.clj
+++ test/unit/puppetlabs/services/master/master_core_test.clj
@@ -215,8 +215,8 @@
                          "environments/../modules/foo/files/site.pp"
                          "environments/production/modules/foo/files/../../../../../../site.pp"]]
       (testing "valid requests return true"
-      (doseq [path valid-paths]
-        (is (not (nil? (valid-static-file-path? path))))))
+        (doseq [path valid-paths]
+          (is (not (nil? (valid-static-file-path? path))))))
       (testing "invalid requests return false"
         (doseq [path invalid-paths]
           (is (nil? (valid-static-file-path? path)))))))


Fix exec-repl to build in cljs.

Fix exec-repl to build in cljs.

--- src/datomish/exec_repl.cljc
+++ src/datomish/exec_repl.cljc
@@ -13,7 +13,6 @@
      [datomish.sqlite :as s]
      [datomish.sqlite-schema :as ss]
      [datomish.query :as dq]
-     [datomish.transact :as transact]
      #?@(:clj
            [[datomish.jdbc-sqlite]
             [datomish.pair-chan :refer [go-pair <?]]
@@ -42,6 +41,7 @@
   [db find]
   (pair-channel->lazy-seq (db/<?run db find))))

+#_
 (defn xxopen []
     (datomish.pair-chan/go-pair
       (let [d (datomish.pair-chan/<? (s/<sqlite-connection "/tmp/foo.sqlite"))]


cleanup

cleanup

--- Clojure-Websockets/MainApp/src/cljs/birdwatch/ui/tweets.cljs
+++ Clojure-Websockets/MainApp/src/cljs/birdwatch/ui/tweets.cljs
@@ -93,7 +93,6 @@
   [app _ [_ state-snapshot]]
   (when (:live state-snapshot) (reset! app state-snapshot)))

-
 (defn component
   []
   (comp/make-component mk-state nil state-pub-handler))


update example

update example

--- example/src/example/core.cljs
+++ example/src/example/core.cljs
@@ -3,6 +3,8 @@
             [goog.dom :as gdom]
             [cljss.core :as css :refer [inject-global]]
             [cljss.rum :refer-macros [defstyled]]))
+(defn inject-global-styles! []
+  (inject-global styles/globals))

 (def btn-bg-colors
   {:primary "#0052CC"
@@ -115,10 +117,7 @@

 (defn mount []
   (css/remove-styles!)
-  (inject-global
-    {:body {:margin 0
-            :font "normal 16px sans-serif"
-            :color "#242424"}})
+  (inject-global-styles!)
   (render))

-(render)
+(mount)


logging+use [] to create vector rather than (list)

--- src/babel/over.cljc
+++ src/babel/over.cljc
@@ -24,7 +24,7 @@
 ;;    should be treated the same as empty list.
 (defn over [parents child1 & [child2]]
   (cond (map? parents)
-        (over (list parents) child1 child2)
+        (over [parents] child1 child2)

         true
         (mapcat
@@ -57,7 +57,10 @@
     (let [result (unify! (copy parent)
                          {:head (copy head)})]
       (if (not (= :fail result))
-        (list result)
+        (do
+          (log/debug (str "overh success: " (get-in parent [:rule]) "-> cat=" (get-in head [:synsem :cat])))
+          (log/debug (str "overh success: " (get-in parent [:rule]) "-> pred=" (get-in head [:synsem :sem :pred])))
+          [result])
         (log/debug (str "overh: fail-path for rule: " (:rule parent) ":"
                         (fail-path (copy parent) {:head (copy head)})))))))

@@ -86,7 +89,7 @@
          (log/debug (str "overc success: " (get-in parent [:rule]) " -> " (get-in comp [:rule]
                                                                           (get-in comp [:synsem :sem :pred]
                                                                                "(no pred for comp)"))))
-         (list result))
+         [result])
        (log/debug (str "overc: fail-path for rule: " (:rule parent) ":"
                        (fail-path (copy parent) {:comp (copy comp)})))))))


logging improvements

logging improvements

--- src/babel/over.cljc
+++ src/babel/over.cljc
@@ -152,8 +152,8 @@
                      (unifyc parent-value child-value)]
                  (if (fail? result)
                    (do
-                     (log/debug (str "comp precheck failed  for pair: " pair))
-                     (log/debug (str "comp precheck failed: parent wanted: " (strip-refs parent-value) ";"
+                     (log/trace (str "comp precheck failed  for pair: " pair))
+                     (log/trace (str "comp precheck failed: parent wanted: " (strip-refs parent-value) ";"
                                      "child has: " (strip-refs child-value)))
                      (log/trace (str " child is: " (strip-refs child)))
                      :fail)
@@ -187,7 +187,7 @@
           result
           (if head-pre-checks
             (do
-              (log/debug (str "moreover-head: head failed prechecks for parent: " (get-in parent [:rule])))
+              (log/trace (str "moreover-head: head failed prechecks for parent: " (get-in parent [:rule])))
               :fail)
             (unify
              (copy parent)
@@ -211,8 +211,8 @@
         (do
           (if (not (= true head-pre-checks))
             (log/warn (str "moreover-head: pre-checked missed: fail-path-between "
-                           "parent:'" (get-in parent [:rule]) "' and child '" (morph child) "' :"
-                           (fail-path-between parent {:head child}))))
+                           "parent:'" (get-in parent [:rule]) "' and child:"
+                           (get-in child [:rule] (get-in child [:synsem :sem :pred] :nopred)) ".")))
           (if (= *extra-diagnostics* true)
             (let [fail-path (get-fail-path (get-in parent [:head]) child)]
               (log/trace (str "moreover-head: failed to add head: '" (morph child) "' to parent: " (get-in parent [:rule])))
@@ -269,7 +269,7 @@
                   {:comp child}
                   {:comp {:synsem {:sem (lexfn-sem-impl (get-in child '(:synsem :sem) :top))}}}))]
     (if (not (fail? result))
-      (do (log/debug "unification was successful.")
+      (do (log/trace "unification was successful.")
           (merge {:comp-filled true}
                  result))
       ;; else: fail:
@@ -278,7 +278,7 @@
         (if (= false pre-check)
           (log/warn (str "moreover-comp: pre-checked missed: fail-path-between:"
                          (fail-path-between parent {:comp child}))))
-        (log/trace (str "moreover-comp: fail: child: " (strip-refs child)))
+        (log/trace (str "moreover-comp: fail: child: " (get-in child [:rule] (get-in child [:synsem :sem :pred] :no-pred))))
         (if (and
              *throw-exception-if-failed-to-add-complement*
              (get-in child '(:head)))
@@ -337,7 +337,9 @@
          label (if (get-in parent [:rule]) (get-in parent [:rule]) (:comment parent))]
      (if (not is-fail?)
        (do
-         (log/debug (str "overh successful result: " (get-in parent [:rule])))
+         (log/debug (str "overh: " (get-in parent [:rule]) "=>" (get-in head [:rule]
+                                                                        (get-in head [:synsem :sem :pred]
+                                                                                "(no pred for head)"))))
          (log/trace (str "overh successful result: " (strip-refs (dissoc result :serialized))))
          (list result))))))


test-conexp can now test conexp.contrib too

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/main.clj
+++ src/conexp/main.clj
@@ -65,11 +65,18 @@
 	     (< my-patch patch)))))

 (defn test-conexp
-  "Runs tests for conexp."
-  []
-  (require 'conexp.tests :reload-all)
-  (require 'clojure.test)
-  (clojure.test/run-tests 'conexp.tests))
+  "Runs tests for conexp. If with-contrib? is given and true, tests
+  conexp.contrib.tests too."
+  ([] (test-conexp false))
+  ([with-contrib?]
+     (require 'clojure.test)
+     (if with-contrib?
+       (do (require 'conexp.tests
+                    'conexp.contrib.tests)
+           (clojure.test/run-tests 'conexp.tests
+                                   'conexp.contrib.tests))
+       (do (require 'conexp.tests)
+           (clojure.test/run-tests 'conexp.tests)))))

 ;;;


tweaks

tweaks

--- src/konserve/indexeddb.cljs
+++ src/konserve/indexeddb.cljs
@@ -3,7 +3,7 @@
             [konserve.compressor]
             [konserve.encryptor]
             [konserve.impl.defaults :as defaults]
-            [konserve.impl.storage-layout :as storage-layout :refer [PBackingStore]]
+            [konserve.impl.storage-layout :as storage-layout]
             [konserve.serializers]
             [konserve.utils :refer [with-promise]]))

@@ -39,7 +39,7 @@
   (with-promise out
     (let [p (js/window.indexedDB.databases)]
       (.then p #(put! out %))
-      (.catch p #(put! out (ex-info (str "error listing databases")
+      (.catch p #(put! out (ex-info "error listing databases"
                                     {:cause %
                                      :caller 'konserve.indexeddb/list-dbs}))))))

@@ -268,7 +268,7 @@

 (defn connect-idb-store
   "Connect to a IndexedDB backed KV store with the given db name.
-   Optional serializer, read-handlers, write-handlers, buffer-size and config.
+   Optional serializer, read-handlers, write-handlers.

    This implementation stores all values as js/Blobs in an IndexedDB
    object store instance. The object store itself is nameless, and there
@@ -296,16 +296,15 @@
    value offset in the same way that the filestore implementations are. Consumers
    must discard the amount of bytes found in the :offset key of the locked-cb
    arg map. See: https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream"
-  [db-name & {:keys [config] :as params}]
+  [db-name & {:as params}]
   (let [store-config (merge {:default-serializer :FressianSerializer
                              :compressor         konserve.compressor/null-compressor
                              :encryptor          konserve.encryptor/null-encryptor
                              :read-handlers      (atom {})
                              :write-handlers     (atom {})
-                             :config             (merge {:sync-blob? true
-                                                         :in-place? true
-                                                         :lock-blob? true}
-                                                        config)}
+                             :config             {:sync-blob? true
+                                                  :in-place? true
+                                                  :lock-blob? true}}
                             (dissoc params :config))
         backing            (IndexedDBackingStore. db-name nil)]
     (defaults/connect-default-store backing store-config)))


[scamp] Add test for 'update-self.

[scamp] Add test for 'update-self.

--- modules/scamp/test/scamp/core_test.clj
+++ modules/scamp/test/scamp/core_test.clj
@@ -297,3 +297,21 @@
                                    "liebowitz")
          [{:self {:id "canticle"}, :upstream #{"liebowitz"}, :downstream #{} :messages-seen {}} []])))

+(deftest update-self-test
+  (let [new-node (core/node-contact-address->node "node-id0")
+        non-networked-node (core/node-contact-address->node "non-networked-node")]
+    (is (= (-> core/new-world
+             (core/add-new-node new-node)
+             (core/update-self new-node #(update % :upstream conj "flimflam"))
+             (dissoc :config)
+             purge-world-envelope-ids)
+           {:message-envelopes []
+            :network
+            {"node-id0"
+             {:self {:id "node-id0"}, :upstream #{"flimflam"}, :downstream #{} :messages-seen {}}}}))))
+
+(comment
+(binding [scamp.core/*rand* testing-rand*]
+                                                                  (for [comm (range 2 252)]
+                                                                       (-> comm-test-world (core/do-comms comm) (dissoc :config) purge-world-envelope-ids)))
+  )


Test for all-numeric sample id, clinical matrix.

--- test/cavm/db_test.clj
+++ test/cavm/db_test.clj
@@ -604,7 +604,7 @@
                  {:name "probe4" :id 5 :dataset_id 1}])))))

 (defn clinical2 [db]
-  (ct/testing "cgdata clinical matrix2"
+  (ct/testing "cgdata clinical matrix2, clinical features"
     (loader db detector docroot "test/cavm/test_inputs/clinical_matrix2")
     (let [exp (cdb/run-query db {:select [:name :type] :from [:dataset]})
           samples (cdb/run-query db
@@ -622,6 +622,36 @@
                  {:name "sample3"}
                  {:name "sample4"}
                  {:name "sample5"}]))
+      (ct/is (= probes
+                [{:name "sampleID" :id 1 :dataset_id 1}
+                 {:name "probe1" :id 2 :dataset_id 1}
+                 {:name "probe2" :id 3 :dataset_id 1}
+                 {:name "probe3" :id 4 :dataset_id 1}
+                 {:name "probe4" :id 5 :dataset_id 1}]))
+      (ct/is (= features
+                [{:longtitle nil :field_id 1} ; sample name
+                 {:longtitle "A primary probe" :field_id 2}
+                 {:longtitle "A secondary probe" :field_id 3}])))))
+
+(defn clinical3 [db]
+  (ct/testing "cgdata clinical matrix3, numeric sample id"
+    (loader db detector docroot "test/cavm/test_inputs/clinical_matrix3")
+    (let [exp (cdb/run-query db {:select [:name :type] :from [:dataset]})
+          samples (cdb/run-query db
+                                 {:select [[:value :name]]
+                                  :from [:field]
+                                  :where [:= :name "sampleID"]
+                                  :left-join [:code [:= :field.id :field_id]]
+                                  :order-by [:ordering]})
+          probes (cdb/run-query db {:select [:*] :from [:field]})
+          features (cdb/run-query db {:select [:longtitle :field_id] :from [:feature]})]
+      (ct/is (= exp [{:name "clinical_matrix3" :type "clinicalMatrix"}]))
+      (ct/is (= samples
+                [{:name "1"}
+                 {:name "2"}
+                 {:name "3"}
+                 {:name "4"}
+                 {:name "5"}]))
       (ct/is (= probes
                 [{:name "sampleID" :id 1 :dataset_id 1}
                  {:name "probe1" :id 2 :dataset_id 1}
@@ -739,7 +769,7 @@
              detect-cgdata-clinical clinical1
              detect-cgdata-mutation mutation1 mutation2
              gene-pred1 matrix-dup matrix-bad-probe
-             clinical2]]
+             clinical2 clinical3]]
     (fixture t)))

 (ct/deftest test-h2


tweak

tweak

--- .desc.clj
+++ .desc.clj
@@ -55,7 +55,7 @@
  {:name "->" :desc "arg gets inserted as first arg"}
  {:name "->>" :desc "arg gets inserted as last arg"}
  {:name "interpose" :desc "join(a).split(/\\s+/)"}
- {:name "comp" :desc "comp a b c) = (a (b (c))) = opposite of ->>"}
+ {:name "comp" :desc "(comp a b c) = (a (b (c))) = opposite of ->>"}
  {:name "apply" :desc "apply(fn [args]): fn.call(*args)"}
  {:name "partial" :desc "partial(fn *args): #(apply fn *args *&)"}
  {:name "fnil" :desc "sets default for a function expecting non-nil args used in clojure prob 2 as (hash[:key] ||= {}) << 2"}]


Clear status message on cursor move

Clear status message on cursor move

--- src/lt/plugins/rubocop.cljs
+++ src/lt/plugins/rubocop.cljs
@@ -81,8 +81,8 @@

                         (when-not (= (:line previous-posn) (:line current-posn))
                           (if-let [cops ((or (::cops-by-line @editor) {}) (inc (:line current-posn)))]
-                            (notifos/msg* (:message (first cops)))))
-
+                            (notifos/msg* (:message (first cops)))
+                            (notifos/msg* "")))
                         (object/merge! editor {::previous-cursor current-posn}))))

 (behavior ::on-save


Changing default insert count to 10

Changing default insert count to 10

--- src/kiries/core.clj
+++ src/kiries/core.clj
@@ -32,7 +32,7 @@
                      ["-h" "--host" "Interface to listen on." :default "0.0.0.0"]
                      ["-p" "--port" "Port to listen on." :default 9090 :parse-fn #(Integer. %)]
                      ["-r" "--riemann" "Run Riemann internally." :default true :flag true]
-                     ["-t" "--total" "Import total records" :default 1000]
+                     ["-t" "--total" "Import total records" :default 10]
                      ["-d" "--data" "Import test data" :default false :flag true]]
              )]


Wipe the entire $WORKSPACE, not just the repo checkout.

--- src/clj/runbld/main.clj
+++ src/clj/runbld/main.clj
@@ -55,8 +55,9 @@
                             (filter identity)
                             (apply concat))]
         (when wipe-workspace?
-          (io/log "wiping workspace")
-          (clojure.java.shell/sh "find" local "-mindepth" "1" "-delete"))
+          (let [workspace (System/getenv "WORKSPACE")]
+            (io/log "wiping workspace" workspace)
+            (clojure.java.shell/sh "find" workspace "-mindepth" "1" "-delete")))
         (io/log "cloning" remote)
         (git/git-clone local remote clone-args)
         (io/log "done cloning")))))


Fix input string to handle null-terminated string

--- src/cljam/io/bigwig.clj
+++ src/cljam/io/bigwig.clj
@@ -39,7 +39,7 @@
                     root-offset])

 ; Currently, max number of zoom levels (i.e. max number of zoom headers) is 10,
-; the number is small. Therefore, we choose a record containing vector of zoom
+; the numberais small. Therefore, we choose a record containing vector of zoom
 ; header instead of a flat record.
 ; Cf. https://github.com/ucscGenomeBrowser/kent/blob/3a0198acd1f859a603f5aad90188bee2d82efe0c/src/inc/bbiFile.h#L384
 (defrecord BigWigHeaders [^FixedWidthHeader fixed-width-header
@@ -200,12 +200,26 @@
      fixed-width-header zoom-headers total-summary extended-header bpt-header
      bbi-chrom-info cir-tree)))

+(defn- read-c-style-string
+  "Reads `length` bytes and returns a string. This function is useful for
+  handling c-style null-terminated string."
+  [^RandomAccessFile r ^long length]
+  (->> (lsb/read-bytes r length)
+       (reduce
+        (fn [cs c]
+          (if (zero? c)
+            (reduced cs)
+            (conj cs c)))
+        [])
+       (map char)
+       (apply str)))
+
 (defn- read-bbi-chrom-info-leaves
   "Returns the BbiChromInfo data of leaves."
   [^RandomAccessFile r key-size child-count]
   (repeatedly child-count
               (fn []
-                (let [name (lsb/read-string r key-size)
+                (let [name (read-c-style-string r key-size)
                       id (lsb/read-uint r)
                       size (lsb/read-uint r)]
                   (BbiChromInfo.
@@ -273,7 +287,7 @@
               (if leaf?
                 (letfn [(read-leaves [n]
                           (when-not (zero? n)
-                            (let [key (lsb/read-string r key-size)
+                            (let [key (read-c-style-string r key-size)
                                   id (lsb/read-uint r)
                                   _size (lsb/read-uint r)]
                               (if (zero? (compare chrom key))
@@ -284,7 +298,7 @@
                   (letfn [(through-remainder [n offset]
                             (if (or (zero? n)
                                     (neg? (compare chrom
-                                                   (lsb/read-string r key-size))))
+                                                   (read-c-style-string r key-size))))
                               offset
                               (recur (dec n) (lsb/read-ushort r))))]
                     (recur (through-remainder (dec child-count)


Changes to remove calls to truth_. move identical? nil? not higher up. eliminate the declare. similarly move Reduced, reduced, reduced?, counted?, indexed? and eliminate declares around them. eliminate truth_ call in find. set *unchecked-if* true for body of apply.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -35,12 +35,24 @@
   ^{:doc "bound in a repl thread to the third most recent value printed"}
   *3)

-(declare not nil? identical)
-
 (defn truth_
   "Internal - do not use!"
   [x]
   (js* "(~{x} != null && ~{x} !== false)"))
+
+(defn ^boolean identical?
+  "Tests if 2 arguments are the same object"
+  [x y]
+  (cljs.core/identical? x y))
+
+(defn ^boolean nil?
+  "Returns true if x is nil, false otherwise."
+  [x]
+  (coercive-= x nil))
+
+(defn ^boolean not
+  "Returns true if x is logical false, false otherwise."
+  [x] (if x false true))

 (set! *unchecked-if* true)
 (defn ^boolean type_satisfies_
@@ -295,12 +307,26 @@
   (-chunked-next [coll]))

 ;;;;;;;;;;;;;;;;;;; fundamentals ;;;;;;;;;;;;;;;
-(defn ^boolean identical?
-  "Tests if 2 arguments are the same object"
-  [x y]
-  (cljs.core/identical? x y))
-
-(declare first next)
+
+(defn first
+  "Returns the first item in the collection. Calls seq on its
+  argument. If coll is nil, returns nil."
+  [coll]
+  (when-not (nil? coll)
+    (if (satisfies? ISeq coll)
+      (-first coll)
+      (let [s (seq coll)]
+        (when-not (nil? s)
+          (-first s))))))
+
+(defn ^seq next
+  "Returns a seq of the items after the first. Calls seq on its
+  argument.  If there are no more items, returns nil"
+  [coll]
+  (when-not (nil? coll)
+    (if (satisfies? INext coll)
+      (-next coll)
+      (seq (rest coll)))))

 (defn ^boolean =
   "Equality. Returns true if x equals y, false if not. Compares
@@ -316,11 +342,6 @@
          (= y (first more)))
        false)))

-(defn ^boolean nil?
-  "Returns true if x is nil, false otherwise."
-  [x]
-  (coercive-= x nil))
-
 (defn type [x]
   (when-not (nil? x)
     (.-constructor x)))
@@ -422,7 +443,21 @@
   "Returns a number one greater than num."
   [x] (cljs.core/+ x 1))

-(declare reduced? deref)
+(declare deref)
+
+(deftype Reduced [val]
+  IDeref
+  (-deref [o] val))
+
+(defn reduced
+  "Wraps x in a way such that a reduce will terminate with the value x"
+  [x]
+  (Reduced. x))
+
+(defn ^boolean reduced?
+  "Returns true if x is the result of a call to reduced"
+  [r]
+  (instance? Reduced r))

 (defn- ci-reduce
   "Accepts any collection which satisfies the ICount and IIndexed protocols and
@@ -488,7 +523,15 @@
                (recur nval (inc n))))
            val)))))

-(declare hash-coll cons pr-str counted? RSeq)
+(declare hash-coll cons pr-str RSeq)
+
+(defn ^boolean counted?
+  "Returns true if coll implements count in constant time"
+  [x] (satisfies? ICounted x))
+
+(defn ^boolean indexed?
+  "Returns true if coll implements nth in constant time"
+  [x] (satisfies? IIndexed x))

 (deftype IndexedSeq [a i]
   Object
@@ -639,16 +682,6 @@
       coll
       (-seq coll))))

-(defn first
-  "Returns the first item in the collection. Calls seq on its
-  argument. If coll is nil, returns nil."
-  [coll]
-  (when-not (nil? coll)
-    (if (satisfies? ISeq coll)
-      (-first coll)
-      (let [s (seq coll)]
-        (when-not (nil? s)
-          (-first s))))))

 (defn ^seq rest
   "Returns a possibly empty seq of the items after the first. Calls seq on its
@@ -663,15 +696,6 @@
           ())))
     ()))

-(defn ^seq next
-  "Returns a seq of the items after the first. Calls seq on its
-  argument.  If there are no more items, returns nil"
-  [coll]
-  (when-not (nil? coll)
-    (if (satisfies? INext coll)
-      (-next coll)
-      (seq (rest coll)))))
-
 (defn second
   "Same as (first (next x))"
   [coll]
@@ -708,10 +732,6 @@
 (extend-type default
   IEquiv
   (-equiv [x o] (identical? x o)))
-
-(defn ^boolean not
-  "Returns true if x is logical false, false otherwise."
-  [x] (if x false true))

 (defn conj
   "conj[oin]. Returns a new collection with the xs
@@ -729,8 +749,6 @@
   [coll]
   (-empty coll))

-(declare counted?)
-
 (defn- accumulating-seq-count [coll]
   (loop [s (seq coll) acc 0]
     (if (counted? s) ; assumes nil is counted, which it currently is
@@ -744,8 +762,6 @@
   (if (counted? coll)
     (-count coll)
     (accumulating-seq-count coll)))
-
-(declare indexed?)

 (defn- linear-traversal-nth
   ([coll n]
@@ -906,14 +922,6 @@
   "Returns true if coll satisfies ISequential"
   [x] (satisfies? ISequential x))

-(defn ^boolean counted?
-  "Returns true if coll implements count in constant time"
-  [x] (satisfies? ICounted x))
-
-(defn ^boolean indexed?
-  "Returns true if coll implements nth in constant time"
-  [x] (satisfies? IIndexed x))
-
 (defn ^boolean reduceable?
   "Returns true if coll satisfies IReduce"
   [x] (satisfies? IReduce x))
@@ -1037,7 +1045,7 @@
 (defn find
   "Returns the map entry for key, or nil if key not present."
   [coll k]
-  (when (and coll
+  (when (and (not (nil? coll))
              (associative? coll)
              (contains? coll k))
     [k (-lookup coll k)]))
@@ -1181,20 +1189,6 @@
   where the keys will be the ordinals."
   ([f init coll]
      (-kv-reduce coll f init)))
-
-(deftype Reduced [val]
-  IDeref
-  (-deref [o] val))
-
-(defn ^boolean reduced?
-  "Returns true if x is the result of a call to reduced"
-  [r]
-  (instance? Reduced r))
-
-(defn reduced
-  "Wraps x in a way such that a reduce will terminate with the value x"
-  [x]
-  (Reduced. x))

 ;;; Math - variadic forms will not work until the following implemented:
 ;;; first, next, reduce
@@ -2107,6 +2101,7 @@
 ;; see core.clj
 (gen-apply-to)

+(set! *unchecked-if* true)
 (defn apply
   "Applies fn f to the argument list formed by prepending intervening arguments to args.
   First cut.  Not lazy.  Needs to use emitted toApply."
@@ -2154,6 +2149,7 @@
             (apply-to f bc arglist)
             (.cljs$lang$applyTo f arglist)))
          (.apply f f (to-array arglist))))))
+(set! *unchecked-if* false)

 (defn vary-meta
  "Returns an object of the same type and value as obj, with


Fix sample posts retrieve.

Fix sample posts retrieve.

--- src/oc/storage/api/orgs.clj
+++ src/oc/storage/api/orgs.clj
@@ -45,10 +45,11 @@

 (defn- default-entries-for
   "Return any sample posts for a specific board slug."
-  [board-slug]
+  [board-name]
   (try
-    (->
-      (str "samples/" board-slug ".edn")
+    (->> board-name
+      (slugify/slugify)
+      (format "samples/%s.edn")
       (clojure.java.io/resource)
       (slurp)
       (read-string))


Add more documentation.

Add more documentation.

--- test/such/clojure/core.clj
+++ test/such/clojure/core.clj
@@ -8,24 +8,31 @@
             clojure.string)
   (:use midje.sweet))

+;; Here are the three ways to immigrate:
+;; 1. Every public var in a set of namespaces
 (immigrate/namespaces 'such.shorthand 'such.types)
+;; 2. Selected vars in a single namespace
+(immigrate/selection 'such.immigration '[move-var! selection])
+;; 3. Every public var in a namespace, with the resulting vars in this namespace prefixed.
+(immigrate/prefixed 'clojure.string "str-")
+;; Go to the f_core.clj file in this directory to see use of this namespace.

-(immigrate/selection 'such.immigration '[move-var! selection])
+
+;; Other possibly interesting facts

 (fact "you can immigrate a private var, but it remains private (see f-core for confirmation)"
   (meta #'move-var!) => (contains {:private true}))

-(selection 'clojure.set '[union])

-(immigrate/prefixed 'clojure.string "str-")

-;; It is safe to immigrate twice
+;; It is safe to immigrate twice.
+(selection 'clojure.set '[union]) ; Note that the immigrated `selection` needn't be namespace-quolified
 (selection 'clojure.set '[union intersection])

-;; Demonstrate handling of existing ns-map entries.
+;; Existing vars (ns-map entries) are overwritten silently.

-(fact
+(fact "we start out with nothing"
   (contains? (ns-map *ns*) 'root-value) => false
   (contains? (ns-map *ns*) 'has-root-value?) => false)

@@ -33,22 +40,24 @@
 ;; ... as will this referred value
 (require '[such.vars :refer [has-root-value?]])

-(fact
+(fact "The above two lines produce this situation:"
   (contains? (ns-map *ns*) 'root-value) => true
   (contains? (ns-interns *ns*) 'root-value) => true
   (contains? (ns-refers *ns*) 'root-value) => false
+  root-value => string?

   (contains? (ns-map *ns*) 'has-root-value?) => true
   (contains? (ns-interns *ns*) 'has-root-value?) => false
   (contains? (ns-refers *ns*) 'has-root-value?) => true)

+;; Now we immigrate "over" the previous versions.
 (immigrate/namespaces 'such.vars)

 (fact "the interned value is interned - but with a different value"
   (contains? (ns-map *ns*) 'root-value) => true
   (contains? (ns-interns *ns*) 'root-value) => true
   (contains? (ns-refers *ns*) 'root-value) => false
-  ((find-var *ns* 'root-value) 'root-value) =not=> string?)
+  (root-value 'root-value) =not=> string?)

 (fact "the referred value is now interned"
   (contains? (ns-map *ns*) 'has-root-value?) => true


Make delete functions work by passing a head, not just the name of a head

--- src/doctopus/db.clj
+++ src/doctopus/db.clj
@@ -100,9 +100,9 @@
           (where {:name (:name tentacle)})))

 (defn delete-tentacle!
-  [name]
+  [tentacle]
   (delete tentacles
-          (where {:name name})))
+          (where {:name (:name tentacle)})))

 (defn get-head
   [name]
@@ -129,6 +129,6 @@
           (where {:name (:name head)})))

 (defn delete-head!
-  [name]
+  [head]
   (delete heads
-          (where {:name name})))
+          (where {:name (:name head)})))


Remove pulling in core - to stop a cyclic dependency.

--- src/overtone/repl/debug.clj
+++ src/overtone/repl/debug.clj
@@ -1,6 +1,5 @@
 (ns overtone.repl.debug
   (:use [clojure.pprint]
-        [overtone.core]
         [overtone.sc.machinery.ugen.defaults]
         [overtone.helpers seq]))


Zap extraneous `do`, keep the context flowing

--- src/vip/data_processor/db/translations/v5_1/election_administrations.clj
+++ src/vip/data_processor/db/translations/v5_1/election_administrations.clj
@@ -44,8 +44,7 @@
               import-id
               (election-administrations->ltree import-id idx-fn))]
     (if (seq rows)
-      (do
-        (-> ctx
+      (-> ctx
             (postgres/bulk-import postgres/xml-tree-values rows)
             (assoc :ltree-index (idx-fn)))
-        ctx))))
+      ctx)))


CMR-2579: Fixing provider ingest test for Access control group API changes.

--- system-int-test/test/cmr/system_int_test/ingest/provider_ingest_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/provider_ingest_test.clj
@@ -114,10 +114,12 @@
           coll3 (d/ingest "PROV2" (dc/collection))
           gran4 (d/ingest "PROV2" (dg/granule coll3))
           ;; create an access group to test cascading deletes
-          access-group (access-control/create-group (transmit-config/echo-system-token)
-                                                    {:name "Administrators"
-                                                     :description "A Group"
-                                                     :provider-id "PROV1"})]
+          access-group (u/map-keys->kebab-case
+                        (access-control/create-group
+                         (transmit-config/echo-system-token)
+                         {:name "Administrators"
+                          :description "A Group"
+                          :provider_id "PROV1"}))]
       (index/wait-until-indexed)

       (is (= 2 (count (:refs (search/find-refs :collection {:provider-id "PROV1"})))))
@@ -125,8 +127,9 @@

       ;; ensure PROV1 group is indexed
       (is (= [(:concept-id access-group)]
-             (map :concept-id (:items (access-control/search (transmit-config/echo-system-token)
-                                                             {:provider "PROV1"})))))
+             (map :concept-id (:items (u/map-keys->kebab-case
+                                       (access-control/search (transmit-config/echo-system-token)
+                                                              {:provider "PROV1"}))))))

       ;; delete provider PROV1
       (let [{:keys [status content-length]} (ingest/delete-ingest-provider "PROV1")]
@@ -136,40 +139,40 @@

       ;; PROV1 concepts are not in metadata-db
       (are [concept]
-           (not (mdb/concept-exists-in-mdb? (:concept-id concept) (:revision-id concept)))
-           coll1
-           coll2
-           gran1
-           gran2
-           gran3
-           access-group)
+        (not (mdb/concept-exists-in-mdb? (:concept-id concept) (:revision-id concept)))
+        coll1
+        coll2
+        gran1
+        gran2
+        gran3
+        access-group)

       ;; PROV1 access group is unindexed
       (is (= 0 (:hits
-                 (access-control/search (transmit-config/echo-system-token)
-                                        {:provider "PROV1"}))))
+                (access-control/search (transmit-config/echo-system-token)
+                                       {:provider "PROV1"}))))

       ;; PROV2 concepts are in metadata-db
       (are [concept]
-           (mdb/concept-exists-in-mdb? (:concept-id concept) (:revision-id concept))
-           coll3
-           gran4)
+        (mdb/concept-exists-in-mdb? (:concept-id concept) (:revision-id concept))
+        coll3
+        gran4)

       ;; search on PROV1 finds nothing
       (is (d/refs-match?
-            []
-            (search/find-refs :collection {:provider-id "PROV1"})))
-      (is (d/refs-match?
-            []
-            (search/find-refs :granule {:provider-id "PROV1"})))
+           []
+           (search/find-refs :collection {:provider-id "PROV1"})))
+      (is (d/refs-match?
+           []
+           (search/find-refs :granule {:provider-id "PROV1"})))

       ;; search on PROV2 finds the concepts
       (is (d/refs-match?
-            [coll3]
-            (search/find-refs :collection {:provider-id "PROV2"})))
-      (is (d/refs-match?
-            [gran4]
-            (search/find-refs :granule {:provider-id "PROV2"})))))
+           [coll3]
+           (search/find-refs :collection {:provider-id "PROV2"})))
+      (is (d/refs-match?
+           [gran4]
+           (search/find-refs :granule {:provider-id "PROV2"})))))

   (testing "delete non-existent provider"
     (let [{:keys [status errors content-type]} (ingest/delete-ingest-provider "NON_EXIST")]
@@ -194,10 +197,12 @@
   (doseq [provider [{:provider-id "SMALL" :short-name "SP" :cmr-only true :small true}
                     {:provider-id "NOTSMALL" :short-name "NSP"}]]
     (ingest/create-ingest-provider provider)
-    (let [access-group (access-control/create-group (transmit-config/echo-system-token)
-                                                    {:name "Administrators"
-                                                     :description "A Group"
-                                                     :provider-id (:provider-id provider)})]
+    (let [access-group (u/map-keys->kebab-case
+                        (access-control/create-group
+                         (transmit-config/echo-system-token)
+                         {:name "Administrators"
+                          :description "A Group"
+                          :provider_id (:provider-id provider)}))]
       (is (mdb/concept-exists-in-mdb? (:concept-id access-group) (:revision-id access-group)))
       (ingest/delete-ingest-provider (:provider-id provider))
       (is (not (mdb/concept-exists-in-mdb? (:concept-id access-group) (:revision-id access-group))))


Rename `pattern` to `one-token-pattern` to make it clear it is just for single-token regexes.

--- src/isla/parser.clj
+++ src/isla/parser.clj
@@ -3,7 +3,9 @@
   (:use [isla.lexer])
   (:require [clojure.string :as str]))

-(declare parse alternatives is-type pattern-sequence pattern nnode pattern-sequence-selector
+(declare parse nnode
+         alternatives is-type pattern-sequence pattern
+         pattern-sequence-selector one-token-pattern
          -root -block -expression -assignment -invocation
          -nl -integer -is -string -assignee -value -identifier)

@@ -38,26 +40,27 @@

 ;; atoms

-(defn -nl [tokens] (pattern tokens :nl :nl))
+(defn -nl [tokens] (one-token-pattern tokens :nl :nl))

 (defn -is [tokens]
-  (pattern tokens #"is" :is (fn [x] [:is])))
+  (one-token-pattern tokens #"is" :is (fn [x] [:is])))

 ;; values

 (defn -value [tokens]
   (pattern-sequence-selector tokens [-string -integer -identifier] :value))

-(defn -assignee [tokens] (pattern tokens #"[A-Za-z]+" :assignee))
+(defn -assignee [tokens] (one-token-pattern tokens #"[A-Za-z]+" :assignee))

-(defn -identifier [tokens] (pattern tokens #"(?!^is$)[A-Za-z]+" :identifier))
+(defn -identifier [tokens] (one-token-pattern tokens #"(?!^is$)[A-Za-z]+" :identifier))

 (defn -integer [tokens]
   (if (is-type #"[0-9]+" (first tokens))
     {:node (nnode :integer [(Integer/parseInt (first tokens))]) :left-tokens (rest tokens)}))

 (defn -string [tokens]
-  (pattern tokens #"'[A-Za-z0-9 ]+'" :string (fn [x] [(str/replace (first tokens) "'" "")])))
+  (one-token-pattern tokens #"'[A-Za-z0-9 ]+'" :string
+                     (fn [x] [(str/replace (first tokens) "'" "")])))

 ;; helpers

@@ -96,7 +99,7 @@
           (pattern-sequence left-tokens (rest patterns) (conj collected node)) ;; round again
           nil))))) ;; pattern match failure token match failure - return

-(defn pattern [tokens matcher tag & args]
+(defn one-token-pattern [tokens matcher tag & args]
   (if (is-type matcher (first tokens))
     (let [output (if (not= nil args)
                    ((first args) (first tokens))