streams/adjust is no longer a multimethod.

Also document that streams/smap is to be preferred to adjust's
functional form.

--- src/riemann/streams.clj
+++ src/riemann/streams.clj
@@ -765,7 +765,7 @@
         (let [e (if (nil? (k event)) (assoc event k v) event)]
           (call-rescue e children))))))

-(defmulti adjust
+(defn adjust
   "Passes on a changed version of each event by applying a function to a
   particular field or to the event as a whole.

@@ -777,26 +777,24 @@

   takes {:service \"foo\"} and emits {:service \"foo rate\"}.

-  If a function is passed to adjust instead of a sequence, the entire event will
-  be given to the function and the result will be passed along to the children.
-  For example:
+  If a function is passed to adjust instead of a vector, adjust behaves like
+  smap: the entire event will be given to the function and the result will be
+  passed along to the children. For example:

   (adjust #(assoc % :metric (count (:tags %))) ...)

   takes {:tags [\"foo\" \"bar\"]} and emits {:tags [\"foo\" \"bar\"] :metric 2}.
-  "
-  (fn [& args] (vector? (first args))))
-
-(defmethod adjust true [[field f & args] & children]
-  (fn [event]
-    (let [value (apply f (field event) args)
-          event (assoc event field value)]
-      (call-rescue event children))))
-
-(defmethod adjust false [f & children]
-  (fn [event]
-    (call-rescue (f event) children)))
-
+
+  Prefer (smap f & children) to (adjust f & children) where possible."
+  [& args]
+  (if (vector? (first args))
+    ; Adjust a particular field in the event.
+    (let [[[field f & args] & children] args]
+      (fn [event]
+        (let [value (apply f (field event) args)
+              event (assoc event field value)]
+          (call-rescue event children))))
+    (apply smap (first args) (rest args))))

 (defmacro by
   "Splits stream by field.


perf tests

perf tests

--- perf-test/clj/reitit/middleware_interceptor_perf.clj
+++ perf-test/clj/reitit/middleware_interceptor_perf.clj
@@ -5,6 +5,8 @@
             [reitit.interceptor :as interceptor]

             reitit.chain
+            sieppari.queue
+            sieppari.core
             io.pedestal.interceptor
             io.pedestal.interceptor.chain))

@@ -34,12 +36,12 @@
 (def +items+ 10)

 (defn expected! [x]
-  (assert (= (range +items+) (:values x))))
+  (println x)
+  #_(assert (= (range +items+) (:values x))))

 (defn middleware [handler value]
   (fn [request]
-    (let [values (or (:values request) [])]
-      (handler (assoc request :values (conj values value))))))
+    (handler request)))

 (def map-request {})
 (def record-request (map->RequestOrContext map-request))
@@ -49,18 +51,21 @@
         app (middleware/chain mw identity)]

     ;; 1000ns
+    ;;   18ns (identity)
     (title "middleware - map")
     (expected! (app map-request))
     (cc/quick-bench
       (app map-request))

     ;;  365ns
+    ;;   21ns (identity)
     (title "middleware - record")
     (expected! (app record-request))
     (cc/quick-bench
       (app record-request))

-    ;; 6900ns
+    ;;  6900ns
+    ;; 10000ns (identity)
     (title "middleware - dynamic")
     (expected! ((middleware/chain mw identity) record-request))
     (cc/quick-bench
@@ -70,10 +75,7 @@
   (let [interceptors (conj
                        (mapv
                          (fn [value]
-                           {:enter (fn [ctx]
-                                     (let [request (:request ctx)
-                                           values (conj (or (:values request) []) value)]
-                                       (assoc ctx :request (assoc request :values values))))})
+                           {:enter identity})
                          (range +items+))
                        identity)
         queue (sieppari.queue/into-queue interceptors)
@@ -81,24 +83,28 @@
         app2 (fn [req] (sieppari.core/execute queue req))]

     ;; 5500ns
+    ;; 4000ns (identity)
     (title "sieppari - map")
     (expected! (app map-request))
     (cc/quick-bench
       (app map-request))

     ;; 4600ns
+    ;; 3800ns (identity)
     (title "sieppari - record")
     (expected! (app record-request))
     (cc/quick-bench
       (app record-request))

     ;; 2200ns
+    ;; 1300ns (identity)
     (title "sieppari - map (compiled queue)")
     (expected! (app2 map-request))
     (cc/quick-bench
       (app2 map-request))

     ;; 1600ns
+    ;; 1300ns (identity)
     (title "sieppari - record (compiled queue)")
     (expected! (app2 record-request))
     (cc/quick-bench
@@ -147,24 +153,14 @@
 (defn pedestal-chain-text []
   (let [is (map io.pedestal.interceptor/interceptor
                 (map (fn [value]
-                       {:enter (interceptor value)}) (range +items+)))
+                       {:enter identity}) (range +items+)))
         ctx (io.pedestal.interceptor.chain/enqueue nil is)]

     ;; 8400ns
+    ;; 7200ns (identity)
     (title "pedestal")
     (cc/quick-bench
       (io.pedestal.interceptor.chain/execute ctx))))
-
-#_(defn pedestal-tuned-chain-text []
-    (let [is (map io.pedestal.interceptor/interceptor
-                  (map (fn [value]
-                         {:enter (interceptor value)}) (range +items+)))
-          ctx (reitit.chain/map->Context (reitit.chain/enqueue nil is))]
-
-      ;; 67 µs
-      (title "pedestal - tuned")
-      (cc/quick-bench
-        (reitit.chain/execute ctx))))

 ;;
 ;; Naive chain
@@ -280,7 +276,6 @@
   (middleware-test)
   (sieppari-test)
   (pedestal-chain-text)
-  (pedestal-tuned-chain-text)
   (interceptor-chain-test))

 ; Middleware (static chain) => 5µs


Properly annotate some const fns

Properly annotate some const fns

--- src/caesium/binding.clj
+++ src/caesium/binding.clj
@@ -199,20 +199,20 @@
       ^bytes ^{Pinned {}} salt
       ^bytes ^{Pinned {}} personal]]

-    [^int crypto_hash_sha256_bytes []]
+    [^long ^{size_t {}} crypto_hash_sha256_bytes []]
     [^int crypto_hash_sha256
      [^bytes ^{Pinned {}} buf
       ^bytes ^{Pinned {}} msg
       ^long ^{LongLong {}} msglen]]

-    [^int crypto_hash_sha512_bytes []]
+    [^long ^{size_t {}} crypto_hash_sha512_bytes []]
     [^int crypto_hash_sha512
      [^bytes ^{Pinned {}} buf
       ^bytes ^{Pinned {}} msg
       ^long ^{LongLong {}} msglen]]

-    [^int ^{size_t {}} crypto_scalarmult_bytes []]
-    [^int ^{size_t {}} crypto_scalarmult_scalarbytes []]
+    [^long ^{size_t {}} crypto_scalarmult_bytes []]
+    [^long ^{size_t {}} crypto_scalarmult_scalarbytes []]
     [^String crypto_scalarmult_primitive []]

     [^int crypto_scalarmult_base


fix max column width violation

fix max column width violation

--- src/calfpath/route.cljc
+++ src/calfpath/route.cljc
@@ -49,7 +49,7 @@
 ;
 ;(let [m0 (:matcher (get routes 0))
 ;      h0 (or (:handler (get routes 0))
-;           (make-handler (:nested (get routes 0))))
+;           (make-handler (:nested (get routes 0))))
 ;      m1 ; similar to m0, for element 1
 ;      h1 ; similar to h0, for element 1
 ;      ....]
@@ -381,7 +381,7 @@
             (i/expected "HTTP method key to be retrievable as a keyword or keyword-set value" spec))
           (cond
             (keyword? method) (-> spec
-                                ;; Clojure (not CLJS) keywords are interned; compare identity (faster) instead of equality
+                                ;; Clojure (not CLJS) keywords are interned; compare identity (faster), not equality
                                 (assoc :matcher (fn method-matcher [request]
                                                   (when (#?(:cljs = :clj identical?)
                                                           (:request-method request) method)


Wrapping riemann port in read-string

Wrapping riemann port in read-string

--- src/stravinski/core.clj
+++ src/stravinski/core.clj
@@ -91,6 +91,6 @@
                               #'riemann-submit #'errors? #'success? #'stats-agent)]
     (if (nil? @riemann-conn)
       (reset! riemann-conn (riemann.client/tcp-client :host (or (System/getenv "RIEMANN_HOST") (assert-get "riemann.host"))
-                                                      :port (or (System/getenv "RIEMANN_PORT") (read-string (assert-get "riemann.port"))))))
+                                                      :port (or (read-string (System/getenv "RIEMANN_PORT")) (read-string (assert-get "riemann.port"))))))
     (binding [*out* *out*]
       (f processor-fn creds-map track-params))))


working on it..

working on it..

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -17,10 +17,10 @@
 (def ^:const mapfn map)

 ;; deterministic generation:
-(def ^:const shufflefn (fn [x] x))
+;;(def ^:const shufflefn (fn [x] x))

 ;; nondeterministic generation
-;;(def ^:const shufflefn shuffle)
+(def ^:const shufflefn shuffle)

 (def ^:const randomize-lexemes-before-phrases
   false)
@@ -51,30 +51,35 @@
             (assoc
              (comp-paths-to-complements bolt (find-comp-paths bolt) model depth max-depth)
              [] [bolt])))
-     (mapcat (fn [each-bolt-and-comps] ;; for each such map in each bolt, find all possible combinations of complements, taking one complement per path.
-               ;; the result is a trellis for each bolt, and a path through this trellis is one complement for each complement position.
-               (map (fn [each-path-through-trellis]
-                      (zipmap (keys each-bolt-and-comps)
-                              each-path-through-trellis))
-                    (apply combo/cartesian-product (vals each-bolt-and-comps)))))
-     (map (fn [bolt-and-comps]
-            (apply unify
-                   (let [bolt (get bolt-and-comps [])
-                         paths-and-comps (dissoc bolt-and-comps [])
-                         paths (keys paths-and-comps)]
-                     (cons bolt
-                           (map (fn [path]
-                                  (let [result (assoc-in bolt path (get paths-and-comps path))]
-                                    (if (= true truncate)
-                                      (dissoc-paths result [path])
-                                      result)))
-                                paths))))))
-     (map (fn [expression]
-            (do-defaults expression model)))
-     (filter not-fail?)
-     (map (fn [final]
-            (log/trace (str "final: " ((:morph-ps model) final)))
-            final)))))
+     (map (fn [each-bolt-and-comps] ;; for each such map in each bolt, find all possible combinations of complements, taking one complement per path.
+            ;; the result is a trellis for each bolt, and a path through this trellis is one complement for each complement position.
+            (map (fn [each-path-through-trellis]
+                   (zipmap (keys each-bolt-and-comps)
+                           each-path-through-trellis))
+                 (apply combo/cartesian-product (vals each-bolt-and-comps)))))
+     (filter #(not (empty? %)))
+     (map (fn [bolt-group]
+            (->> bolt-group
+                 (map (fn [bolt-and-comps]
+                        (apply unify
+                               (let [bolt (get bolt-and-comps [])
+                                     paths-and-comps (dissoc bolt-and-comps [])
+                                     paths (keys paths-and-comps)]
+                                 (cons bolt
+                                       (map (fn [path]
+                                              (let [result (assoc-in bolt path (get paths-and-comps path))]
+                                                (if (= true truncate)
+                                                  (dissoc-paths result [path])
+                                                  result)))
+                                            paths))))))
+                 (filter #(not (= :fail %))))))
+;     (map (fn [expression]
+;            (do-defaults expression model)))
+;     (filter not-fail?)
+;     (map (fn [final]
+;            (log/trace (str "final: " ((:morph-ps model) final)))
+;            final))
+     )))

 (defn generate
   "Return one (by default) or _n_ (using :take _n_) expressions matching spec _spec_ given the model _model_."
@@ -147,6 +152,7 @@

 ;; TODO: rewrite using (recur)
 (defn comp-paths-to-complements [bolt comp-paths model depth max-depth]
+  (log/info (str "comp-paths-to-complements: depth=" depth "; max-depth: " max-depth ":" ((:morph-ps model) bolt)))
   (if (not (empty? comp-paths))
     (let [path (first comp-paths)
           comps (filter not-fail? (comp-path-to-complements bolt path model depth max-depth))]
@@ -171,14 +177,13 @@
 (defn comp-path-to-complements
   "return a lazy sequence of bolts for all possible complements that can be added to the end of the _path_ within _bolt_."
   [bolt path model depth max-depth]
-  (log/info (str "comp-path-to-complements:" depth "/" max-depth ":" ((:morph-ps model) bolt) "@" path))
+  (log/debug (str "comp-path-to-complements:" depth "/" max-depth ":" ((:morph-ps model) bolt) "@" path))
   (let [spec (get-in bolt path)
         lexemes (shufflefn (get-lexemes model spec))
         bolts-at (if (< depth max-depth)
-                   (generate-all
-                    (get-in bolt path)
-                    model
-                    (+ 1 depth) max-depth))
+                           ;;                                   (generate-all (get-in bolt path) model
+                           (lightning-bolts model (get-in bolt path)
+                                            (+ 1 depth) max-depth))
         lexemes-before-phrases
         (lexemes-before-phrases depth max-depth)]
     (if lexemes-before-phrases


+(defn add-bolt-at)

+(defn add-bolt-at)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -119,6 +119,8 @@
       (lazy-cat lexemes bolts-at)
       (lazy-cat bolts-at lexemes))))

+(declare add-bolt-at)
+
 (defn add-comps
   "given a bolt, return the lazy sequence of all bolts derived from this bolt after adding,
    at each supplied path in comp-paths, the bolts for that path."
@@ -134,29 +136,27 @@
                           depth max-depth top-bolt path-from-top)
               (let [path (first comp-paths)
                     bolts-at (first bolts-at-paths)]
-                (log/debug (str "add-comps to: "
-                                (if (not (= bolt top-bolt))
-                                  (str ((:morph-ps model) top-bolt)
-                                       "/"))
-                                ((:morph-ps model) bolt) "@" path))
                 (flatten
                  (mapfn
                   (fn [bolt-at]
-                    (if (= false (get-in bolt-at [:phrasal]))
-                      [(do-defaults (assoc-in bolt path bolt-at) model)]
-                      (let [comp-paths (find-comp-paths bolt-at)
-                            comp-bolts (map #(comp-path-to-bolts bolt-at % model (+ 1 depth) max-depth)
-                                            comp-paths)]
-                        (when (not (some empty? comp-bolts))
-                          (mapfn #(do-defaults (assoc-in bolt path %) model)
-                                 (add-comps bolt-at
-                                            model
-                                            comp-paths
-                                            comp-bolts
-                                            (+ 1 depth)
-                                            max-depth
-                                            top-bolt))))))
+                    (add-bolt-at top-bolt bolt path bolt-at model depth max-depth))
                   bolts-at))))))))
+
+(defn add-bolt-at [top-bolt bolt path bolt-at model depth max-depth]
+  (if (= false (get-in bolt-at [:phrasal]))
+    [(do-defaults (assoc-in bolt path bolt-at) model)]
+    (let [comp-paths (find-comp-paths bolt-at)
+          comp-bolts (map #(comp-path-to-bolts bolt-at % model (+ 1 depth) max-depth)
+                          comp-paths)]
+      (when (not (some empty? comp-bolts))
+        (mapfn #(do-defaults (assoc-in bolt path %) model)
+               (add-comps bolt-at
+                          model
+                          comp-paths
+                          comp-bolts
+                          (+ 1 depth)
+                          max-depth
+                          top-bolt))))))
 (defn generate2
   "Return all expressions matching spec _spec_ given the model _model_."
   [spec model]


more logging

more logging

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -102,7 +102,8 @@
         ;; this is the relative depth; that is, the depth from the top of the current lightning bolt.
         ;; total-depth, on the other hand, is the depth all the way to the top of the entire
         ;; expression, which might involve several parent lightning bolts.
-        parents (lazy-shuffle (candidate-parents grammar spec))]
+        ;;        parents (lazy-shuffle (candidate-parents grammar spec))]
+        parents (candidate-parents grammar spec)]
     (let [lexical ;; 1. generate list of all phrases where the head child of each parent is a lexeme.
           (when (= false (get-in spec [:head :phrasal] false))
             (lazy-mapcat
@@ -111,13 +112,16 @@
                      subset
                      (if-let [index-fn
                               (:index-fn language-model)]
-                       (do (log/debug (str "found index-fn."))
+                       (do (log/trace (str "found index-fn."))
+                           (log/debug (str "lightning-bolts: calling index-fn with rule: " (:rule parent)
+                                           " with spec: " (strip-refs (get-in parent [:head] :top))))
                            (index-fn (get-in parent [:head] :top)))
                        (do (log/warn (str "no indices found for spec: " spec))
                            []))]
-                 (log/info (str "lightning-bolts: " (get-in parent [:rule])
-                                 " : (optimizeme) size of subset of candidate heads: "
-                                 (count subset) " with spec: " (strip-refs spec)))
+                 (if (not (empty? subset))
+                   (log/debug (str "lightning-bolts: " (get-in parent [:rule])
+                                   " : (optimizeme) size of subset of candidate heads: "
+                                   (count subset) " with spec: " (strip-refs spec))))
                  (log/trace (str "lightning-bolts: " (get-in parent [:rule])
                                  " : head lexeme candidates: "
                                  (string/join ","
@@ -125,7 +129,8 @@
                                                    subset))))

                  (let [result (over/overh parent (lazy-shuffle subset))]
-                   (log/debug (str "lightning-bolts: (optimizeme) surviving candidate heads: " (count result)))
+                   (if (not (empty? result))
+                     (log/debug (str "lightning-bolts: (optimizeme) surviving candidate heads: " (count result))))

                    (log/trace (str "lightning-bolts: surviving results: "
                                    (string/join ","
@@ -147,21 +152,23 @@
           phrasal ;; 2. generate list of all phrases where the head child of each parent is itself a phrase.
           (if (and (< total-depth max-total-depth)
                    (= true (get-in spec [:head :phrasal] true)))
-            (lazy-mapcat (fn [parent]
-                           (over/overh
-                            parent
-                            (lightning-bolts language-model (get-in parent [:head])
-                                             (+ 1 depth) (+ 1 total-depth)
-                                             :max-total-depth max-total-depth)))
+            (do
+              (lazy-mapcat (fn [parent]
+                             (log/debug (str "calling lightning-bolts recursively: parent: " (:rule parent)))
+                             (over/overh
+                              parent
+                              (lightning-bolts language-model (get-in parent [:head])
+                                               (+ 1 depth) (+ 1 total-depth)
+                                               :max-total-depth max-total-depth)))
                          (filter #(= true
                                      (get-in % [:head :phrasal] true))
-                                 parents)))]
+                                 parents))))]
       (filter
        (fn [bolt]
          (any-possible-complement?
           bolt [:comp] language-model total-depth
           :max-total-depth max-total-depth))
-       (if (lexemes-before-phrases total-depth max-total-depth)
+       (if (or true (lexemes-before-phrases total-depth max-total-depth))
          (lazy-cat lexical phrasal)
          (lazy-cat phrasal lexical))))))

@@ -351,24 +358,24 @@
   "find subset of _rules_ for which each member unifies successfully with _spec_"
   [rules spec]
   (log/trace (str "candidate-parents: spec: " (strip-refs spec)))
-  (filter #(not (= :fail %))
-          (pmap (fn [rule]
-                  (log/trace (str "candidate-parents: rule: " (:rule rule)))
-                  (if (and (not-fail? (unify (get-in rule [:synsem :cat] :top)
-                                             (get-in spec [:synsem :cat] :top)))
-                           (not-fail? (unify (get-in rule [:synsem :infl] :top)
-                                             (get-in spec [:synsem :infl] :top)))
-                           (not-fail? (unify (get-in rule [:synsem :sem :tense] :top)
-                                             (get-in spec [:synsem :sem :tense] :top)))
-                           (not-fail? (unify (get-in rule [:synsem :modified] :top)
-                                             (get-in spec [:synsem :modified] :top))))
-                    (let [result
-                          (unify spec rule)]
-                      (if (fail? result)
-                        :fail
-                        result))
-                    :fail))
-                rules)))
+  (let [result
+        (filter not-fail?
+                (mapfn (fn [rule]
+                         (log/trace (str "candidate-parents: rule: " (:rule rule)))
+                         (if (and (not-fail? (unify (get-in rule [:synsem :cat] :top)
+                                                    (get-in spec [:synsem :cat] :top)))
+                                  (not-fail? (unify (get-in rule [:synsem :infl] :top)
+                                                    (get-in spec [:synsem :infl] :top)))
+                                  (not-fail? (unify (get-in rule [:synsem :sem :tense] :top)
+                                                    (get-in spec [:synsem :sem :tense] :top)))
+                                  (not-fail? (unify (get-in rule [:synsem :modified] :top)
+                                                   (get-in spec [:synsem :modified] :top))))
+                           (unify spec rule)
+                           :fail))
+                       rules))]
+    (log/debug (str "candidate-parents for spec: " (strip-refs spec) " : "
+                    (string/join "," (map :rule result))))
+    result))

 (defn lazy-shuffle [seq]
   (lazy-seq (shuffle seq)))


filter (add-comps) result with (not (nil?))

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -126,44 +126,50 @@
   "given a bolt, return the lazy sequence of all bolts derived from this bolt after adding,
    at each supplied path in comp-paths, the bolts for that path."
   [bolt model comp-paths bolts-at-paths depth max-depth & [top-bolt truncate? take-n]]
-  (lazy-seq
-   (let [top-bolt (or top-bolt bolt)
-         truncate? (if (= truncate? false)
-                     false
-                     true)]
-     (if (empty? comp-paths)
-       [bolt] ;; done: we've added all the comps to the bolt, so just return the bolt as a singleton vector.
-       ;; else, more comp-paths to go.
-       (flatten
-        (mapfn #(add-comps % model
-                           (rest comp-paths)
-                           (rest bolts-at-paths)
-                           depth max-depth top-bolt truncate? take-n)
-               (let [path (first comp-paths)
-                     bolts-at (first bolts-at-paths)]
-                 (flatten
-                  (mapfn #(let [bolt (assoc-in bolt path %)]
-                            (if (= false (get-in % [:phrasal]))
-                              [bolt]
-                              (-> (add-bolt-at top-bolt bolt path % model depth max-depth truncate? take-n)
-                                  ((fn [with-added-complement]
-                                     (if truncate? (truncate with-added-complement [path] model)
-                                         with-added-complement))))))
-                         bolts-at)))))))))
+  (when (not (= :fail bolt))
+    (log/debug (str "add-comps: " ((:morph-ps model) bolt) ": comp-paths:" (string/join "," comp-paths)))
+    (lazy-seq
+     (let [top-bolt (or top-bolt bolt)
+           truncate? (if (= truncate? false)
+                       false
+                       true)]
+       (if (empty? comp-paths)
+         (do
+           (log/debug (str "complete tree: " ((:morph-ps model) bolt)))
+           [bolt]) ;; done: we've added all the comps to the bolt, so just return the bolt as a singleton vector.
+         ;; else, more comp-paths to go.
+         (flatten
+          (mapfn #(add-comps % model
+                             (rest comp-paths)
+                             (rest bolts-at-paths)
+                             depth max-depth top-bolt truncate? take-n)
+                 (let [path (first comp-paths)
+                       bolts-at (first bolts-at-paths)]
+                   (flatten
+                    (mapfn #(let [bolt (assoc-in bolt path %)]
+                              (if (= false (get-in % [:phrasal]))
+                                [bolt]
+                                (-> (add-bolt-at top-bolt bolt path % model depth max-depth truncate? take-n)
+                                    ((fn [with-added-complement]
+                                       (if truncate? (truncate with-added-complement [path] model)
+                                           with-added-complement))))))
+                           bolts-at))))))))))

 (defn add-bolt-at [top-bolt bolt path bolt-at model depth max-depth truncate? & [take-n]]
   (lazy-seq
    (mapfn #(do-defaults % model)
-                  (let [comp-paths (find-comp-paths bolt-at)
-                        comp-bolts
-                        (pmap #(if take-n
-                                 (take take-n (comp-path-to-bolts bolt-at % model (+ 1 depth) max-depth))
-                                 (comp-path-to-bolts bolt-at % model (+ 1 depth) max-depth))
-                              comp-paths)]
-                    (when (not (some empty? comp-bolts))
-                      (lazy-seq
-                       (filter #(not (= :fail %))
-                               (mapfn #(assoc-in bolt path %)
+          (let [comp-paths (find-comp-paths bolt-at)
+                comp-bolts
+                (pmap #(comp-path-to-bolts bolt-at % model (+ 1 depth) max-depth)
+                      comp-paths)]
+            (log/debug (str "add-bolt-at:" ((:morph-ps model) bolt-at) "; comp-paths: " (string/join "," comp-paths)))
+            (when (not (some empty? comp-bolts))
+              (lazy-seq
+               (filter #(not (= :fail %))
+                       (mapfn #(let [assoc (if (empty? path) %
+                                               (assoc-in bolt path %))]
+                                 assoc)
+                              (filter (fn [with-comps] (not (nil? with-comps)))
                                       (add-comps bolt-at
                                                  model
                                                  comp-paths
@@ -172,7 +178,7 @@
                                                  max-depth
                                                  top-bolt
                                                  truncate?
-                                                 take-n)))))))))
+                                                 take-n))))))))))
 (defn generate
   "Return one (by default) or _n_ (using :take _n_) expressions matching spec _spec_ given the model _model_."
   [spec language-model
@@ -196,12 +202,10 @@
       take
       (reduce concat
               (pmap #(do
-                       (log/debug (str "add-bolt-at: " ((:morph-ps language-model) %)))
-                       (filter (fn [expr]
-                                 (cond
-                                   (not (= :fail expr)) true
-                                   true (do (log/debug (str "fail.")) false)))
-                               (add-bolt-at % % [] % language-model depth max-depth truncate-children 10)))
+                       (log/trace (str "add-bolt-at:" ((:morph-ps language-model) %)))
+                       (let [result (filter (fn [x] (not (= :fail x)))
+                                            (add-bolt-at % % [] % language-model depth max-depth truncate-children take))]
+                         result))
                     (lightning-bolts language-model spec 0 max-total-depth))))
      ((fn [seq]
         (if (= take 1)


fix dynamic var name in echo

fix dynamic var name in echo

--- src/bract/core/echo.clj
+++ src/bract/core/echo.clj
@@ -33,7 +33,7 @@
   [x & more]
   (->> (cons x more)
     (string/join \space)
-    (str (when *module-name* (format "[%s] " *module-name*)))
+    (str (when *inducer-name* (format "[%s] " *inducer-name*)))
     Echo/echo))


Introduce `pmap-runner` as a temporary measure

Can help avoid possibly experiencing https://github.com/benedekfazekas/mranderson/issues/56.

--- src/mranderson/move.clj
+++ src/mranderson/move.clj
@@ -282,15 +282,21 @@
           (recur (.getParentFile dir)))))
     (throw (FileNotFoundException. (format "file for %s not found in %s" old-sym source-path)))))

+(def ^:private pmap-runner
+  "Removing parallelism might alleviate https://github.com/benedekfazekas/mranderson/issues/56"
+  (if (System/getProperty "mranderson.internal.no-parallelism")
+    map
+    pmap))
+
 (defn replace-ns-symbol-in-source-files
   "Replaces all occurrences of the old name with the new name in
   all Clojure source files found in dirs."
   [old-sym new-sym extension dirs watermark]
   (->> (clojure-source-files dirs extension)
-       (pmap (fn [file]
-               (->> (str file)
-                    util/file->extension
-                    (update-file file replace-ns-symbol old-sym new-sym watermark extension))))
+       (pmap-runner (fn [file]
+                      (->> (str file)
+                           util/file->extension
+                           (update-file file replace-ns-symbol old-sym new-sym watermark extension))))
        (doall)))

 (defn move-ns


calfpath.route/make-dispatcher is for CLJ/JVM only

--- src/calfpath/route.cljc
+++ src/calfpath/route.cljc
@@ -68,8 +68,8 @@
   *routes* :foo)

-(defn make-dispatcher
-  "Given a collection of routes return a Ring handler function that matches specified request and invokes
+#?(:clj (defn make-dispatcher
+          "Given a collection of routes return a Ring handler function that matches specified request and invokes
   corresponding route handler on successful match, returns nil otherwise.
   Synopsis:
   0. A route is a map {:matcher `(fn [request]) -> request?`     ; :matcher is a required key
@@ -81,58 +81,58 @@
      only when :matcher is also present. Expr should return a value similar to matcher.
   3. A matchex is for optimization only, which may be disabled by setting a false or nil value for the :matchex key.
   4. Handler is a Ring handler (fn [request] [request respond raise]) that responds to a Ring request."
-  [routes]
-  (let [routes (->> routes
-                 (map (fn [spec]
-                        (when-not (:matcher spec)
-                          (i/expected ":matcher key to be present" spec))
-                        (cond
-                          (contains? spec :handler) spec
-                          (contains? spec :nested)  (assoc spec
-                                                      :handler (make-dispatcher (:nested spec)))
-                          :otherwise                (i/expected ":nested or :handler key to be present in route"
-                                                      spec))))
-                 vec)
-        routes-sym   (gensym "routes-")
-        dispatch-sym (gensym "dispatch-")
-        request-sym  (gensym "request-")
-        invoke-sym   (gensym "invoke-handler-")
-        n            (count routes)
-        matcher-syms (mapv (fn [idx] (gensym (str "matcher-" idx "-"))) (range n))
-        handler-syms (mapv (fn [idx] (gensym (str "handler-" idx "-"))) (range n))
-        bindings (->> (range n)
-                   (mapcat (fn [idx]
-                             `[~(get matcher-syms idx) (:matcher (get ~routes-sym ~idx))
-                               ~(get handler-syms idx) (:handler (get ~routes-sym ~idx))]))
-                   ;; eval-forms can only access information via root-level vars
-                   ;; so we use the dynamic var *routes* here
-                   (into `[~routes-sym ~'calfpath.route/*routes*]))
-        all-exps (->> (range n)
-                   reverse
-                   (reduce (fn
-                             ([expr]
-                               expr)
-                             ([expr idx]
-                               (let [matcher-sym (get matcher-syms idx)
-                                     matcher-exp (if-let [matchex (:matchex (get routes idx))]
-                                                   (matchex request-sym)
-                                                   `(~matcher-sym ~request-sym))
-                                     handler-sym (get handler-syms idx)]
-                                 `(if-let [request# ~matcher-exp]
-                                    (~invoke-sym ~handler-sym request#)
-                                    ~expr))))
-                     `nil))
-        fn-form  `(let [~@bindings]
-                    (fn ~dispatch-sym
-                      ([~request-sym ~invoke-sym]
-                        ~all-exps)
-                      ([~request-sym]
-                        (~dispatch-sym ~request-sym i/invoke))
-                      ([~request-sym respond# raise#]
-                        (~dispatch-sym ~request-sym (fn [handler# updated-request#]
-                                                      (handler# updated-request# respond# raise#))))))]
-    (binding [*routes* routes]
-      (eval fn-form))))
+          [routes]
+          (let [routes (->> routes
+                         (map (fn [spec]
+                                (when-not (:matcher spec)
+                                  (i/expected ":matcher key to be present" spec))
+                                (cond
+                                  (contains? spec :handler) spec
+                                  (contains? spec :nested)  (assoc spec
+                                                              :handler (make-dispatcher (:nested spec)))
+                                  :otherwise                (i/expected ":nested or :handler key to be present in route"
+                                                              spec))))
+                         vec)
+                routes-sym   (gensym "routes-")
+                dispatch-sym (gensym "dispatch-")
+                request-sym  (gensym "request-")
+                invoke-sym   (gensym "invoke-handler-")
+                n            (count routes)
+                matcher-syms (mapv (fn [idx] (gensym (str "matcher-" idx "-"))) (range n))
+                handler-syms (mapv (fn [idx] (gensym (str "handler-" idx "-"))) (range n))
+                bindings (->> (range n)
+                           (mapcat (fn [idx]
+                                     `[~(get matcher-syms idx) (:matcher (get ~routes-sym ~idx))
+                                       ~(get handler-syms idx) (:handler (get ~routes-sym ~idx))]))
+                           ;; eval-forms can only access information via root-level vars
+                           ;; so we use the dynamic var *routes* here
+                           (into `[~routes-sym ~'calfpath.route/*routes*]))
+                all-exps (->> (range n)
+                           reverse
+                           (reduce (fn
+                                     ([expr]
+                                       expr)
+                                     ([expr idx]
+                                       (let [matcher-sym (get matcher-syms idx)
+                                             matcher-exp (if-let [matchex (:matchex (get routes idx))]
+                                                           (matchex request-sym)
+                                                           `(~matcher-sym ~request-sym))
+                                             handler-sym (get handler-syms idx)]
+                                         `(if-let [request# ~matcher-exp]
+                                            (~invoke-sym ~handler-sym request#)
+                                            ~expr))))
+                             `nil))
+                fn-form  `(let [~@bindings]
+                            (fn ~dispatch-sym
+                              ([~request-sym ~invoke-sym]
+                                ~all-exps)
+                              ([~request-sym]
+                                (~dispatch-sym ~request-sym i/invoke))
+                              ([~request-sym respond# raise#]
+                                (~dispatch-sym ~request-sym (fn [handler# updated-request#]
+                                                              (handler# updated-request# respond# raise#))))))]
+            (binding [*routes* routes]
+              (eval fn-form)))))

 ;; ----- fallback route match -----


Add predicate functions to Encoder and Decoder protocols.

--- src/multicodec/core.clj
+++ src/multicodec/core.clj
@@ -49,7 +49,9 @@
   "An encoder converts values to binary sequences and writes the results to an
   output stream."

-  ; TODO: (encodable? codec value)
+  (encodable?
+    [codec value]
+    "Returns true if the value type can be encoded by this codec.")

   (encode!
     [codec ^java.io.OutputStream output value]
@@ -73,7 +75,9 @@
 (defprotocol Decoder
   "A decoder reads binary sequences and interpretes them as Clojure values."

-  ; TODO: (decodable? codec header)
+  (decodable?
+    [codec header]
+    "Returns true if the codec supports decoding of the given header.")

   (decode!
     [codec ^java.io.InputStream input]


added quotes for the customer testimonials

--- src-cljs/frontend/components/signup.cljs
+++ src-cljs/frontend/components/signup.cljs
@@ -66,13 +66,13 @@
                  [:div.customer-photo.rohan-singh]
                  [:div.logo.spotify]]
                 [:div.customer [:p "Rohan Singh, Senior Infrastructure Engineer at Spotify"]]
-                [:div.testimonial [:p "We love CircleCI's integration with GitHub and their ease of use. They've created a great user experience that makes it easy to see what's going on with builds and what the status is."]]]
+                [:div.testimonial [:p "\"We love CircleCI's integration with GitHub and their ease of use. They've created a great user experience that makes it easy to see what's going on with builds and what the status is.\""]]]
               [:div.row.testimonial-card
                 [:div.photo-logo-row
                  [:div.customer-photo.matt-kemp]
                  [:div.logo.sprig]]
                 [:div.customer [:p "Matt Kemp, Co-founder & Head of Engineering at Sprig"]]
-                [:div.testimonial [:p "CircleCI is an excellent product and was the clear winner over the alternatives when I tried them all out. With CircleCI, I was able to get a green build the fastest and hit the fewest bumps."]]]]
+                [:div.testimonial [:p "\"CircleCI is an excellent product and was the clear winner over the alternatives when I tried them all out. With CircleCI, I was able to get a green build the fastest and hit the fewest bumps.\""]]]]
              [:div.col-md-1]]
             [:div.row.footer
              [:div.github-example.col-md-12


Fixed memory issues with new loader

Fixed memory issues with new loader

--- src/cfpb/qu/loader2.clj
+++ src/cfpb/qu/loader2.clj
@@ -128,10 +128,11 @@
         dir (:dir definition)
         sources (:sources tdef)
         columns (:columns tdef)
-        raw-data (->> sources
+        file-data (->> sources
                       (map #(read-csv-file (str dir "/" %)))
-                      (apply concat []))]
-    (map #(cast-data % columns) raw-data)))
+                      (map (fn [d]
+                             (map #(cast-data % columns) d))))]
+    (apply concat [] file-data)))

 (defn read-concept-data
   [concept definition]
@@ -147,17 +148,57 @@
               (assoc acc concept (read-concept-data concept definition)))
             {} (keys concepts))))

-(defmulti read-slice
-  (fn [slice definition]
+(defn- join-maps
+  "Join two vectors of maps on a key."
+  [left lkey lval right rkey rval]
+  (let [lkey (keyword lkey)
+        lval (keyword lval)
+        rkey (keyword rkey)
+        rval (keyword rval)
+        rmap (apply hash-map (flatten (map (juxt rkey rval) right)))]
+    (->> left
+         (map (fn [row]
+                (assoc row lval (get rmap (get row lkey))))))))
+
+(defn load-csv-file
+  [file collection transform-fn]
+  (with-open [in-file (io/reader (io/resource file))]
+    (let [data (csv/read-csv in-file)
+          headers (map keyword (first data))
+          data (map (partial zipmap headers) (rest data))
+          data (transform-fn data)
+          chunks (partition-all *chunk-size* data)]
+      (doseq [chunk chunks]
+        (coll/insert-batch collection chunk)))))
+
+(defn load-table
+  [table collection concepts references definition]
+  (let [tdef (get-in definition [:tables (keyword table)])
+        dir (:dir definition)
+        sources (:sources tdef)
+        columns (:columns tdef)
+        cast-data (partial map #(cast-data % columns))
+        add-concepts (fn [data]
+                       (reduce (fn [data [column cdef]]
+                                 (join-maps
+                                  data (:column cdef) column
+                                  (get concepts (keyword (:concept cdef))) :_id (:value cdef)))
+                               data references))]
+    (doseq [file sources]
+      (load-csv-file (str dir "/" file) collection (comp add-concepts cast-data)))))
+
+(defmulti load-slice
+  (fn [slice _ definition]
     (get-in definition [:slices (keyword slice) :type])))

-(defmethod read-slice "table"
-  [slice definition]
-  (let [table (get-in definition [:slices (keyword slice) :table])]
-    (read-table table definition)))
-
-(defmethod read-slice "derived"
-  [slice definition]
+(defmethod load-slice "table"
+  [slice concepts definition]
+  (let [table (get-in definition [:slices (keyword slice) :table])
+        references (get-in definition [:slices (keyword slice) :references])]
+    (load-table table slice concepts references definition)))
+
+(defmethod load-slice "derived"
+  [slice concepts definition]
   (let [database (:database definition)
         sdef (get-in definition [:slices (keyword slice)])
         from-collection (:slice sdef)
@@ -179,38 +220,16 @@
         project (apply merge (concat project-dims project-aggs))
         aggregation [{"$group" group} {"$project" project} {"$match" match}]
         query-result (get-aggregation database from-collection aggregation)
-        data (:data query-result)]
-    (:data query-result)))
-
-(defmethod read-slice :default
-  [slice definition]
-  (let [type (get-in definition [:slices (keyword slice) :type])]
-    (log/error "Cannot load slice" slice "with type" type)))
-
-(defn- join-maps
-  "Join two vectors of maps on a key."
-  [left lkey lval right rkey rval]
-  (let [lkey (keyword lkey)
-        lval (keyword lval)
-        rkey (keyword rkey)
-        rval (keyword rval)
-        rmap (apply hash-map (flatten (map (juxt rkey rval) right)))]
-    (->> left
-         (map (fn [row]
-                (assoc row lval (get rmap (get row lkey))))))))
-
-(defn load-slice
-  [slice concepts definition]
-  (let [data (read-slice slice definition)
-        references (get-in definition [:slices (keyword slice) :references])
-        data (reduce (fn [data [column cdef]]
-                       (join-maps data (:column cdef) column
-                                  (get concepts (keyword (:concept cdef))) :_id (:value cdef)))
-                     data references)
+        data (:data query-result)
         chunks (partition-all *chunk-size* data)]
     (doseq [chunk chunks]
       (coll/insert-batch slice chunk))))
-
+
+(defmethod load-slice :default
+  [slice concepts definition]
+  (let [type (get-in definition [:slices (keyword slice) :type])]
+    (log/error "Cannot load slice" slice "with type" type)))
+
 (defn load-slices
   [definition]
   (log/info "Loading concepts")


fix macro

fix macro

--- src/clj/flambo/kryo.clj
+++ src/clj/flambo/kryo.clj
@@ -15,7 +15,7 @@
     (.deserialize ser buf)))

 (defmacro defregistrator
-  [name register-impl]
+  [name & register-impl]
   (let [prefix (gensym)
         classname (str *ns* ".registrator." name)]
     `(do


Fix for current-ice when there is no run active.

--- src/clj/game/macros.clj
+++ src/clj/game/macros.clj
@@ -11,7 +11,7 @@
                 'corp-reg '(get-in @state [:corp :register])
                 'runner-reg '(get-in @state [:runner :register])
                 'current-ice '(when-let [run (:run @state)]
-                                (when (> (:position run) 0) ((:ices run) (dec (:position run)))))
+                                (when (> (or (:position run) 0) 0) ((:ices run) (dec (:position run)))))
                 'target '(first targets)]
            ~@actions))))

@@ -20,7 +20,7 @@
      (let ~['runner '(:runner @state)
             'corp '(:corp @state)
             'run '(:run @state)
-            'current-ice '(when (and run (> (:position run) 0)) ((:ices run) (dec (:position run))))
+            'current-ice '(when (and run (> (or (:position run) 0) 0)) ((:ices run) (dec (:position run))))
             'corp-reg '(get-in @state [:corp :register])
             'runner-reg '(get-in @state [:runner :register])
             'target '(first targets)


hard limits on what could be selected

hard limits on what could be selected

--- src/clj/hsm/actions.clj
+++ src/clj/hsm/actions.clj
@@ -355,6 +355,7 @@
   [db proj-list]
   (let [conn (:connection db)]
     (cql/select conn :github_project
+      (dbq/limit 100)
       (dbq/where [[:in :full_name proj-list]]))))

 (defn load-projects-by-int-id
@@ -362,6 +363,7 @@
   (let [conn (:connection db)]
     ;; FIX THIS SHIT!@!@!@!
      (mapcat #(cql/select conn :github_project
+            (dbq/limit 1000)
             (dbq/where [[:= :id %]]))
       proj-list)))

@@ -424,6 +426,7 @@
   (log/warn "Fetching user-ids" user-ids)
   (let [conn (:connection db)]
     (cql/select conn :github_user
+        (dbq/limit 100)
         (dbq/where [[:in :login user-ids]]))))

 (defn fetch-top-users


add number hints

add number hints

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -218,7 +218,7 @@
     [this a b c d e f g h i j k l m n o p q s t rest]))

 (defprotocol ICounted
-  (-count [coll] "constant time count"))
+  (^number -count [coll] "constant time count"))

 (defprotocol IEmptyableCollection
   (-empty [coll]))
@@ -854,13 +854,13 @@
   [coll]
   (-empty coll))

-(defn- accumulating-seq-count [coll]
+(defn- ^number accumulating-seq-count [coll]
   (loop [s (seq coll) acc 0]
     (if (counted? s) ; assumes nil is counted, which it currently is
       (+ acc (-count s))
       (recur (next s) (inc acc)))))

-(defn count
+(defn ^number count
   "Returns the number of items in the collection. (count nil) returns
   0.  Also works on strings, arrays, and Maps"
   [coll]
@@ -1269,7 +1269,7 @@

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Seq fns ;;;;;;;;;;;;;;;;

-(defn compare
+(defn ^number compare
   "Comparator. Returns a negative number, zero, or a positive number
   when x is logically 'less than', 'equal to', or 'greater than'
   y. Uses IComparable if available and google.array.defaultCompare for objects
@@ -1425,7 +1425,7 @@
 ;;; Math - variadic forms will not work until the following implemented:
 ;;; first, next, reduce

-(defn +
+(defn ^number +
   "Returns the sum of nums. (+) returns 0."
   ([] 0)
   ([x] x)
@@ -1433,14 +1433,14 @@
   ([x y & more]
     (reduce + (cljs.core/+ x y) more)))

-(defn -
+(defn ^number -
   "If no ys are supplied, returns the negation of x, else subtracts
   the ys from x and returns the result."
   ([x] (cljs.core/- x))
   ([x y] (cljs.core/- x y))
   ([x y & more] (reduce - (cljs.core/- x y) more)))

-(defn *
+(defn ^number *
   "Returns the product of nums. (*) returns 1."
   ([] 1)
   ([x] x)
@@ -1449,7 +1449,7 @@

 (declare divide)

-(defn /
+(defn ^number /
   "If no denominators are supplied, returns 1/numerator,
   else returns numerator divided by all of the denominators."
   ([x] (/ 1 x))
@@ -1504,25 +1504,25 @@
        (cljs.core/>= y (first more)))
      false)))

-(defn dec
+(defn ^number dec
   "Returns a number one less than num."
   [x] (- x 1))

-(defn max
+(defn ^number max
   "Returns the greatest of the nums."
   ([x] x)
   ([x y] (cljs.core/max x y))
   ([x y & more]
    (reduce max (cljs.core/max x y) more)))

-(defn min
+(defn ^number min
   "Returns the least of the nums."
   ([x] x)
   ([x y] (cljs.core/min x y))
   ([x y & more]
    (reduce min (cljs.core/min x y) more)))

-(defn byte [x] x)
+(defn ^number byte [x] x)

 (defn char
   "Coerce to char"
@@ -1532,109 +1532,109 @@
     (and (string? x) (== (.-length x) 1)) x
     :else (throw (js/Error. "Argument to char must be a character or number"))))

-(defn short [x] x)
-(defn float [x] x)
-(defn double [x] x)
-
-(defn unchecked-byte [x] x)
-(defn unchecked-char [x] x)
-(defn unchecked-short [x] x)
-(defn unchecked-float [x] x)
-(defn unchecked-double [x] x)
-
-(defn unchecked-add
+(defn ^number short [x] x)
+(defn ^number float [x] x)
+(defn ^number double [x] x)
+
+(defn ^number unchecked-byte [x] x)
+(defn ^number unchecked-char [x] x)
+(defn ^number unchecked-short [x] x)
+(defn ^number unchecked-float [x] x)
+(defn ^number unchecked-double [x] x)
+
+(defn ^number unchecked-add
   "Returns the sum of nums. (+) returns 0."
   ([] 0)
   ([x] x)
   ([x y] (cljs.core/unchecked-add x y))
   ([x y & more] (reduce unchecked-add (cljs.core/unchecked-add x y) more)))

-(defn unchecked-add-int
+(defn ^number unchecked-add-int
   "Returns the sum of nums. (+) returns 0."
   ([] 0)
   ([x] x)
   ([x y] (cljs.core/unchecked-add-int x y))
   ([x y & more] (reduce unchecked-add-int (cljs.core/unchecked-add-int x y) more)))

-(defn unchecked-dec [x]
+(defn ^number unchecked-dec [x]
   (cljs.core/unchecked-dec x))

-(defn unchecked-dec-int [x]
+(defn ^number unchecked-dec-int [x]
   (cljs.core/unchecked-dec-int x))

-(defn unchecked-divide-int
+(defn ^number unchecked-divide-int
   "If no denominators are supplied, returns 1/numerator,
   else returns numerator divided by all of the denominators."
   ([x] (unchecked-divide-int 1 x))
   ([x y] (cljs.core/divide x y)) ;; FIXME: waiting on cljs.core//
   ([x y & more] (reduce unchecked-divide-int (unchecked-divide-int x y) more)))

-(defn unchecked-inc [x]
+(defn ^number unchecked-inc [x]
   (cljs.core/unchecked-inc x))

-(defn unchecked-inc-int [x]
+(defn ^number unchecked-inc-int [x]
   (cljs.core/unchecked-inc-int x))

-(defn unchecked-multiply
+(defn ^number unchecked-multiply
   "Returns the product of nums. (*) returns 1."
   ([] 1)
   ([x] x)
   ([x y] (cljs.core/unchecked-multiply x y))
   ([x y & more] (reduce unchecked-multiply (cljs.core/unchecked-multiply x y) more)))

-(defn unchecked-multiply-int
+(defn ^number unchecked-multiply-int
   "Returns the product of nums. (*) returns 1."
   ([] 1)
   ([x] x)
   ([x y] (cljs.core/unchecked-multiply-int x y))
   ([x y & more] (reduce unchecked-multiply-int (cljs.core/unchecked-multiply-int x y) more)))

-(defn unchecked-negate [x]
+(defn ^number unchecked-negate [x]
   (cljs.core/unchecked-negate x))

-(defn unchecked-negate-int [x]
+(defn ^number unchecked-negate-int [x]
   (cljs.core/unchecked-negate-int x))

 (declare mod)

-(defn unchecked-remainder-int [x n]
+(defn ^number unchecked-remainder-int [x n]
   (cljs.core/unchecked-remainder-int x n))

-(defn unchecked-substract
+(defn ^number unchecked-substract
   "If no ys are supplied, returns the negation of x, else subtracts
   the ys from x and returns the result."
   ([x] (cljs.core/unchecked-subtract x))
   ([x y] (cljs.core/unchecked-subtract x y))
   ([x y & more] (reduce unchecked-substract (cljs.core/unchecked-subtract x y) more)))

-(defn unchecked-substract-int
+(defn ^number unchecked-substract-int
   "If no ys are supplied, returns the negation of x, else subtracts
   the ys from x and returns the result."
   ([x] (cljs.core/unchecked-subtract-int x))
   ([x y] (cljs.core/unchecked-subtract-int x y))
   ([x y & more] (reduce unchecked-substract-int (cljs.core/unchecked-subtract-int x y) more)))

-(defn- fix [q]
+(defn- ^number fix [q]
   (if (>= q 0)
     (Math/floor q)
     (Math/ceil q)))

-(defn int
+(defn ^number int
   "Coerce to int by stripping decimal places."
   [x]
   (bit-or x 0))

-(defn unchecked-int
+(defn ^number unchecked-int
   "Coerce to int by stripping decimal places."
   [x]
   (fix x))

-(defn long
+(defn ^number long
   "Coerce to long by stripping decimal places. Identical to `int'."
   [x]
   (fix x))

-(defn unchecked-long
+(defn ^number unchecked-long
   "Coerce to long by stripping decimal places. Identical to `int'."
   [x]
   (fix x))
@@ -1648,90 +1648,90 @@
 (defn doubles [x] x)
 (defn longs [x] x)

-(defn js-mod
+(defn ^number js-mod
   "Modulus of num and div with original javascript behavior. i.e. bug for negative numbers"
   [n d]
   (cljs.core/js-mod n d))

-(defn mod
+(defn ^number mod
   "Modulus of num and div. Truncates toward negative infinity."
   [n d]
   (js-mod (+ (js-mod n d) d) d))

-(defn quot
+(defn ^number quot
   "quot[ient] of dividing numerator by denominator."
   [n d]
   (let [rem (js-mod n d)]
     (fix (/ (- n rem) d))))

-(defn rem
+(defn ^number rem
   "remainder of dividing numerator by denominator."
   [n d]
   (let [q (quot n d)]
     (- n (* d q))))

-(defn rand
+(defn ^number rand
   "Returns a random floating point number between 0 (inclusive) and n (default 1) (exclusive)."
   ([]  (Math/random))
   ([n] (* n (rand))))

-(defn rand-int
+(defn ^number rand-int
   "Returns a random integer between 0 (inclusive) and n (exclusive)."
   [n] (fix (rand n)))

-(defn bit-xor
+(defn ^number bit-xor
   "Bitwise exclusive or"
   [x y] (cljs.core/bit-xor x y))

-(defn bit-and
+(defn ^number bit-and
   "Bitwise and"
   [x y] (cljs.core/bit-and x y))

-(defn bit-or
+(defn ^number bit-or
   "Bitwise or"
   [x y] (cljs.core/bit-or x y))

-(defn bit-and-not
+(defn ^number bit-and-not
   "Bitwise and"
   [x y] (cljs.core/bit-and-not x y))

-(defn bit-clear
+(defn ^number bit-clear
   "Clear bit at index n"
   [x n]
   (cljs.core/bit-clear x n))

-(defn bit-flip
+(defn ^number bit-flip
   "Flip bit at index n"
   [x n]
   (cljs.core/bit-flip x n))

-(defn bit-not
+(defn ^number bit-not
   "Bitwise complement"
   [x] (cljs.core/bit-not x))

-(defn bit-set
+(defn ^number bit-set
   "Set bit at index n"
   [x n]
   (cljs.core/bit-set x n))

-(defn bit-test
+(defn ^number bit-test
   "Test bit at index n"
   [x n]
   (cljs.core/bit-test x n))

-(defn bit-shift-left
+(defn ^number bit-shift-left
   "Bitwise shift left"
   [x n] (cljs.core/bit-shift-left x n))

-(defn bit-shift-right
+(defn ^number bit-shift-right
   "Bitwise shift right"
   [x n] (cljs.core/bit-shift-right x n))

-(defn bit-shift-right-zero-fill
+(defn ^number bit-shift-right-zero-fill
   "Bitwise shift right with zero fill"
   [x n] (cljs.core/bit-shift-right-zero-fill x n))

-(defn bit-count
+(defn ^number bit-count
   "Counts the number of bits set in n"
   [v]
   (let [v (- v (bit-and (bit-shift-right v 1) 0x55555555))


* src/cljs/cljs/core.cljs: CLJS-64: Cannot use true/false as map key

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -247,6 +247,10 @@

   IHash
   (-hash [o] o))
+
+(extend-type boolean
+  IHash
+  (-hash [o] (js* "((~{o} === true) ? 1 : 0)")))

 (extend-type function
   IHash


add PersistentArrayMapIterator

add PersistentArrayMapIterator

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -5069,6 +5069,15 @@

 (declare keys vals)

+(deftype PersistentArrayMapIterator [arr ^:mutable i cnt]
+  Object
+  (hasNext [_]
+    (< i cnt))
+  (next [_]
+    (let [ret [(aget arr i) (aget arr (inc i))]]
+      (set! i (+ i 2))
+      ret)))
+
 (deftype PersistentArrayMap [meta cnt arr ^:mutable __hash]
   Object
   (toString [coll]
@@ -5137,6 +5146,10 @@
   IHash
   (-hash [coll] (caching-hash coll hash-unordered-coll __hash))

+  IIterable
+  (-iterator [this]
+    (PersistentArrayMapIterator. arr 0 (* cnt 2)))
+
   ISeqable
   (-seq [coll]
     (persistent-array-map-seq arr 0 nil))


Fixed cell generation

Fixed cell generation

--- src/cljs_life/core.cljs
+++ src/cljs_life/core.cljs
@@ -2,17 +2,11 @@
   (:require [quil.core :as q :include-macros true]
             [quil.middleware :as m]))

+(enable-console-print!)
+
 (def world-size 500)
 (def size 5)
 (def max-cells (inc (/ world-size size)))
-
-(defn setup []
-  (q/frame-rate 1)
-  (q/background 240)
-  (q/stroke 100)
-  (q/fill 100)
-  ; Initial state
-  (set (repeatedly 1200 #(vector (rand-int max-cells) (rand-int max-cells)))))

 (defn neighbours
   "Returns the coordinates of the cell's 8 neighbours"
@@ -24,15 +18,29 @@
 (defn will-live?
   "Checks if a cell will be alive in the next iteration"
   [world [cell count]]
-  (or (= 3 count) (and (= 2 count) (contains? world cell))))
+  (or (= 3 count) (and (= 2 count) (some #{cell} world))))
+
+(defn next-cells [world]
+  (->> (mapcat neighbours world)
+       frequencies
+       (filter #(will-live? world %))
+       distinct
+       (map first)))
+
+(defn setup []
+  (q/frame-rate 1)
+  (q/background 240)
+  (q/stroke 240)
+  (q/fill 180)
+  ; Initial state
+  (->> (repeatedly 1200 #(vector (rand-int max-cells) (rand-int max-cells)))
+       distinct
+       next-cells))

 (defn update-world
   "Updates the set of living cells"
   [world]
-  (->> (mapcat neighbours world)
-       frequencies
-       (filter #(will-live? world %))
-       set))
+  (next-cells world))

 (defn draw-world
   "Resets the background and draws the next set of cells"


Add exit() function for ClojureScript version.

--- src/cljx/quil/core.cljx
+++ src/cljx/quil/core.cljx
@@ -1542,7 +1542,6 @@
                 #+clj PApplet/CLOSE
                 #+cljs 2)))

-#+clj
 (defn
   ^{:requires-bindings true
     :processing-name "exit()"
@@ -1555,7 +1554,8 @@
   completed (or after setup completes if called during the setup
   method). "
   []
-  (applet-close (current-applet)))
+  #+clj (applet-close (current-applet))
+  #+cljs (.exit (current-applet)))

 #+clj
 (defn


Using iterate in generate-game

Using iterate in generate-game

Previously I was using reduce passing by a dummy collection of the right lenght

--- src/civs/logic/core.clj
+++ src/civs/logic/core.clj
@@ -9,9 +9,9 @@

 ; Asked question about this function:
 ; http://stackoverflow.com/questions/25632388/clojure-executing-an-operation-n-times-using-the-output-as-input-of-next-operat
-(defn generate-game [world n-tribes]
-  (let [ game (create-game world)
-         game (reduce (fn [acc, _] (:game (generate-tribe acc))) game (repeat n-tribes :just_something))]
+(defn generate-game [world n-groups]
+  (let [ game0 (create-game world)
+         game (nth (iterate #(:game (generate-tribe %)) game0) n-groups :just_something)]
     game))

 (defn- clean-game


Provide a friendly from in addition to the from email address when sending emails.

--- src/oc/email/mailer.clj
+++ src/oc/email/mailer.clj
@@ -2,6 +2,7 @@
   (require [clojure.string :as s]
            [clojure.java.shell :as shell]
            [clojure.java.io :as io]
+           [clojure.walk :refer (keywordize-keys)]
            [oc.email.config :as c]
            [taoensso.timbre :as timbre]
            [amazonica.aws.simpleemail :as ses]
@@ -14,27 +15,30 @@

 (def default-reply-to (str "hello@" c/email-from-domain))

-(defn- send-email [to reply-to subject company-slug body]
+(defn- send-email [{to :to reply-to :reply-to subject :subject snap :snapshot} body]
   "Send emails to all to recipients in parallel."
-  (doall (pmap
-    #(do
-      (timbre/info "Sending email: " %)
-      (ses/send-email creds
-        :destination {:to-addresses [%]}
-        :source (str company-slug "@" c/email-from-domain)
-        :reply-to-addresses [(if (s/blank? reply-to) default-reply-to reply-to)]
-        :message {:subject subject
-                  :body {:html body}}))
-      (s/split to #","))))
+  (let [snapshot (keywordize-keys snap)
+        company-slug (:company-slug snapshot)
+        company-name (:name snapshot)]
+    (doall (pmap
+      #(do
+        (timbre/info "Sending email: " %)
+        (ses/send-email creds
+          :destination {:to-addresses [%]}
+          :source (str company-name " Update <" company-slug "@" c/email-from-domain ">")
+          :reply-to-addresses [(if (s/blank? reply-to) default-reply-to reply-to)]
+          :message {:subject subject
+                    :body {:html body}}))
+        (s/split to #",")))))

-(defn send-snapshot [{to :to reply-to :reply-to subject :subject note :note snapshot :snapshot}]
+(defn send-snapshot [{note :note snapshot :snapshot :as msg}]
   (let [uuid-fragment (subs (str (java.util.UUID/randomUUID)) 0 4)
         html-file (str uuid-fragment ".html")
         inline-file (str uuid-fragment ".inline.html")]
     (try
       (spit html-file (content/html (assoc snapshot :note note))) ; create the email in a tmp file
       (shell/sh "juice" html-file inline-file) ; inline the CSS
-      (send-email to reply-to subject (:company-slug snapshot) (slurp inline-file)) ; email it to the recipients
+      (send-email msg (slurp inline-file)) ; email it to the recipients
       (finally
         ; remove the tmp files
         (io/delete-file html-file true)
@@ -46,17 +50,17 @@

   (require '[oc.email.mailer :as mailer] :reload)

-  (def snapshot (json/decode (slurp "./resources/snapshots/buffer.json")))
+  (def snapshot (json/decode (slurp "./opt/samples/buffer.json")))
   (mailer/send-snapshot {:to "change@me.com"
                          :reply-to "change@me.com"
-                         :subject "[Buffer] Latest Update"
+                         :subject "Buffer Latest Update"
                          :note "Enjoy this groovy update!"
                          :snapshot (assoc snapshot :company-slug "buffer")})

-  (def snapshot (json/decode (slurp "./resources/snapshots/open.json")))
+  (def snapshot (json/decode (slurp "./opt/samples/open.json")))
   (mailer/send-snapshot {:to "change@me.com,change+1@me.com,change+2@me.com"
                          :reply-to "change@me.com"
-                         :subject "[OpenCompany] Check it"
+                         :subject "Check it"
                          :note "Hot diggity!"
                          :snapshot (assoc snapshot :company-slug "open")})


[ref] create-fee use IDs.

[ref] create-fee use IDs.

--- src/ombs/db/payment.clj
+++ src/ombs/db/payment.clj
@@ -53,7 +53,7 @@
                                 :events_id eid
                                 :debit money })))

-(defn add-participant
+(defn add-participant
   ([event date user]
   (sql/insert participation (sql/values {:events_id (get-eid event date)
                                          :users_id (get-uid user)})))
@@ -70,8 +70,13 @@
     (parts-price eid parts)
     (get-debt uid eid)) )

-(defn create-fee [uid eid & [parts]]
-  (sql/insert fees (sql/values {:users_id uid
-                                :events_id eid
-                                :parts parts
-                                :money (calc-fee-money uid eid parts) })))
+(defn create-fee
+  ([uid eid] (create-fee uid eid 0))
+  ([uid eid parts]
+   (sql/insert fees (sql/values {:users_id uid
+                                 :events_id eid
+                                 :parts parts
+                                 :money (calc-fee-money uid eid parts) }))))
+
+(defn can-pay? [uid eid]
+  false)


fix bug - freeing control bus previously freed an audio bus of the same id

--- src/overtone/sc/bus.clj
+++ src/overtone/sc/bus.clj
@@ -43,7 +43,7 @@
   [b]
   (case (type b)
     :audio-bus   (free-id :audio-bus (:id b))
-    :control-bus (free-id :audio-bus (:id b))))
+    :control-bus (free-id :control-bus (:id b))))

 ; Reserve the first 11 busses for audio I/O and mixer, forever.
 (dotimes [i 11]


make backend detect danny and daniel too

--- src/pc/http/datomic.clj
+++ src/pc/http/datomic.clj
@@ -25,7 +25,7 @@

 (defn handle-precursor-pings [document-id datoms]
   (if-let [ping-datoms (seq (filter #(and (= :chat/body (:a %))
-                                            (re-find #"@prcrsr" (:v %)))
+                                            (re-find #"(?i)@prcrsr|@danny|@daniel" (:v %)))
                                       datoms))]
     (doseq [datom ping-datoms
             :let [message (format "<https://prcrsr.com/document/%s|%s>: %s"


Fix scroll

Fix scroll

--- src/cljs/auto/core.cljs
+++ src/cljs/auto/core.cljs
@@ -42,7 +42,7 @@
   (let [element-to (dom/by-id element-to-id)
         position-to (-> element-to .getBoundingClientRect .-top)
         top (-> js/document .-body .-scrollTop)
-        height (-> js/window .-innerHeight)]
+        height (+ top (-> js/window .-innerHeight))]
     (if (or (< position-to top) (> position-to height)) (.scrollIntoView element-to))))

 (defroute "/" []


* src/cljs/cljs/core.cljs: simplify + smaller threshold

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -829,7 +829,6 @@
          ret))))

 ;; Simple caching of string hashcode
-(def string-hash-cache-max 2048)
 (def string-hash-cache (js-obj))
 (def string-hash-cache-count 0)

@@ -840,7 +839,7 @@
     h))

 (defn check-string-hash-cache [k]
-  (when (> string-hash-cache-count string-hash-cache-max)
+  (when (> string-hash-cache-count 255)
     (set! string-hash-cache (js-obj))
     (set! string-hash-cache-count 0))
   (let [h (aget string-hash-cache k)]


remove unneeded loop binding `step`, two arity version of PersistentVector -reduce delegates to ci-reduce again - doing correct version of the loop with offset 1 seems to subtle at the momment.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -4116,9 +4116,9 @@

   IReduce
   (-reduce [v f]
-    (-reduce v f (f)))
+    (ci-reduce v f))
   (-reduce [v f init]
-    (loop [i 0 step 0 init init]
+    (loop [i 0 init init]
       (if (< i cnt)
         (let [arr  (unchecked-array-for v i)
               len  (alength arr)
@@ -4131,12 +4131,12 @@
                        init))]
           (if (reduced? init)
             @init
-            (recur (+ i len) len init)))
+            (recur (+ i len) init)))
         init)))

   IKVReduce
   (-kv-reduce [v f init]
-    (loop [i 0 step 0 init init]
+    (loop [i 0 init init]
       (if (< i cnt)
         (let [arr  (unchecked-array-for v i)
               len  (alength arr)
@@ -4149,7 +4149,7 @@
                        init))]
           (if (reduced? init)
             @init
-            (recur (+ i len) len init)))
+            (recur (+ i len) init)))
         init)))

   IFn


Fix args name; refs #11

Fix args name; refs #11

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -1064,9 +1064,9 @@
        (if (. f applyTo)
          (if (<= (bounded-count arglist fixed-arity)
                  fixed-arity)
-           (. f apply f (to-array arglist))
-           (. f apply f (to-array arglist))) ;; applyTo
-         (. f apply f (to-array arglist)))))
+           (. f apply f (to-array args))
+           (. f apply f (to-array args))) ;; applyTo
+         (. f apply f (to-array args)))))
   ([f x args]
      (let [arglist (list* x args)
            fixed-arity (. f cljs$lang$maxFixedArity)]


Use korma transactions instead of c.j.jdbc.

Korma keeps connections open, so it conflicts with raw c.j.jdbc usage
with sqlite.

--- src/clojars/promote.clj
+++ src/clojars/promote.clj
@@ -6,6 +6,7 @@
             [clojure.java.shell :as sh]
             [clojure.java.jdbc :as sql]
             [clojure.string :as str]
+            [korma.db :as korma]
             [cemerick.pomegranate.aether :as aether]
             [korma.core :refer [select fields where update set-fields]])
   (:import (java.util.concurrent LinkedBlockingQueue)
@@ -96,33 +97,33 @@
 (defn- deploy-to-s3 [info]
   (let [files (reduce (partial add-coords info) {}
                       ["jar" "jar.asc" "pom" "pom.asc"])]
-    (aether/deploy-artifacts :artifacts (keys files)
-                             :files files
-                             :transfer-listener :stdout
-                             :repository {"releases" releases})))
+    (when (config :releases-secret-key)
+      (aether/deploy-artifacts :artifacts (keys files)
+                               :files files
+                               :transfer-listener :stdout
+                               :repository {"releases" releases}))))

 (defn promote [{:keys [group name version] :as info}]
-  (sql/with-connection (config :db)
-    (sql/transaction
-     (let [blockers (blockers info)]
-       (if (empty? blockers)
-         (do
-           (println "Promoting" info)
-           (update db/jars
-                   (set-fields {:promoted_at (java.util.Date.)})
-                   (where {:group_name group :jar_name name :version version}))
-           (deploy-to-s3 info))
-         blockers)))))
+  (korma/transaction
+   (println "checking" group "/" name "for promotion...")
+   (let [blockers (blockers info)]
+     (if (empty? blockers)
+       (do
+         (println "Promoting" info)
+         (deploy-to-s3 info)
+         ;; TODO: this doesn't seem to be happening. db locked?
+         (update db/jars
+                 (set-fields {:promoted_at (java.util.Date.)})
+                 (where {:group_name group :jar_name name :version version})))
+       (do (println "...failed.")
+           blockers)))))

 (defonce queue (LinkedBlockingQueue.))

 (defn start []
   (.start (Thread. #(loop []
-                      (try (promote (.take queue))
-                           (catch Exception e
-                             (.printStackTrace e)))
+                      (locking #'promote
+                        (try (promote (.take queue))
+                             (catch Exception e
+                               (.printStackTrace e))))
                       (recur)))))
-
-;; TODO: probably worth periodically queueing all non-promoted
-;; releases into here to catch things that fall through the cracks,
-;; say if the JVM is restarted before emptying this queue.


refold line for clarity

refold line for clarity

--- src/tile_game/grid.cljs
+++ src/tile_game/grid.cljs
@@ -82,7 +82,9 @@
     [:center
      [:h1 "Tile Puzzle"]
      (render-board board dim command)
-     [:h4 (if (solve/solved? board) "Solved!" "Slide tiles with arrow keys or clicking on tile")]
+     [:h4 (if (solve/solved? board)
+            "Solved!"
+            "Slide tiles with arrow keys or clicking on tile")]
      [:details [:summary (str (count moves) " moves.")] (str moves)]
      (board-size-slider size command)
      [:div


minor: improve logs

minor: improve logs

--- ssclj/jar/src/main/clojure/com/sixsq/slipstream/ssclj/usage/record_keeper.clj
+++ ssclj/jar/src/main/clojure/com/sixsq/slipstream/ssclj/usage/record_keeper.clj
@@ -123,15 +123,16 @@

 (defn- insert-metric
   [usage-metric]
-  (log/info "Will persist usage event metric "(:metric_name usage-metric)
-            "START:" usage-metric)
+  (log/info "Will record START for metric "(:metric_name usage-metric)
+            ", usage-metric :" usage-metric)
   (kc/insert usage_records (kc/values usage-metric))
   (log/info "Done persisting metric: " usage-metric))

 (defn- close-usage-record
   ([usage-metric close-timestamp]
-    (log/info "Will close usage event metric " (:metric_name usage-metric)
-              "with timestamp: " close-timestamp)
+    (log/info "Will record STOP for metric " (:metric_name usage-metric)
+              "with timestamp: " close-timestamp
+              ", usage-metric: " usage-metric)
     (kc/update
         usage_records
         (kc/set-fields {:end_timestamp close-timestamp})


Make volume dispatch table result in something better sounding.


adding with-path compojure wrapper so that instrument-handler can find the request :path metadata attribute

--- src/prometheus/core.clj
+++ src/prometheus/core.clj
@@ -1,5 +1,6 @@
 (ns prometheus.core
   (:import
+    (clojure.lang IObj)
     (java.io StringWriter)
     (io.prometheus.client.exporter.common TextFormat)
     (io.prometheus.client Counter Histogram CollectorRegistry)))
@@ -33,8 +34,19 @@
     (-> (.labels histogram labels)
         (.observe request-time))))

-(defn instrument-handler [handler ^String app-name ^CollectorRegistry registry]
+(defn with-path
+  "Adds the matched compojure route as the :path response metadata attribute"
+  [request response]
+  (if-let [route (last (:compojure/route request))]
+    (if (instance? IObj response)
+      (let [response-meta (or (meta response) {})]
+        (with-meta response (assoc response-meta :path route)))
+      response)
+    response))
+
+(defn instrument-handler
   "Ring middleware to record request metrics"
+  [handler ^String app-name ^CollectorRegistry registry]
   (let [counter (make-request-counter app-name registry)
         histogram (make-request-histogram app-name registry)]
     (fn [request]
@@ -48,8 +60,9 @@
         (record-request-metric counter histogram request-method response-status request-time response-path)
         response))))

-(defn dump-metrics [^CollectorRegistry registry]
-  "Compojure handler to expose prometheus metrics using simple client's text format"
+(defn dump-metrics
+  "Ring handler to expose prometheus metrics using simple client's text format"
+  [^CollectorRegistry registry]
   (let [writer (StringWriter.)]
     (TextFormat/write004 writer (.metricFamilySamples registry))
     {:status  200


Switch to clj-http and fix ns declaration

--- src/riemann/mailgun.clj
+++ src/riemann/mailgun.clj
@@ -1,8 +1,7 @@
-;(ns riemann.mailgun
-  ;"Forwards events to Mailgun"
-  ;(:require [clj-http.client :as client]))
-(use 'aleph.http)
-(use '[riemann.common :only [body subject]])
+(ns riemann.mailgun
+  "Forwards events to Mailgun"
+  (:require [clj-http.client :as client]
+            [riemann.common :refer [body subject]]))

 (def ^:private event-url
   "https://api.mailgun.net/v2/%s/messages")
@@ -10,10 +9,8 @@
 (defn- post
   "POST to the Mailgun events API."
   [mgun-opts msg-opts]
-  (sync-http-request
-    {:method :post
-     :url (format event-url (:sandbox mgun-opts))
-     :basic-auth ["api" (:service-key mgun-opts)]
+  (client/post (format event-url (:sandbox mgun-opts))
+    {:basic-auth ["api" (:service-key mgun-opts)]
      :form-params
      {:from (format (:from msg-opts) (:sandbox mgun-opts))
       :to (:to msg-opts)


streams/forward can take vectors of events

--- src/riemann/streams.clj
+++ src/riemann/streams.clj
@@ -1139,10 +1139,12 @@
     (reset! reference event)))

 (defn forward
-  "Sends an event through a client"
+  "Sends an event or a collection of events through a Riemann client."
   [client]
-  (fn stream [event]
-    (riemann.client/send-event client event)))
+  (fn stream [es]
+    (if (map? es)
+      (riemann.client/send-event client es)
+      (riemann.client/send-events client es))))

 (defn match
   "Passes events on to children only when (f event) matches value, using


atomize interpolate-constant

atomize interpolate-constant

--- src/riemann/streams.clj
+++ src/riemann/streams.clj
@@ -679,22 +679,20 @@

   Note: ignores event times currently--will change later."
   [interval & children]
-    (let [state (ref nil)
+    (let [state (atom nil)
           emit-dup (bound-fn emit-dup []
                      (call-rescue
                        (assoc (deref state) :time (unix-time))
                        children))
           peri (periodically-until-expired interval emit-dup)]
       (fn stream [event]
-        (dosync
-          (ref-set state event))
+        (reset! state event)

         (peri event)
         (when (expired? event)
           (call-rescue event children)
           ; Clean up
-          (dosync
-            (ref-set state nil))
+          (reset! state nil)
           ))))

 (defn ddt-real


Remove unnecessary map.

Remove unnecessary map.

--- src/onyx/plugin/messaging_output.clj
+++ src/onyx/plugin/messaging_output.clj
@@ -87,17 +87,14 @@
                            (reduce (fn [accum* segment]
                                      (let [routes (r/route-data event result segment)
                                            segment* (r/flow-conditions-transform segment routes event)
-                                           hash-group (g/hash-groups segment* egress-tasks task->group-by-fn)
-                                           ;; todo, map to short ids here
-                                           task-slots (map (fn [route]
-                                                             {:slot-id (select-slot job-task-id-slots hash-group route)
-                                                              :dst-task-id [job-id route]})
-                                                           (:flow routes))]
-                                       (reduce conj!
-                                               accum*
-                                               (map (fn [task-slot]
-                                                      [segment* task-slot])
-                                                    task-slots))))
+                                           hash-group (g/hash-groups segment* egress-tasks task->group-by-fn)]
+                                       (reduce (fn [coll route]
+                                                 (conj! coll
+                                                        (list segment*
+                                                              {:slot-id (select-slot job-task-id-slots hash-group route)
+                                                               :dst-task-id [job-id route]})))
+                                               accum*
+                                               (:flow routes))))
                                    accum
                                    leaves))
                          (transient [])


Fix svg loading would break the `viewBox` property

--- src/sinusoides/util.clj
+++ src/sinusoides/util.clj
@@ -26,8 +26,12 @@
      x#))

 (defmacro embed-svg [svg-file]
-  (let [hiccup (tagsoup/parse-string (slurp svg-file))]
-    `~hiccup))
+  (let [svg (tagsoup/parse-string (slurp svg-file))
+        fix (let [viewbox (:viewbox (svg 1))]
+              (if (nil? viewbox)
+                svg
+                (assoc-in svg [1 :viewBox] viewbox)))]
+    `~fix))

 ;; from clojure.core.incubator
 (defn seqable? [x]


Remove deprecated wrap-file-info middleware

--- src/compojure/route.clj
+++ src/compojure/route.clj
@@ -5,7 +5,6 @@
         [ring.util.response :only (file-response resource-response status)]
         [ring.util.codec :only (url-decode)]
         ring.middleware.content-type
-        ring.middleware.file-info
         ring.middleware.head))

 (defn- add-wildcard
@@ -21,7 +20,7 @@
   (-> (GET (add-wildcard path) {{file-path :*} :route-params}
         (let [options (merge {:root "public"} options)]
           (file-response file-path options)))
-      (wrap-file-info (:mime-types options))
+      (wrap-content-type options)
       (wrap-head)))

 (defn resources
@@ -32,7 +31,6 @@
   (-> (GET (add-wildcard path) {{resource-path :*} :route-params}
         (let [root (:root options "public")]
           (resource-response (str root "/" resource-path))))
-      (wrap-file-info (:mime-types options))
       (wrap-content-type options)
       (wrap-head)))


Consolidate codename and help-keys into keymap

--- src/tile_game/grid.cljs
+++ src/tile_game/grid.cljs
@@ -63,20 +63,22 @@
      (let [tile (b/coords->tile board [x y])]
        (render-tile [x y] tile command)))])

+(def keymap
+  [{:key "Left", :desc "Move blank tile left", :code 37, :action :left}
+   {:key "Right", :desc "Move blank tile right", :code 39, :action :right}
+   {:key "Up", :desc "Move blank tile up", :code 38, :action :up}
+   {:key "Down", :desc "Move blank tile down", :code 40, :action :down}
+   {:key "N", :desc "Shuffle Board", :code 78, :action :new-game}
+   {:key "R", :desc "Reset Board", :code 82, :action :reset}
+   {:key "S", :desc "Solve next piece", :code 83, :action :solve}])
+
 (defn help-screen []
-  (let [help-keys {"Left" "Move blank tile left"
-                   "Right" "Move blank tile right"
-                   "Up" "Move blank tile up"
-                   "Down" "Move blank tile down"
-                   "N" "Shuffle Board"
-                   "R" "Reset Board"
-                   "S" "Solve next piece"}]
-    [:table {:style {:width "25%"}}
-     [:thead
-      [:tr [:th "Key"] [:th "Action"]]]
-     (into [:tbody]
-           (for [[key action] help-keys]
-             [:tr [:td key] [:td action]]))]))
+  [:table {:style {:width "25%"}}
+   [:thead
+    [:tr [:th "Key"] [:th "Action"]]]
+   (into [:tbody]
+         (for [{:keys [key desc]} keymap]
+           [:tr [:td key] [:td desc]]))])

 (defn tile-grid [command]
   (let [{:keys [board size analysis-mode moves]} @app-state
@@ -131,20 +133,13 @@
         (recur new-cancel)))
     (recur cancel)))

-(def codename
-  {37 :left
-   39 :right
-   38 :up
-   40 :down
-   78 :new-game
-   82 :reset
-   83 :solve})
-
 (defn handle-keydown [command]
-  (fn [e]
-    (when-let [key (codename (.-keyCode e))]
-      (.preventDefault e)
-      (async/put! command key))))
+  (let [codename (into {} (for [{:keys [code action]} keymap]
+                            [code action]))]
+    (fn [e]
+      (when-let [key (codename (.-keyCode e))]
+        (.preventDefault e)
+        (async/put! command key)))))

 (defn init []
   (let [command (async/chan)]


fix kondo warning about missing else statement

--- src/tile_game/grid.cljs
+++ src/tile_game/grid.cljs
@@ -46,7 +46,7 @@
      "Shuffle"]]])

 (defn render-tile [[x y] tile command]
-  (if-not (zero? tile)
+  (when-not (zero? tile)
     (let [fill-color (nth colors tile)]
       [:g {:key (str "tile-" tile) :on-click #(async/put! command tile)}
        [:rect {:x (+ x 0.05) :y (+ y 0.05) :width 0.9 :height 0.9 :fill fill-color}]


formatting fns on one line just b/c

formatting fns on one line just b/c

--- src/app/cljs/one/sample/view/editor.cljs
+++ src/app/cljs/one/sample/view/editor.cljs
@@ -64,12 +64,11 @@
     (event/listen new
                   CLICK
                   (fn [e]
-                    (append! ($ "#content") (detach! ($ "#workspace")))
+                    (appe#nd! ($ "#content") (detach! ($ "#workspace")))
                     (dispatch/fire :document-requested)))
     (event/listen title
                   CLICK
-                  (fn [e]
-                    (.setAttribute title "contenteditable" true)))))
+                  (fn [e] (.setAttribute title "contenteditable" true)))))

 (defn- add-documents-list-listeners []
   (let [items (nodes ($ "#sidebar-documents > ol > li"))]


Don't my own gl texture funcs

Don't my own gl texture funcs

yet

--- go-fighweel/src/cloj/lwjgl/texture.clj
+++ go-fighweel/src/cloj/lwjgl/texture.clj
@@ -1,4 +0,0 @@
-(ns cloj.lwjgl.texture
-  (:require )
-
-  )


Release 1.3.5.

Release 1.3.5.

--- src/traqbio/version.clj
+++ src/traqbio/version.clj
@@ -21,7 +21,7 @@
 (ns traqbio.version)

-(def ^:private ^:const version "1.3.5-SNAPSHOT")
+(def ^:private ^:const version "1.3.5")

 (defn traqbio-version


Added segv-alive helper func.

Added segv-alive helper func.

--- src/rewindable/ago.cljs
+++ src/rewindable/ago.cljs
@@ -38,6 +38,20 @@

 (defn seqv+ [ago-world-now]
   (update-in ago-world-now [:seqv (dec (count (:seqv ago-world-now)))] inc))
+
+(defn compare-segvs [segv-x segv-y]
+  (loop [xs segv-x
+         ys segv-y]
+    (let [x (first xs)
+          y (first ys)]
+      (cond (= nil x y) 0
+            (nil? x) 1 ; Normal compare handles length mismatches wrong.
+            (nil? y) -1
+            (= x y) (recur (rest xs) (rest ys))
+            :else (- x y)))))
+
+(defn segv-alive? [ago-world segv]
+  (<= (compare-segvs segv (:segv @ago-world)) 0))

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

@@ -189,19 +203,8 @@
     (active? [_] (active-cb))
     (commit [_] (when (active-cb) f))))

-(defn compare-segvs [segv-x segv-y]
-  (loop [xs segv-x
-         ys segv-y]
-    (let [x (first xs)
-          y (first ys)]
-      (cond (= nil x y) 0
-            (nil? x) 1
-            (nil? y) -1
-            (= x y) (recur (rest xs) (rest ys))
-            :else (- x y)))))
-
 (defn ago-take [state blk ^not-native c]
-  (let [active? #(<= (compare-segvs (chan-segv c) (:segv @(chan-ago-world c))) 0)]
+  (let [active? #(segv-alive? (chan-ago-world c) (chan-segv c))]
     (if-let [cb (protocols/take!
                  c (fn-handler
                     active?
@@ -216,7 +219,7 @@
       nil)))

 (defn ago-put [state blk ^not-native c val]
-  (let [active? #(<= (compare-segvs (chan-segv c) (:segv @(chan-ago-world c))) 0)]
+  (let [active? #(segv-alive? (chan-ago-world c) (chan-segv c))]
     (if-let [cb (protocols/put!
                  c val (fn-handler
                         active?
@@ -245,7 +248,7 @@
 (defn ago-return-chan [state value]
   (let [^not-native c (aget state ioc-helpers/USER-START-IDX)
         ago-world (chan-ago-world c)
-        active? #(<= (compare-segvs (chan-segv c) (:segv @ago-world)) 0)]
+        active? #(segv-alive? ago-world (chan-segv c))]
     (when (active?)
       (when-not (nil? value)
         (protocols/put! c value (fn-handler active? (fn [] nil))))
@@ -285,4 +288,3 @@
       (doseq [[sma-old ss-buf] reborn-smasN]
         (ago-revive-state-machine ago-world sma-old ss-buf))
       ago-world))
-


Revert "Deprecate streams/over and streams/under"

Decided I like these after all.

This reverts commit 0bdb11c4a9afb984e7b3b83d9df08b234624b41d.

--- src/riemann/streams.clj
+++ src/riemann/streams.clj
@@ -1540,20 +1540,18 @@
 (defn over
   "Passes on events only when their metric is greater than x"
   [x & children]
-  (deprecated "streams/over is deprecated in favor of (where (< x metric))"
-              (fn stream [event]
-                (when-let [m (:metric event)]
-                  (when (< x m)
-                    (call-rescue event children))))))
+  (fn stream [event]
+    (when-let [m (:metric event)]
+      (when (< x m)
+        (call-rescue event children)))))

 (defn under
   "Passes on events only when their metric is smaller than x"
   [x & children]
-  (deprecated "streams/under is deprecated in favor of (where (< metric x))"
-              (fn stream [event]
-                (when-let [m (:metric event)]
-                  (when (> x m)
-                    (call-rescue event children))))))
+  (fn stream [event]
+    (when-let [m (:metric event)]
+      (when (> x m)
+        (call-rescue event children)))))

 (defn- where-test [k v]
   (condp some [k]


Coalesce: reduce race condition

Coalesce: reduce race condition

Coalesce emitted a lazy sequence from a mutable iterator to downstream
children. Forces realization into a vector.

--- src/riemann/streams.clj
+++ src/riemann/streams.clj
@@ -1047,10 +1047,10 @@

 (defn coalesce
   "Combines events over time. Coalesce remembers the most recent event for each
-  service/host combination that passes through it (limited by :ttl). Every second,
-  it passes on *all* events it remembers. When events
-  expire, they are included in the emitted sequence of events *once*, and
-  removed from the state table thereafter.
+  service/host combination that passes through it (limited by :ttl). Every
+  second, it passes on *all* events it remembers. When events expire, they are
+  included in the emitted sequence of events *once*, and removed from the state
+  table thereafter.

   Use coalesce to combine states that arrive at different times--for instance,
   to average the CPU use over several hosts."
@@ -1059,7 +1059,7 @@
         dt (if (number? dt) dt 1)
         chm (java.util.concurrent.ConcurrentHashMap.)
         callback (fn callback []
-                   (let [es (seq (.values chm))
+                   (let [es (vec (.values chm))
                          expired (filter expired? es)]
                      (doseq [e expired
                              :let [s (:service e)


Include version numbers in temp store

Include version numbers in temp store

--- src/rill/temp_store.clj
+++ src/rill/temp_store.clj
@@ -22,7 +22,10 @@
   [given-events]
   (let [store (memory-store)]
     (doseq [events (partition-by message/primary-aggregate-id given-events)]
-      (append-events store (message/primary-aggregate-id (first events)) nil events))
+      (append-events store
+                     (message/primary-aggregate-id (first events))
+                     nil
+                     (map #(assoc %1 message/number %2) events (iterate inc 0))))
     store))

 (defn execute
@@ -54,4 +57,3 @@
    [actual-status actual-events]]
   (and (= expected-status actual-status)
        (messages= expected-events actual-events)))
-


add catalyst integration routes stubs

add catalyst integration routes stubs

--- src/wb_es/web/index.clj
+++ src/wb_es/web/index.clj
@@ -5,18 +5,38 @@
             [ring.middleware.json :refer [wrap-json-response]]
             [ring.util.response :refer [response not-found]]
             [wb-es.web.core :as web-core]))
+(def search-route
+  (GET "/search" [q & options]
+       (response (web-core/search q options))))
+
+(def autocomplete-route
+  (GET "/autocomplete" [q & options]
+       (response (web-core/autocomplete q options))))
+
+(def search-exact-route
+  (GET "/search-exact" [q & options]
+       (response (web-core/search-exact q options))))
+
+(def count-route
+  (GET "/count" [q & options]
+       (response (web-core/count q options))))
+
+(def random-route
+  (GET "/random" [q & options]
+       (response (web-core/random options))))

 (defroutes app
-  (GET "/search" [q & options]
-       (response (web-core/search q options)))
-  (GET "/autocomplete" [q & options]
-       (response (web-core/autocomplete q options)))
-  (GET "/search-exact" [q & options]
-       (response (web-core/search-exact q options)))
-  (GET "/count" [q & options]
-       (response (web-core/count q options)))
-  (GET "/random" [q & options]
-       (response (web-core/random options)))
+  search-route
+  autocomplete-route
+  search-exact-route
+  count-route
+  random-route
+  (context "/integration" []
+           search-route
+           autocomplete-route
+           search-exact-route
+           count-route
+           random-route)
   (route/not-found (response {:message "endpoint not found"})))

 (defn handler [request]


:update-contact! handler fixed (#559)

:update-contact! handler fixed (#559)

--- src/status_im/contacts/handlers.cljs
+++ src/status_im/contacts/handlers.cljs
@@ -83,9 +83,12 @@
                                         :private updates-private-key}}}})))

 (register-handler :update-contact!
-  (-> (fn [db [_ {:keys [whisper-identity] :as contact}]]
+  (fn [db [_ {:keys [whisper-identity] :as contact}]]
+    (if (contacts/exists? whisper-identity)
+      (do
+        (contacts/save contact)
         (update-in db [:contacts whisper-identity] merge contact))
-      ((after save-contact))))
+      db)))

 (defn load-contacts! [db _]
   (let [contacts (->> (contacts/get-all)


NB: Fix BREAKING v2.2.2 `conn-pool` bug

NB: Fix BREAKING v2.2.2 `conn-pool` bug

v2.2.2 introduced a bug that broke `wcar` support for custom connection pool
types and API compatibility with Carmine v1.

This commit fixes the regression w/o giving up the recent `conn-pool`
performance gains. Sorry for the hassle!

--- src/taoensso/carmine/connections.clj
+++ src/taoensso/carmine/connections.clj
@@ -91,27 +91,31 @@

 (def ^:private pool-cache (atom {}))

-(defn conn-pool ^java.io.Closeable [opts & [cached?]]
-  (if (not (or (nil? opts) (map? opts) (keyword? opts)))
-    opts ; Pass through pre-made pools (Carmine v1 & custom pool support)
-    (if-let [dp (and cached? (@pool-cache opts))]
-      @dp
-      (locking pool-cache ; Pool creation can be racey even with `delay`
-        ;; Retry after lock acquisition:
-        (if-let [dp (and cached? (@pool-cache opts))]
-          @dp
-          (let [dp (delay
-                    (if (= opts :none) (->NonPooledConnectionPool)
-                        (let [defaults {:test-while-idle?              true
-                                        :num-tests-per-eviction-run    -1
-                                        :min-evictable-idle-time-ms    60000
-                                        :time-between-eviction-runs-ms 30000}]
-                          (->ConnectionPool
-                           (reduce set-pool-option
-                                   (GenericKeyedObjectPool. (make-connection-factory))
-                                   (merge defaults opts))))))]
-            (swap! pool-cache assoc opts dp)
-            @dp))))))
+(defn conn-pool ^java.io.Closeable [opts & [use-cache?]]
+  ;; Impl. a little contorted for high-speed v1 API backwards-comp
+  (if-let [dp (and use-cache? (@pool-cache opts))]
+    @dp
+    (let [dp (delay
+              (cond
+               (= opts :none) (->NonPooledConnectionPool)
+               ;; Pass through pre-made pools (note that test reflects):
+               (satisfies? IConnectionPool opts) opts
+               :else
+               (let [defaults {:test-while-idle?              true
+                               :num-tests-per-eviction-run    -1
+                               :min-evictable-idle-time-ms    60000
+                               :time-between-eviction-runs-ms 30000}]
+                 (->ConnectionPool
+                  (reduce set-pool-option
+                          (GenericKeyedObjectPool. (make-connection-factory))
+                          (merge defaults opts))))))]
+      (if-not use-cache?
+        @dp
+        (locking pool-cache ; Pool creation can be racey even with `delay`
+          (if-let [dp (@pool-cache opts)] ; Retry after lock acquisition
+            @dp
+            (do (swap! pool-cache assoc opts dp)
+                @dp)))))))

 (comment (conn-pool :none) (conn-pool {}))

@@ -138,7 +142,7 @@
 (defn pooled-conn "Returns [<open-pool> <pooled-connection>]."
   [pool-opts spec-opts]
   (let [spec (conn-spec spec-opts)
-        pool (conn-pool pool-opts :cached)]
+        pool (conn-pool pool-opts :use-cache)]
     (try (try [pool (get-conn pool spec)]
               (catch IllegalStateException e
                 (let [pool (conn-pool pool-opts)]


Sort by date descending

Sort by date descending

--- src/zoo_live/events.clj
+++ src/zoo_live/events.clj
@@ -46,6 +46,7 @@
     (select ent
             (where where-clause)
             (limit per_page)
+            (order :created_at :DESC)
             (offset (* (- page 1) per_page)))))

 (defn- kafka-config


Fix projects creation lightbox.

Fix projects creation lightbox.

--- src/uxbox/ui/dashboard/projects.cljs
+++ src/uxbox/ui/dashboard/projects.cljs
@@ -230,10 +230,10 @@
   [local]
   (html
    [:div.input-radio.radio-primary
-    (layout-input local :mobile)
-    (layout-input local :tablet)
-    (layout-input local :notebook)
-    (layout-input local :desktop)]))
+    (layout-input local "mobile")
+    (layout-input local "tablet")
+    (layout-input local "notebook")
+    (layout-input local "desktop")]))

 (defn- new-project-lightbox-render
   [own]


Fix range of sine oscillator.

Fix range of sine oscillator.

--- src/afterglow/effects/oscillators.clj
+++ src/afterglow/effects/oscillators.clj
@@ -503,7 +503,7 @@
   (let [two-pi (* 2.0 Math/PI)]
     (build-oscillator (fn [phase]
                         (let [adjusted-phase (- phase 0.25)]
-                          (+ 0.5 (Math/sin (* two-pi adjusted-phase)))))
+                          (+ 0.5 (* 0.5 (Math/sin (* two-pi adjusted-phase))))))
                       :interval interval :interval-ratio interval-ratio :phase phase)))

 (defn sine-beat


Showing UI page on new version initialization

https://app.asana.com/0/17212341117686/62449643414915

--- src/background/relevance/background.cljs
+++ src/background/relevance/background.cljs
@@ -14,7 +14,7 @@
             [re-frame.core :refer [dispatch register-sub register-handler subscribe dispatch-sync]]
             [khroma.extension :as ext]
             [khroma.browser-action :as browser]
-            )
+            [khroma.storage :as storage])
   (:require-macros [cljs.core.async.macros :refer [go go-loop]]))

@@ -120,7 +120,16 @@
       (dispatch [:data-load (<! (io/load))])
       (dispatch [::window-focus {:windowId (:id (<! (windows/get-last-focused {:populate false})))}])
       ;; We should only hook to the channels once, so we do it during the :initialize handler
-      (hook-to-channels))
+      (hook-to-channels)
+      ;; Finally, if it's the first time on this version, show the intro page
+      ;; We could probably hook to on-installed,
+      (let [version    (get @runtime/manifest "version")
+            last-shown (:last-initialized (<! (storage/get :last-initialized)))]
+        (when (not= version last-shown)
+          (open-results-tab)
+          (storage/set {:last-initialized version}))
+        )
+      )
     {:app-state {}}))


inlined handler fns for search page

inlined handler fns for search page

--- src/cljs/phonecat_re_frame/handlers.cljs
+++ src/cljs/phonecat_re_frame/handlers.cljs
@@ -75,18 +75,12 @@
      :search-input  ""
      :order-prop    "name"}))

-(defn handle-search-input-entered
-  [app-state [_ search-input]]
-  (assoc-in app-state [:search-input] search-input))
-
-(defn handle-order-prop-changed
-  [app-state [_ order-prop]]
-  (assoc-in app-state [:order-prop] order-prop))
-
 (register-handler
   :search-input-entered
-  handle-search-input-entered)
+  (fn [app-state [_ search-input]]
+    (assoc-in app-state [:search-input] search-input)))

 (register-handler
   :order-prop-changed
-  handle-order-prop-changed)+  (fn [app-state [_ order-prop]]
+    (assoc-in app-state [:order-prop] order-prop)))