remove the old school comments from compiler.clj

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -982,15 +982,6 @@
             (throw (ex-info (str "failed compiling file:" src) {:file src} e))))
         (throw (java.io.FileNotFoundException. (str "The file " src " does not exist.")))))))

-(comment
-  ;; flex compile-file
-  (do
-    (compile-file "/tmp/hello.cljs" "/tmp/something.js")
-    (slurp "/tmp/hello.js")
-
-    (compile-file "/tmp/somescript.cljs")
-    (slurp "/tmp/somescript.js")))
-
 (defn path-seq
   [file-str]
   (->> File/separator
@@ -1044,14 +1035,6 @@
              (recur (rest cljs-files) (conj output-files (assoc ns-info :file-name (.getPath output-file)))))
            output-files)))))

-(comment
-  ;; compile-root
-  ;; If you have a standard project layout with all file in src
-  (compile-root "src")
-  ;; will produce a mirrored directory structure under "out" but all
-  ;; files will be compiled to js.
-  )
-
 ;; TODO: needs fixing, table will include other things than keywords - David

 (defn emit-constants-table [table]
@@ -1072,191 +1055,3 @@
   (with-open [out ^java.io.Writer (io/make-writer dest {})]
     (binding [*out* out]
       (emit-constants-table table))))
-
-(comment
-
-;;the new way - use the REPL!!
-(require '[cljs.compiler :as comp])
-(def repl-env (comp/repl-env))
-(comp/repl repl-env)
-;having problems?, try verbose mode
-(comp/repl repl-env :verbose true)
-;don't forget to check for uses of undeclared vars
-(comp/repl repl-env :warn-on-undeclared true)
-
-(test-stuff)
-(+ 1 2 3)
-([ 1 2 3 4] 2)
-({:a 1 :b 2} :a)
-({1 1 2 2} 1)
-(#{1 2 3} 2)
-(:b {:a 1 :b 2})
-('b '{:a 1 b 2})
-
-(extend-type number ISeq (-seq [x] x))
-(seq 42)
-;(aset cljs.core.ISeq "number" true)
-;(aget cljs.core.ISeq "number")
-(satisfies? ISeq 42)
-(extend-type nil ISeq (-seq [x] x))
-(satisfies? ISeq nil)
-(seq nil)
-
-(extend-type default ISeq (-seq [x] x))
-(satisfies? ISeq true)
-(seq true)
-
-(test-stuff)
-
-(array-seq [])
-(defn f [& etc] etc)
-(f)
-
-(in-ns 'cljs.core)
-;;hack on core
-
-
-(deftype Foo [a] IMeta (-meta [_] (fn [] a)))
-((-meta (Foo. 42)))
-
-;;OLD way, don't you want to use the REPL?
-(in-ns 'cljs.compiler)
-(import '[javax.script ScriptEngineManager])
-(def jse (-> (ScriptEngineManager.) (.getEngineByName "JavaScript")))
-(.eval jse cljs.compiler/bootjs)
-(def envx {:ns (@namespaces 'cljs.user) :context :expr :locals '{ethel {:name ethel__123 :init nil}}})
-(analyze envx nil)
-(analyze envx 42)
-(analyze envx "foo")
-(analyze envx 'fred)
-(analyze envx 'fred.x)
-(analyze envx 'ethel)
-(analyze envx 'ethel.x)
-(analyze envx 'my.ns/fred)
-(analyze envx 'your.ns.fred)
-(analyze envx '(if test then else))
-(analyze envx '(if test then))
-(analyze envx '(and fred ethel))
-(analyze (assoc envx :context :statement) '(def test "fortytwo" 42))
-(analyze (assoc envx :context :expr) '(fn* ^{::fields [a b c]} [x y] a y x))
-(analyze (assoc envx :context :statement) '(let* [a 1 b 2] a))
-(analyze (assoc envx :context :statement) '(defprotocol P (bar [a]) (baz [b c])))
-(analyze (assoc envx :context :statement) '(. x y))
-(analyze envx '(fn foo [x] (let [x 42] (js* "~{x}['foobar']"))))
-
-(analyze envx '(ns fred (:require [your.ns :as yn]) (:require-macros [clojure.core :as core])))
-(defmacro js [form]
-  `(emit (ana/analyze {:ns (@ana/namespaces 'cljs.user) :context :statement :locals {}} '~form)))
-
-(defn jscapture [form]
-  "just grabs the js, doesn't print it"
-  (with-out-str
-    (emit (analyze {:ns (@namespaces 'cljs.user) :context :expr :locals {}} form))))
-
-(defn jseval [form]
-  (let [js (jscapture form)]
-    ;;(prn js)
-    (.eval jse (str "print(" js ")"))))
-
-;; from closure.clj
-(optimize (jscapture '(defn foo [x y] (if true 46 (recur 1 x)))))
-
-(js (if a b c))
-(js (def x 42))
-(js (defn foo [a b] a))
-(js (do 1 2 3))
-(js (let [a 1 b 2 a b] a))
-
-(js (ns fred (:require [your.ns :as yn]) (:require-macros [cljs.core :as core])))
-
-(js (def foo? (fn* ^{::fields [a? b c]} [x y] (if true a? (recur 1 x)))))
-(js (def foo (fn* ^{::fields [a b c]} [x y] (if true a (recur 1 x)))))
-(js (defn foo [x y] (if true x y)))
-(jseval '(defn foo [x y] (if true x y)))
-(js (defn foo [x y] (if true 46 (recur 1 x))))
-(jseval '(defn foo [x y] (if true 46 (recur 1 x))))
-(jseval '(foo 1 2))
-(js (and fred ethel))
-(jseval '(ns fred (:require [your.ns :as yn]) (:require-macros [cljs.core :as core])))
-(js (def x 42))
-(jseval '(def x 42))
-(jseval 'x)
-(jseval '(if 42 1 2))
-(jseval '(or 1 2))
-(jseval '(fn* [x y] (if true 46 (recur 1 x))))
-(.eval jse "print(test)")
-(.eval jse "print(cljs.user.Foo)")
-(.eval jse  "print(cljs.user.Foo = function (){\n}\n)")
-(js (def fred 42))
-(js (deftype* Foo [a b-foo c]))
-(jseval '(deftype* Foo [a b-foo c]))
-(jseval '(. (new Foo 1 2 3) b-foo))
-(js (. (new Foo 1 2 3) b))
-(.eval jse "print(new cljs.user.Foo(1, 42, 3).b)")
-(.eval jse "(function (x, ys){return Array.prototype.slice.call(arguments, 1);})(1,2)[0]")
-
-(macroexpand-1 '(cljs.core/deftype Foo [a b c] Fred (fred [x] a) (fred [x y] b) (ethel [x] c) Ethel (foo [] d)))
-(-> (macroexpand-1 '(cljs.core/deftype Foo [a b c] Fred (fred [x] a) (fred [x y] b) (ethel [x] c) Ethel (foo [] d)))
-    last last last first meta)
-
-(macroexpand-1 '(cljs.core/extend-type Foo Fred (fred ([x] a) ([x y] b)) (ethel ([x] c)) Ethel (foo ([] d))))
-(js (new foo.Bar 65))
-(js (defprotocol P (bar [a]) (baz [b c])))
-(js (. x y))
-(js (. "fred" (y)))
-(js (. x y 42 43))
-(js (.. a b c d))
-(js (. x (y 42 43)))
-(js (fn [x] x))
-(js (fn ([t] t) ([x y] y) ([ a b & zs] b)))
-
-(js (. (fn foo ([t] t) ([x y] y) ([a b & zs] b)) call nil 1 2))
-(js (fn foo
-      ([t] t)
-      ([x y] y)
-      ([ a b & zs] b)))
-
-(js ((fn foo
-       ([t] (foo t nil))
-       ([x y] y)
-       ([ a b & zs] b)) 1 2 3))
-
-
-(jseval '((fn foo ([t] t) ([x y] y) ([ a b & zs] zs)) 12 13 14 15))
-
-(js (defn foo [this] this))
-
-(js (defn foo [a b c & ys] ys))
-(js ((fn [x & ys] ys) 1 2 3 4))
-(jseval '((fn [x & ys] ys) 1 2 3 4))
-(js (cljs.core/deftype Foo [a b c] Fred (fred [x] a) (fred [x y] a)  (ethel [x] c) Ethel (foo [] d)))
-(jseval '(cljs.core/deftype Foo [a b c] Fred (fred [x] a) (fred [x y] a)  (ethel [x] c) Ethel (foo [] d)))
-
-(js (do
-           (defprotocol Proto (foo [this]))
-           (deftype Type [a] Proto (foo [this] a))
-           (foo (new Type 42))))
-
-(jseval '(do
-           (defprotocol P-roto (foo? [this]))
-           (deftype T-ype [a] P-roto (foo? [this] a))
-           (foo? (new T-ype 42))))
-
-(js (def x (fn foo [x] (let [x 42] (js* "~{x}['foobar']")))))
-(js (let [a 1 b 2 a b] a))
-
-(doseq [e '[nil true false 42 "fred" fred ethel my.ns/fred your.ns.fred
-            (if test then "fooelse")
-            (def x 45)
-            (do x y y)
-            (fn* [x y] x y x)
-            (fn* [x y] (if true 46 (recur 1 x)))
-            (let* [a 1 b 2 a a] a b)
-            (do "do1")
-            (loop* [x 1 y 2] (if true 42 (do (recur 43 44))))
-            (my.foo 1 2 3)
-            (let* [a 1 b 2 c 3] (set! y.s.d b) (new fred.Ethel a b c))
-            (let [x (do 1 2 3)] x)
-            ]]
-  (->> e (analyze envx) emit)
-  (newline)))


Use specific path-munging function for ns resolution

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -1217,8 +1217,11 @@
         :else {:env env :op :set! :form form :target targetexpr :val valexpr
                :children [targetexpr valexpr]})))))

+(defn munge-path [ss]
+  (clojure.lang.Compiler/munge (str ss)))
+
 (defn ns->relpath [s]
-  (str (string/replace (munge s) \. \/) ".cljs"))
+  (str (string/replace (munge-path s) \. \/) ".cljs"))

 (declare analyze-file)


* src/clj/cljs/compiler.clj: direct invoke goog ns

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -688,7 +688,12 @@
   (let [fn? (and *cljs-static-fns*
                  (not (-> f :info :dynamic))
                  (-> f :info :fn-var))
-        js? (= (-> f :info :ns) 'js)
+        ns (-> f :info :ns)
+        js? (= ns 'js)
+        goog? (when ns
+                (or (= ns 'goog)
+                    (when-let [ns-str (str ns)]
+                      (= (get (string/split ns-str #"\.") 0 nil) "goog"))))
         keyword? (and (= (-> f :op) :constant)
                       (keyword? (-> f :form)))
         [f variadic-invoke]
@@ -729,7 +734,7 @@
                (when-not (zero? mfa) ",")
                "cljs.core.array_seq([" (comma-sep (drop mfa args)) "], 0))"))

-       (or fn? js?)
+       (or fn? js? goog?)
        (emits f "(" (comma-sep args)  ")")

        :else


Delete obsoleted functions

Delete obsoleted functions

--- src/useful/io.clj
+++ src/useful/io.clj
@@ -3,30 +3,6 @@
   (:import [java.net URL URLConnection JarURLConnection]
            [java.io File FileInputStream PrintStream]
            [clojure.lang IDeref]))
-
-(defmacro multi-outstream [var]
-  (let [current-writer
-        `(let [w# ~var]
-           (if (instance? IDeref w#) (first @w#) w#))]
-    `(PrintStream.
-      (proxy [java.io.BufferedOutputStream] [nil]
-        (write
-          ([b#]           (.write ~current-writer b#))
-          ([b# off# len#] (.write ~current-writer b# off# len#)))
-        (flush [] (.flush ~current-writer))))))
-
-(defmacro with-outstream [bindings & forms]
-  `(do (doseq [[var# outs#] (partition 2 ~bindings)]
-         (swap! var# conj outs#))
-       (binding ~bindings ~@forms)
-       (doseq [[var# outs#] (partition 2 ~bindings)]
-         (doall (swap! var# (partial remove #(= outs# %)))))))
-
-(defn default-outstream-push [outs default]
-  (swap! outs conj default))
-
-(defn default-outstream-pop [outs default]
-  (doall (swap! outs (partial remove #(= default %)))))

 (defn resource-stream [name]
   (if-let [url (.findResource (.getClassLoader clojure.lang.RT) name)]


use with :only support

use with :only support

Signed-off-by: Brenton Ashworth <1d17d9de8cdc4334ed2cad585a02d8c1d3605456@gmail.com>

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -101,6 +101,9 @@
                       (do
                         (confirm-var-exists env prefix (symbol suffix))
                         sym))))
+
+           (get-in @namespaces [(-> env :ns :name) :uses sym])
+           (symbol (str (get-in @namespaces [(-> env :ns :name) :uses sym]) "." (munge (name sym))))

            :else
            (let [full-ns (if (core-name? env sym)
@@ -763,12 +766,16 @@
                       (into s xs))
                     s))
                 #{} args)
-        {requires :require requires-macros :require-macros :as params}
+        {uses :use requires :require requires-macros :require-macros :as params}
         (reduce (fn [m [k & libs]]
                   (assoc m k (into {}
-                                   (map (fn [[lib as alias]]
-                                          (assert (and alias (= :as as)) "Only [lib.ns :as alias] form supported")
-                                          [alias lib])
+                                   (mapcat (fn [[lib kw expr]]
+                                          (assert (and expr (or (= :as kw)
+                                                                (= :only kw)))
+                                                  "Only (:require [lib.ns :as alias]*) and (:use [lib.ns :only [names]]*) form supported")
+                                          (if (= :only kw)
+                                            (map vector expr (repeat lib))
+                                            [[expr lib]]))
                                         libs))))
                 {} (remove (fn [[r]] (= r :refer-clojure)) args))]
     (set! *cljs-ns* name)
@@ -778,12 +785,13 @@
     (swap! namespaces #(-> %
                            (assoc-in [name :name] name)
                            (assoc-in [name :excludes] excludes)
+                           (assoc-in [name :uses] uses)
                            (assoc-in [name :requires] requires)
                            (assoc-in [name :requires-macros]
                                      (into {} (map (fn [[alias nsym]]
                                                      [alias (find-ns nsym)])
                                                    requires-macros)))))
-    {:env env :op :ns :name name :requires requires
+    {:env env :op :ns :name name :uses uses :requires requires
      :requires-macros requires-macros :excludes excludes}))

 (defmethod parse 'deftype*
@@ -998,11 +1006,11 @@
                   ast (analyze env (first forms))]
               (do (emit ast)
                   (if (= (:op ast) :ns)
-                    (recur (rest forms) (:name ast) (:requires ast))
+                    (recur (rest forms) (:name ast) (merge (:uses ast) (:requires ast)))
                     (recur (rest forms) ns-name deps))))
             {:ns (or ns-name 'cljs.user)
              :provides [ns-name]
-             :requires (if (= ns-name 'cljs.core) (vals deps) (conj (vals deps) 'cljs.core))
+             :requires (if (= ns-name 'cljs.core) (set (vals deps)) (conj (set (vals deps)) 'cljs.core))
              :file dest}))))))

 (defn requires-compilation?


build the board for the game

build the board for the game

--- src/clojure_noon/core.clj
+++ src/clojure_noon/core.clj
@@ -960,5 +960,47 @@
  :rows 5}

-
-
+(defn tri*
+  "Generates lazy sequences of triangular numbers"
+  ([] (tri* 0 1))
+  ([sum n]
+   (let [new-sum (+ sum n)]
+     (cons new-sum (lazy-seq (tri* new-sum (inc n)))))))
+
+(def tri (tri*))
+
+(take 5 tri)
+
+(defn triangular?
+  "Is the number triangular? e.g. 1, 3, 6, 10, 15, etc."
+  [n]
+  (= n (last (take-while #(>= n %) tri))))
+
+(triangular? 6)
+
+(defn row-tri
+  "The triangular number at the end of the row n"
+  [n]
+  (last (take n tri)))
+
+(row-tri 2)
+
+(defn row-num
+  "Returns row number the position belongs to: pos 1 in row 1, positions 2 and 3 in row 2, etc."
+  [pos]
+  (inc (count (take-while #(> pos %) tri))))
+
+(row-num 5)
+
+(defn connect
+  "Form a mutual connection between two positions"
+  [board max-pos pos neighbor destination]
+  (if (<= destination max-pos)
+    (reduce (fn [new-board [p1 p2]]
+              (assoc-in new-board [p1 :connections p2] neighbor))
+            board
+            [[pos destination] [destination pos]])
+    board))
+
+(connect {} 15 1 2 4)
+


Chapter 3 and first three exercises completed

--- src/clojure_noon/core.clj
+++ src/clojure_noon/core.clj
@@ -392,3 +392,117 @@
 (let [[pongo & dalmations] dalmation-list]
   [pongo dalmations])

+(into final-body-parts
+      (set [part (matching-part part)]))
+
+(into [] (set [:a :a]))
+
+;let is a handy way to introduce local names for values which simpliefies the code
+
+(loop [iteration 0]
+  (println (str "Iteration " iteration))
+  (if (> iteration 3)
+    (println "Goodbye!")
+    (recur (inc iteration))))
+
+;the loop above and the function below are equivalent but loop is less verbose
+(defn recursive-printer
+  ([]
+   (recursive-printer 0))
+  ([iteration]
+   (println iteration)
+   (if (> iteration 3)
+     (println "Goodbye!")
+     (recursive-printer (inc iteration)))))
+
+(recursive-printer)
+
+#"regular-expression"
+(re-find #"^left-" "left-eye")
+(re-find #"^left-" "cleft-chin")
+(re-find #"^left-" "wongleblart")
+
+;re-find I assume stands for regular-expression find
+
+(defn matching-part
+  [part]
+  {:name (clojure.string/replace (:name part) #"^left-" "right-")
+   :size (:size part)})
+
+(matching-part {:name "left-eye" :size 1})
+
+(matching-part {:name "head" :size 3})
+
+;;better symmetrizer with reduce
+(reduce + [1 2 3 4])
+
+;;it is equivalent to this
+(+ (+ (+ 1 2) 3) 4)
+
+;reduce can also take an initial value
+(reduce + 15 [1 2 3 4]) ;;here the initial value is 15
+
+;;reduce is usually used to consilidate a bunch of values into 1 value like it is done above
+;;but reduce can also be used to take a bunch of values and turn them into a larger set of values
+;;one way of implementing the reduce function
+(defn my-reduce
+  ([f initial collection]
+   (loop [result initial
+          remaining collection]
+     (if (empty? remaining)
+       result
+       (recur (f result (first remaining)) (rest remaining)))))
+  ([f [head & tail]]
+   (my-reduce f head tail)))
+
+(defn better-symmetrize-body-parts
+  "expects a seq of maps that have a :name and :size"
+  [asym-body-parts]
+  (reduce (fn [final-body-parts part]
+            (into final-body-parts (set [part (matching-part part)])))
+          []
+          asym-body-parts))
+
+(defn hit
+  [asym-body-parts]
+  (let [sym-parts (better-symmetrize-body-parts asym-body-parts)
+        body-part-size-sum (reduce + (map :size sym-parts))
+        target (rand body-part-size-sum)]
+    (loop [[part & remaining] sym-parts
+           accumulated-size (:size part)]
+      (if (> accumulated-size target)
+        part
+        (recur remaining (+ accumulated-size (:size (first remaining))))))))
+
+(hit asym-hobbit-body-parts)
+
+;;exercises - chapter 3
+;1. use the str, vector, list, hash-map and hash-set functions.
+(prn-str "hello world")
+(str "hello world")
+(vector) ;creates an empty vector []
+[1 2 3] ;creates a vector with 1 2 3
+() ; empty list ()
+(1 2 3 4) ;list with 1 2 3 4
+(hash-map) ;empty hash-map {}
+{:key1 1 :key2 2} ;two keys and two values
+(hash-set) ; empty hash-set #{}
+#{1 2 3} ;hash-set can only have values
+
+;;2. write a function that takes a number and adds 100 to it
+(defn add-hundred
+  [num]
+  (+ num 100))
+(add-hundred 1)
+
+;;3. Write a function dec-maker, that works exactly like the function inc-maker except with subtraction
+(defn dec-maker
+  "Create a custom decrementer"
+  [dec-by]
+  #(- % dec-by))
+
+(def dec3 (dec-maker 3))
+(dec3 8)
+
+
+


new implementation of 'if

new implementation of 'if

--- src/co/nclk/flax/core.clj
+++ src/co/nclk/flax/core.clj
@@ -5,6 +5,7 @@
             [cheshire.generate :refer [add-encoder encode-str]]
             [clojure.pprint :refer [pprint]]
             [clojure.tools.logging :refer [log]]
+            [clojure.data.xml :as xml]
             [co.nclk.flax.node :refer [invoke destroy node-manager]]
             [co.nclk.flax.data :refer [resolve-module resolve-program]]
             [stencil.parser :refer [parse]]
@@ -347,7 +348,11 @@
         (condp = fun
           ;; Special forms
           'if
-          (eval (conj (evaluate (-> fun-entry val) config) fun))
+          (evaluate
+            ((if (evaluate (-> fun-entry val first) config)
+               second #(nth % 2 nil))
+              (-> fun-entry val))
+            config)

           'fn
           (fn [& argv]
@@ -413,6 +418,7 @@
           ;; Functions
           (let [yield (apply (resolve fun) (evaluate (-> m first val) config))]
             (if (coll? yield)
+              ;; Laziness disabled.
               (doall yield)
               yield))))

@@ -557,6 +563,9 @@
             failures (->> checkpoints
                           (filter #(-> % :success :value false?)))
             num-failures (count failures)]
+
+        (log :info "Creating target/logs/checkpoints.json")
+        (spit "target/logs/checkpoints.json" (json/generate-string checkpoints))
         (log :info "Creating target/logs/failures.json")
         (spit "target/logs/failures.json" (json/generate-string failures))
         (log :info (str "Failures: " num-failures))


Fix some indentation

Fix some indentation

--- test/com/nomistech/clojure_the_language/c_850_utils/s_100_utils_test.clj
+++ test/com/nomistech/clojure_the_language/c_850_utils/s_100_utils_test.clj
@@ -272,24 +272,24 @@
 ;;;; ---- positions ----

 (fact "`position` and `positions` work"
-      (fact "`position` tests"
-            (position even? []) => nil
-            (position even? [12]) => 0
-            (position even? [11 13 14]) => 2
-            (position even? [11 13 14 14]) => 2)
-      (fact "`positions` tests"
-            (positions even? []) => []
-            (positions even? [12]) => [0]
-            (positions even? [11 13 14]) => [2]
-            (positions even? [11 13 14 14 15]) => [2 3]))
+  (fact "`position` tests"
+    (position even? []) => nil
+    (position even? [12]) => 0
+    (position even? [11 13 14]) => 2
+    (position even? [11 13 14 14]) => 2)
+  (fact "`positions` tests"
+    (positions even? []) => []
+    (positions even? [12]) => [0]
+    (positions even? [11 13 14]) => [2]
+    (positions even? [11 13 14 14 15]) => [2 3]))

 ;;;; ___________________________________________________________________________
 ;;;; ---- last-index-of-char-in-string ----

 (fact "`last-index-of-char-in-string` works"
-      (fact (last-index-of-char-in-string \c "") => -1
-            (last-index-of-char-in-string \c "xyz") => -1
-            (last-index-of-char-in-string \c "c") => 0
-            (last-index-of-char-in-string \c "abc") => 2
-            (last-index-of-char-in-string \c "abcde") => 2
-            (last-index-of-char-in-string \c "abcce") => 3))
+  (fact (last-index-of-char-in-string \c "") => -1
+    (last-index-of-char-in-string \c "xyz") => -1
+    (last-index-of-char-in-string \c "c") => 0
+    (last-index-of-char-in-string \c "abc") => 2
+    (last-index-of-char-in-string \c "abcde") => 2
+    (last-index-of-char-in-string \c "abcce") => 3))


fixing misplaced docstring

fixing misplaced docstring

--- ingestion-api/src/ingestion_api/mqtt/domain/util.clj
+++ ingestion-api/src/ingestion_api/mqtt/domain/util.clj
@@ -10,8 +10,9 @@
     (bit-shift-right b 4)))

-(defn to-byte-array [s]
+(defn to-byte-array
   "Converts a sequence a byte-array"
+  [s]
   (byte-array (map byte s)))

 (defn gloss-int-type


Bump number of intersection tests in CI

Bump number of intersection tests in CI

--- test/aurora/btree_test.cljs
+++ test/aurora/btree_test.cljs
@@ -74,7 +74,7 @@
   (aurora.btree/iterator-prop 1))

 (defspec intersection-prop-test
-  500
+  1000
   aurora.btree/intersection-prop)

 (defspec trie-tree-prop-test


core: some?

core: some?

--- core.clj
+++ core.clj
@@ -371,3 +371,9 @@
   {:tag Bool
    :added "1.0"}
   [x] (if x false true))
+
+(defn some?
+  "Returns true if x is not nil, false otherwise."
+  {:tag Bool
+   :added "1.0"}
+  [x] (not (nil? x)))


Unrelated to macro stuff.

Unrelated to macro stuff.

--- core.clj
+++ core.clj
@@ -32,10 +32,8 @@
    [UnityEngine Time Mathf Debug]
    [seawisphunter.minibuffer Minibuffer Command]))

-(log "minibuffer.lisp.core reloaded")
-
-;; This is just me trying to debug do-with-minibuffer
-(defonce defer-count 0)
+;(log "minibuffer.lisp.core reloaded")
+
 ;; gen-delegate, generate-generic-delegate, sys-func, and sys-action taken from
 ;; core-clr.clj and reworked from macros to be functions.

@@ -73,20 +71,27 @@
 (defn do-with-minibuffer
   "Run (f Minibuffer/instance) when Minibuffer/instance is available.

-   FIXME: I don't think this works currently."
+   FIXME: I don't think defering works currently. I'm not sure any state can be saved when hitting stop then play in Unity."
   [f]
   (if (nil? Minibuffer/instance)
       (do
-          (def defer-count (inc defer-count))
-          (log "defering with-minibuffer")
+        ;(log "defering do-with-minibuffer")
         (Minibuffer/OnStart (gen-delegate Action [] (f Minibuffer/instance))) )
     (f Minibuffer/instance)))

 (defmacro with-minibuffer
+  "Minibuffer/instance is only available when a scene with Minibuffer is running. This form will defer execution until such an instance is available.
+
+  (with-minibuffer minibuffer
+    (.Message minibuffer \"Minibuffer instance available!\"))"
     [minibuffer-var & body]
     `(do-with-minibuffer (fn [~minibuffer-var] ~@body)))

+;; I'd really prefer if this weren't a macro.  Seems possible.
 (defmacro make-delegate
+  "Creates a delegate that may be a Func<...>, Action<...>, or Action based on
+  typeargs and args. A Func<...> is created if there is one more typearg than
+  arg. An Action is created if there are no typeargs or args."
     [typeargs args f]
     (cond
      (some #{'&} args)                       (throw
@@ -113,19 +118,25 @@
                  (str "Typeargs and args must be equal length or typeargs may have "
                       "one more element at the end to represent its return type.")))))

-(defmacro separate-types [f args]
+(defmacro separate-types
+  "Given a function signature with type annotations do the following:
+
+  (separate-types ^Int64 do-it [^String a ^Object b c])
+    -> {:typeargs [String Object nil] :typeresult Int64}"
+  [f args]
           `{:typeargs (->> '~args
                            (mapv meta)
                            (mapv :tag))
           :typeresult (:tag (meta '~f))})

-;; (defmacro separate-types-oldform [f args]
-;;           `(let [{:keys [typeargs# typeresult#]} (separate-types ~f ~args)]
-;;                 (if typeresult#
-;;                     (conj typeargs# typeresult#)
-;;                   typeargs#)))
-
-(defmacro separate-types-oldform [f args]
+(defmacro separate-types-oldform
+  "Given a function signature with type annotations do the following:
+
+  (separate-types ^Int64 do-it [^String a ^Object b c])
+    -> [String Object nil Int64]
+
+  This is suitable for input into the macro make-delegate."
+  [f args]
           `(let [h# (separate-types ~f ~args)]
                 (if (:typeresult h#)
                     (conj (:typeargs h#) (:typeresult h#))
@@ -174,7 +185,7 @@
                                nil)))
                       (eval `(make-delegate ~typeargs ~args ~f))))))

-(defmacro defcmd2
+(defmacro defcmd
     "Define a Minibuffer command and function. The docstring is required.
   The typeargs define what C# types the function accepts and optionally what it
   returns. Minibuffer makes extensive use of the type information. Consider the
@@ -207,8 +218,8 @@

 (defn message
   "Print a message to the echo area."
-  [& strings] ;; or concatenate or format?
-  (let [msg (apply str strings)]
+  [& strings]
+  (let [msg (apply str strings)] ; or concatenate or format?
        (with-minibuffer m
                         (.Message m msg))
        msg))
@@ -216,7 +227,11 @@
 ;; Thanks, Joseph (@selfsame), for the repl environment tip!
 (def repl-env (atom (arcadia.repl/env-map)))

-(defn repl-eval-print-string [s]
+(defn repl-eval-print-string
+  "This repl is used by the eval-expression command.
+
+  (def result-string (repl-eval-print-string \"(+ 1 2)\"))"
+  [s]
   (let [{:keys [result env]} (arcadia.repl/repl-eval-print repl-env s)]
        (reset! repl-env env)
        result))


sc/URI doesn't allow diacritical characters in URIs

--- src/db_quiz_prep/core.clj
+++ src/db_quiz_prep/core.clj
@@ -20,7 +20,7 @@
                      :page-size positive-number}
    :data {:selector {:p sc/URI
                      :o s/Str}
-          :surface-forms [sc/URI]
+          :surface-forms [s/Str]
           :source-graph sc/URI
           :target-graph sc/URI}
    :split-angles {:easy degree


Minor variable name changes.

Minor variable name changes.

--- src/vault/data/format/edn.clj
+++ src/vault/data/format/edn.clj
@@ -41,10 +41,10 @@
   "Determines the 'type' of the given value. By default, the result is just the
   class of the value. For maps, the :vault.data/type key is used if present.
   This is the main way types are represented in the data layer."
-  [v]
-  (or (when (map? v)
-        (:vault.data/type v))
-      (class v)))
+  [value]
+  (or (when (map? value)
+        (:vault.data/type value))
+      (class value)))

@@ -155,9 +155,9 @@
   "Reads the first few bytes from a blob's content to determine whether it is a
   data blob. The result is true if the header matches, otherwise false."
   [^bytes content]
-  (let [magic-bytes (.getBytes blob-header blob-charset)
-        magic-len (count magic-bytes)]
-    (= (seq magic-bytes) (take magic-len (seq content)))))
+  (let [header (.getBytes blob-header blob-charset)
+        len (count header)]
+    (= (seq header) (take len (seq content)))))

 (defn- read-primary-value!


cljs tests in core-test

cljs tests in core-test

--- test/deferst/core_test.cljc
+++ test/deferst/core_test.cljc
@@ -5,6 +5,7 @@
       :clj [clojure.test :as t
             :refer [deftest is are testing use-fixtures]])

+   #?(:cljs [promesa.core :as p])
    #?(:cljs [deferst.system-test])

    [clojure.set :as set]
@@ -20,31 +21,71 @@
       (let [sysmap (d/start! sys)
             x-sysmap {:foo 10 :a {:a-arg 10}}]
         #?(:clj
-           (is (= @sysmap x-sysmap)))))
+           (is (= @sysmap x-sysmap))
+
+           :cljs
+           (t/async
+            done
+            (p/then
+             sysmap
+             (fn [v] (is (= v x-sysmap))
+               (done)))))))

     (testing "simple system returns system map"
       (let [sysmap (d/system-map sys)
             x-sysmap {:foo 10 :a {:a-arg 10}}]
         #?(:clj
-           (is (= @sysmap x-sysmap)))))
+           (is (= @sysmap x-sysmap))
+
+           :cljs
+           (t/async
+            done
+            (p/then
+             sysmap
+             (fn [v] (is (= v x-sysmap))
+               (done)))))))

     (testing "start! returns same system map if already started"
       (let [sysmap (d/start! sys {:foo 20})
             x-sysmap {:foo 10 :a {:a-arg 10}}]
         #?(:clj
-           (is (= @sysmap x-sysmap)))))
+           (is (= @sysmap x-sysmap))
+
+           :cljs
+           (t/async
+            done
+            (p/then
+             sysmap
+             (fn [v] (is (= v x-sysmap))
+               (done)))))))

     (testing "simple system stops and returns a promise of the config"
       (let [stop-sys (d/stop! sys)
             x-stopmap {:foo 10}]
         #?(:clj
-           (is (= @stop-sys x-stopmap)))))
+           (is (= @stop-sys x-stopmap))
+
+           :cljs
+           (t/async
+            done
+            (p/then
+             stop-sys
+             (fn [v] (is (= v x-stopmap))
+               (done)))))))

     (testing "start! returns new system map when restarted"
       (let [sysmap (d/start! sys {:foo 20})
             x-sysmap {:foo 20 :a {:a-arg 20}}]
         #?(:clj
-           (is (= @sysmap x-sysmap)))))))
+           (is (= @sysmap x-sysmap))
+
+           :cljs
+           (t/async
+            done
+            (p/then
+             sysmap
+             (fn [v] (is (= v x-sysmap))
+               (done)))))))))

 ;; --- Entry Point


Use cl-format for hex

Use cl-format for hex

--- src/advent_2017/day_10.cljc
+++ src/advent_2017/day_10.cljc
@@ -1,6 +1,7 @@
 (ns advent-2017.day-10
   (:require
-   [clojure.string :as str]))
+   [clojure.string :as str]
+   [clojure.pprint :refer [cl-format]]))

 (def data [129,154,49,198,200,133,97,254,41,6,2,1,255,0,191,108])

@@ -24,10 +25,6 @@
 (defn xs->ascii [xs]
   (->> xs (str/join ",") (mapv #?(:clj int :cljs #(.charCodeAt % 0)))))

-(defn hex [n]
-  (let [nybble (fn [n] (nth "0123456789abcdef" n))]
-    (str (nybble (bit-and (bit-shift-right n 4) 0xF)) (nybble (bit-and n 0xF)))))
-
 (defn part-2 []
   (->> [(range 256) 0 0]
     (iterate (partial round (into (xs->ascii data) [17, 31, 73, 47, 23])))
@@ -35,5 +32,5 @@
     ffirst
     (partition 16)
     (map #(reduce bit-xor %))
-    (map hex)
+    (map #(cl-format nil "~2,'0x" %))
     (apply str)))


do less work when the output updates

do less work when the output updates

--- frontend/components/build_steps.cljs
+++ frontend/components/build_steps.cljs
@@ -32,10 +32,19 @@
   (reify
     om/IRender
     (render [_]
-      (html
-       [:span.pre {:dangerouslySetInnerHTML
-                   (clj->js {"__html"
-                             (:converted-message out)})}]))))
+      (let [message-html (:converted-message out)]
+        (html
+         [:span.pre {:dangerouslySetInnerHTML
+                     #js {"__html" message-html}}])))))
+
+(defn trailing-output [converters-state owner opts]
+  (reify
+    om/IRender
+    (render [_]
+      (let [trailing-out (action-model/trailing-output converters-state)]
+        (html
+         [:span {:dangerouslySetInnerHTML
+                 #js {"__html" trailing-out}}])))))

 (defn action [action owner opts]
   (reify
@@ -107,8 +116,9 @@
                        [:span.truncated "(this output has been truncated)"])
                      (om/build-all output (:output action) {:opts opts
                                                             :key :time})
-                     [:span {:dangerouslySetInnerHTML
-                             (clj->js {"__html" (action-model/trailing-output action)})}]
+
+                     (om/build trailing-output (:converters-state action) {:opts opts})
+
                      (when (:truncated action)
                        [:span.truncated "(this output has been truncated)"])]])])]]]]])))))


working build page autoscroll

working build page autoscroll

--- frontend/components/build_steps.cljs
+++ frontend/components/build_steps.cljs
@@ -8,11 +8,14 @@
             [frontend.components.common :as common]
             [frontend.utils :as utils :include-macros true]
             [om.core :as om :include-macros true]
+            [goog.events]
             [goog.string :as gstring]
+            goog.dom
             goog.string.format
             goog.fx.dom.Scroll
             goog.fx.easing)
-  (:require-macros [frontend.utils :refer [html]]))
+  (:require-macros [frontend.utils :refer [html]]
+                   [dommy.macros :refer [sel1]]))

 (defn source-type [source]
   (condp = source
@@ -142,6 +145,32 @@

 (defn container-build-steps [{:keys [containers current-container-id]} owner]
   (reify
+    om/IInitState
+    (init-state [_]
+      {:autoscroll? true})
+    om/IDidMount
+    (did-mount [_]
+      (let [container (om/get-node owner)
+            ;; autoscroll when the container_parent's tail-end is showing
+            scroll-listener #(let [new-autoscroll? (> (.-innerHeight js/window)
+                                                      (.-bottom (.getBoundingClientRect container)))]
+                               (when (not= new-autoscroll? (om/get-state owner [:autoscroll?]))
+                                 (om/set-state! owner [:autoscroll?] new-autoscroll?)))]
+        (om/set-state! owner [:scroll-listener-key] (goog.events/listen
+                                                     (sel1 "main.app-main")
+                                                     "scroll"
+                                                     scroll-listener))
+        ;; call it initially to set things up
+        (scroll-listener)))
+    om/IWillUnmount
+    (will-unmount [_]
+      (goog.events/unlistenByKey (om/get-state owner [:scroll-listener-key])))
+    om/IDidUpdate
+    (did-update [_ _ _]
+      (when (om/get-state owner [:autoscroll?])
+        (let [main (sel1 "main.app-main")
+              very-large-numer 10000000]
+          (set! (.-scrollTop main) very-large-numer))))
     om/IRender
     (render [_]
       (let [non-parallel-actions (->> containers


Added licence and removed test stub from core_test.clj

--- test/clj_mrazik/core_test.clj
+++ test/clj_mrazik/core_test.clj
@@ -1,7 +1,16 @@
+;
+;  (C) Copyright 2016  Pavel Tisnovsky
+;
+;  All rights reserved. This program and the accompanying materials
+;  are made available under the terms of the Eclipse Public License v1.0
+;  which accompanies this distribution, and is available at
+;  http://www.eclipse.org/legal/epl-v10.html
+;
+;  Contributors:
+;      Pavel Tisnovsky
+;
+
 (ns clj-mrazik.core-test
   (:require [clojure.test :refer :all]
             [clj-mrazik.core :refer :all]))

-(deftest a-test
-  (testing "FIXME, I fail."
-    (is (= 0 1))))


minor test change

minor test change

--- test/kbilling/plans_test.cljs
+++ test/kbilling/plans_test.cljs
@@ -6,7 +6,7 @@

 (deftest load-plan
-         (is (= '("cycles" "values" "notifications")
+         (is (= ["cycles" "values" "notifications"]
                 (keys (p/load-plan "test/kbilling/plans/examples/basic"))))
          (is (= ["monthly"]
                 (get-in (p/load-plan "test/kbilling/plans/examples/basic") ["cycles" "$subscription" "$begin"]))))


fixed whitespace

fixed whitespace

--- test/mirthsync/cli_test.clj
+++ test/mirthsync/cli_test.clj
@@ -56,10 +56,3 @@
     (is (nil? (:force (config ["pull"]))))))

-
-
-
-
-
-
-


Accomodate change in cljs with-core-cljs fn signature in cljs commit 80ea15e

--- lein-light-nrepl/src/lighttable/nrepl/cljs.clj
+++ lein-light-nrepl/src/lighttable/nrepl/cljs.clj
@@ -470,6 +470,7 @@
           (when pos
             (core/respond msg :editor.eval.cljs.location (clojure.core/meta (first forms))))
           (with-compiler-env compiler-env
+            nil
             (comp/with-core-cljs
              (if-not (first forms)
                (core/respond msg :editor.eval.cljs.no-op {})


Fix gset test.

Fix gset test.

--- test/replikativ/gset_test.clj
+++ test/replikativ/gset_test.clj
@@ -2,7 +2,7 @@
   (:require [clojure.test :refer :all]
             [replikativ.peer :refer [server-peer]]
             [konserve.memory :refer [new-mem-store]]
-            [kabel.platform :refer [create-http-kit-handler! start stop]]
+            [kabel.http-kit :refer [start stop]]
             [replikativ.environ :refer [*date-fn* store-blob-trans-value]]
             [replikativ.stage :refer [create-stage! connect! subscribe-crdts!]]
             [replikativ.p2p.fetch :refer [fetch]]
@@ -23,7 +23,7 @@
                                             :author user-mail}})))
           peer (<?? (server-peer store "ws://127.0.0.1:9090"
                                  :id "PEER A"
-                                 :middleware (comp (partial fetch store) ensure-hash)))
+                                 :middleware (comp fetch ensure-hash)))
           _ (start peer)
           stage (<?? (create-stage! "mail:a@mail.com" peer))
           _ (<?? (gs/create-simple-gset! stage :user user-mail :description "some Set" :public false))


Update fixtures.clj

Update fixtures.clj

--- test/swagger_gen/fixtures.clj
+++ test/swagger_gen/fixtures.clj
@@ -8,8 +8,7 @@
   {:description "a list of forex rates"
    :required ["rates"]
    :name "Rates"
-   :properties {:rates {:type "array",
-                        :items {:$ref "#/definitions/Rate"}}}})
+   :properties {:rates {:type "array" :items {:$ref "#/definitions/Rate"}}}})

 (def definition-with-array
   {:description "Something"
@@ -21,8 +20,7 @@
   {:description "a list of forex rates"
    :required ["rates"]
    :name "Rates"
-   :properties {:rates {:type "array",
-                        :items {:type "string"}}}})
+   :properties {:rates {:type "array" :items {:type "string"}}}})

 (def error-definition
   {:required ["code" "message"],
@@ -32,8 +30,7 @@

 (def error-definition-with-optional-params
   {:required [],
-   :properties {:code    {:type "integer"},
-                :message {:type "string"}},
+   :properties {:code {:type "integer"} :message {:type "string"}}
    :name "Error"})

 (def simple-route


Test also composure

Test also composure

--- perf-test/clj/reitit/opensensors_routing_test.clj
+++ perf-test/clj/reitit/opensensors_routing_test.clj
@@ -5,13 +5,14 @@
             [cheshire.core :as json]
             [clojure.string :as str]
             [reitit.core :as reitit]
-            [reitit.core :as ring]
+            [reitit.ring :as ring]

             [bidi.bidi :as bidi]

             [ataraxy.core :as ataraxy]

             [compojure.api.sweet :refer [api routes context ANY]]
+            [compojure.core :as compojure]

             [io.pedestal.http.route.definition.table :as table]
             [io.pedestal.http.route.map-tree :as map-tree]
@@ -277,6 +278,82 @@
               "schemas" [:test/route44]
               ["topics/" topic] [:test/route47 topic]
               "topics" [:test/route50]}}))
+
+(def opensensors-compojure-routes
+  (compojure/routes
+    (compojure/context "/v1" []
+      (compojure/context "/public" []
+        (compojure/ANY "/topics/:topic" [] {:name :test/route4} handler)
+        (compojure/ANY "/users/:user-id" [] {:name :test/route16} handler)
+        (compojure/ANY "/orgs/:org-id" [] {:name :test/route18} handler))
+      (compojure/context "/users/:user-id" []
+        (compojure/ANY "/orgs/:org-id" [] {:name :test/route5} handler)
+        (compojure/ANY "/invitations" [] {:name :test/route7} handler)
+        (compojure/ANY "/topics" [] {:name :test/route9} handler)
+        (compojure/ANY "/bookmarks/followers" [] {:name :test/route10} handler)
+        (compojure/context "/devices" []
+          (compojure/ANY "/" [] {:name :test/route15} handler)
+          #_(compojure/ANY "/bulk" [] {:name :test/route21} handler)
+          (compojure/ANY "/:client-id" [] {:name :test/route35} handler)
+          (compojure/ANY "/:client-id/reset-password" [] {:name :test/route49} handler))
+        (compojure/ANY "/device-errors" [] {:name :test/route22} handler)
+        (compojure/ANY "/usage-stats" [] {:name :test/route24} handler)
+        (compojure/ANY "/claim-device/:client-id" [] {:name :test/route26} handler)
+        (compojure/ANY "/owned-orgs" [] {:name :test/route31} handler)
+        (compojure/ANY "/bookmark/:topic" [] {:name :test/route33} handler)
+        (compojure/ANY "/" [] {:name :test/route36} handler)
+        (compojure/ANY "/orgs" [] {:name :test/route52} handler)
+        (compojure/ANY "/api-key" [] {:name :test/route43} handler)
+        (compojure/ANY "/bookmarks" [] {:name :test/route56} handler))
+      (compojure/ANY "/search/topics/:term" [] {:name :test/route6} handler)
+      (compojure/context "/orgs" []
+        (compojure/ANY "/" [] {:name :test/route55} handler)
+        (compojure/context "/:org-id" []
+          (compojure/context "/devices" []
+            (compojure/ANY "/" [] {:name :test/route37} handler)
+            (compojure/ANY "/:device-id" [] {:name :test/route13} handler)
+            #_(compojure/ANY "/:batch/:type" [] {:name :test/route8} handler))
+          (compojure/ANY "/usage-stats" [] {:name :test/route12} handler)
+          (compojure/ANY "/invitations" [] {:name :test/route19} handler)
+          (compojure/context "/members" []
+            (compojure/ANY "/:user-id" [] {:name :test/route34} handler)
+            (compojure/ANY "/" [] {:name :test/route38} handler)
+            #_(compojure/ANY "/invitation-data/:user-id" [] {:name :test/route39} handler))
+          (compojure/ANY "/errors" [] {:name :test/route17} handler)
+          (compojure/ANY "/" [] {:name :test/route42} handler)
+          (compojure/ANY "/confirm-membership/:token" [] {:name :test/route46} handler)
+          (compojure/ANY "/topics" [] {:name :test/route57} handler)))
+      (compojure/context "/messages" []
+        (compojure/ANY "/user/:user-id" [] {:name :test/route14} handler)
+        (compojure/ANY "/device/:client-id" [] {:name :test/route30} handler)
+        (compojure/ANY "/topic/:topic" [] {:name :test/route48} handler))
+      (compojure/context "/topics" []
+        (compojure/ANY "/:topic" [] {:name :test/route32} handler)
+        (compojure/ANY "/" [] {:name :test/route54} handler))
+      (compojure/ANY "/whoami" [] {:name :test/route41} handler)
+      (compojure/ANY "/login" [] {:name :test/route51} handler))
+    (compojure/context "/v2" []
+      (compojure/ANY "/whoami" [] {:name :test/route1} handler)
+      (compojure/context "/users/:user-id" []
+        (compojure/ANY "/datasets" [] {:name :test/route2} handler)
+        (compojure/ANY "/devices" [] {:name :test/route25} handler)
+        (compojure/context "/topics" []
+          (compojure/ANY "/bulk" [] {:name :test/route29} handler)
+          (compojure/ANY "/" [] {:name :test/route54} handler))
+        (compojure/ANY "/" [] {:name :test/route45} handler))
+      (compojure/context "/public" []
+        (compojure/context "/projects/:project-id" []
+          (compojure/ANY "/datasets" [] {:name :test/route3} handler)
+          (compojure/ANY "/" [] {:name :test/route27} handler))
+        #_(compojure/ANY "/messages/dataset/bulk" [] {:name :test/route20} handler)
+        (compojure/ANY "/datasets/:dataset-id" [] {:name :test/route28} handler)
+        (compojure/ANY "/messages/dataset/:dataset-id" [] {:name :test/route53} handler))
+      (compojure/ANY "/datasets/:dataset-id" [] {:name :test/route11} handler)
+      (compojure/ANY "/login" [] {:name :test/route23} handler)
+      (compojure/ANY "/orgs/:org-id/topics" [] {:name :test/route40} handler)
+      (compojure/ANY "/schemas" [] {:name :test/route44} handler)
+      (compojure/ANY "/topics/:topic" [] {:name :test/route47} handler)
+      (compojure/ANY "/topics" [] {:name :test/route50} handler))))

 (def opensensors-compojure-api-routes
   (routes
@@ -490,25 +567,31 @@
                         #(app {:uri % :request-method :get}))
         bidi-f #(bidi/match-route opensensors-bidi-routes %)
         ataraxy-f #(ataraxy/matches opensensors-ataraxy-routes {:uri %})
+        compojure-f #(opensensors-compojure-routes {:uri % :request-method :get})
         compojure-api-f #(opensensors-compojure-api-routes {:uri % :request-method :get})
         pedestal-f #(pedestal/find-route opensensors-pedestal-routes {:path-info % :request-method :get})]

-    ;;  2538ns -> 2028ns
+    ;;  2538ns
+    ;;  2065ns
     (bench!! routes true "reitit" reitit-f)

-    ;;  2845ns -> 2299ns
+    ;;  2845ns
+    ;;  2316ns
     (bench!! routes true "reitit-ring" reitit-ring-f)

-    ;;  2737ns
+    ;;  2541ns
     (bench!! routes true "pedestal" pedestal-f)

-    ;;  9823ns
+    ;;  9462ns
     (bench!! routes true "compojure-api" compojure-api-f)

-    ;; 16716ns
+    ;; 11041ns
+    (bench!! routes true "compojure" compojure-f)
+
+    ;; 16820ns
     (bench!! routes true "bidi" bidi-f)

-    ;; 24467ns
+    ;; 24134ns
     (bench!! routes true "ataraxy" ataraxy-f)))

 (comment


physical-object => !speakable

physical-object => !speakable

--- src/babel/encyclopedia.cljc
+++ src/babel/encyclopedia.cljc
@@ -111,6 +111,8 @@
    {:physical-object
     false}           {:animate false
                       :consumable false}
+   {:physical-object
+    true}            {:speakable false}

    {:place true}     {:activity false
                       :consumable false


Styling tweaks, indentation etc

Styling tweaks, indentation etc

--- re-frame-todo/project.clj
+++ re-frame-todo/project.clj
@@ -18,36 +18,33 @@
   :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}

   :aliases {"dev" ["do" "clean"
-                        ["pdo" ["figwheel" "dev"]]]
+                   ["pdo" ["figwheel" "dev"]]]
             "build" ["do" "clean"
-                          ["cljsbuild" "once" "min"]]}
+                     ["cljsbuild" "once" "min"]]}

-  :profiles
-  {:dev
-   {:dependencies [[binaryage/devtools "0.9.4"]
-                   [figwheel-sidecar "0.5.13"]
-                   [com.cemerick/piggieback "0.2.2"]]
+  :profiles {:dev
+             {:dependencies [[binaryage/devtools "0.9.4"]
+                             [figwheel-sidecar "0.5.13"]
+                             [com.cemerick/piggieback "0.2.2"]]

-    :plugins      [[lein-figwheel "0.5.13"]
-                   [lein-pdo "0.1.1"]]}}
+              :plugins      [[lein-figwheel "0.5.13"]
+                             [lein-pdo "0.1.1"]]}}

-  :cljsbuild
-  {:builds
-   [{:id           "dev"
-     :source-paths ["src/cljs"]
-     :figwheel     {:on-jsload "re-frame-todo.core/mount-root"}
-     :compiler     {:main                 re-frame-todo.core
-                    :output-to            "resources/public/js/compiled/app.js"
-                    :output-dir           "resources/public/js/compiled/out"
-                    :asset-path           "js/compiled/out"
-                    :source-map-timestamp true
-                    :preloads             [devtools.preload]
-                    :external-config      {:devtools/config {:features-to-install :all}}}}
+  :cljsbuild {:builds [{:id           "dev"
+                        :source-paths ["src/cljs"]
+                        :figwheel     {:on-jsload "re-frame-todo.core/mount-root"}
+                        :compiler     {:main                 re-frame-todo.core
+                                       :output-to            "resources/public/js/compiled/app.js"
+                                       :output-dir           "resources/public/js/compiled/out"
+                                       :asset-path           "js/compiled/out"
+                                       :source-map-timestamp true
+                                       :preloads             [devtools.preload]
+                                       :external-config      {:devtools/config {:features-to-install :all}}}}

-    {:id           "min"
-     :source-paths ["src/cljs"]
-     :compiler     {:main            re-frame-todo.core
-                    :output-to       "resources/public/js/compiled/app.js"
-                    :optimizations   :advanced
-                    :closure-defines {goog.DEBUG false}
-                    :pretty-print    false}}]})
+                       {:id           "min"
+                        :source-paths ["src/cljs"]
+                        :compiler     {:main            re-frame-todo.core
+                                       :output-to       "resources/public/js/compiled/app.js"
+                                       :optimizations   :advanced
+                                       :closure-defines {goog.DEBUG false}
+                                       :pretty-print    false}}]})


[#408] Add migrations step

[#408] Add migrations step

--- backend/src/org/akvo/lumen/admin/add_tenant.clj
+++ backend/src/org/akvo/lumen/admin/add_tenant.clj
@@ -2,7 +2,14 @@
   (:require [clojure.java.jdbc :as jdbc]
             [clojure.string :as s]
             [environ.core :refer [env]]
-            [org.akvo.lumen.util :refer [squuid]]))
+            [org.akvo.lumen.util :refer [squuid]]
+            [ragtime.jdbc]
+            [ragtime.repl]))
+
+(defn migrate-tenant [db-uri]
+  (ragtime.repl/migrate
+   {:datastore db-uri
+    :migrations (ragtime.jdbc/load-resources "org/akvo/lumen/migrations/tenants")}))

 (defn -main [label title]
   (let [{pg-host :pghost
@@ -27,4 +34,5 @@
            tenant)
     (exec! "CREATE EXTENSION IF NOT EXISTS btree_gist WITH SCHEMA public;")
     (exec! "CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public;")
-    (jdbc/insert! db-uri :tenants {:db_uri tenant-db-uri :label label :title title})))
+    (jdbc/insert! db-uri :tenants {:db_uri tenant-db-uri :label label :title title})
+    (migrate-tenant tenant-db-uri)))


fixed log title and empty lines

fixed log title and empty lines

--- src/cljs/swarmpit/component/service/log.cljs
+++ src/cljs/swarmpit/component/service/log.cljs
@@ -135,7 +135,9 @@
                     (do (swap! last-glow inc)
                         "log-body Swarmpit-log-fresh")
                     "log-body")}
-    (str (:line item))]])
+    (if (empty? (:line item))
+      (str " ")
+      (str (:line item)))]])

 (rum/defc form-history < rum/reactive [history id taskId]
   (let [anchorEl (state/react (conj form-state-cursor :historyAnchorEl))]
@@ -300,8 +302,8 @@
              :color   "inherit"
              :noWrap  true}
             (if taskId
-              taskId
-              (str serviceId "." taskId)))
+              (str serviceId "." (subs taskId 0 5))
+              serviceId))
           (html [:div.grow])
           (comp/box
             {:className "Swarmpit-appbar-section-desktop"}


Integrating the suggestion of the mentor for the Armstrong Numbers on exercism.io

--- exercism/clojure/armstrong-numbers/src/armstrong_numbers.clj
+++ exercism/clojure/armstrong-numbers/src/armstrong_numbers.clj
@@ -5,13 +5,10 @@
   (count (str num)))

 (defn number-to-digits-list [num]
-  (map #(Integer/parseInt %) (map str (seq (str num)))))
-
-(defn my-expt [exponent num]
-  (math/expt num exponent))
+  (map #(Integer/parseInt (str %)) (seq (str num))))

 (defn exponentiate-all-digits [exponent num]
-  (reduce + (map (partial my-expt exponent) (number-to-digits-list num))))
+  (apply + (map #(math/expt % exponent) (number-to-digits-list num))))

 (defn armstrong? [num] ;; <- arglist goes here
   (= num (exponentiate-all-digits (count-number-of-digits num) num)))


Use Langohr 1.5.0

Use Langohr 1.5.0

--- clojure/project.clj
+++ clojure/project.clj
@@ -4,4 +4,4 @@
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure     "1.5.1"]
-                 [com.novemberain/langohr "1.4.1"]])
+                 [com.novemberain/langohr "1.5.0"]])


Macro: Fix small & large being the wrong way around.

--- test/com/nomistech/clojure_the_language/macros/examples.clj
+++ test/com/nomistech/clojure_the_language/macros/examples.clj
@@ -29,16 +29,16 @@
 (fact
   (let [x 99]
     (if-not (> x 100)
-      (do (println "It's large") :large)
-      (do (println "It's small") :small)))
-  => :large)
+      (do (println "x is small") :small)
+      (do (println "x is large") :large)))
+  => :small)

 (fact
   (let [x 101]
     (if-not (> x 100)
-      (do (println "It's large") :large)
-      (do (println "It's small") :small)))
-  => :small)
+      (do (println "x is small") :small)
+      (do (println "x is large") :large)))
+  => :large)

 ;;;; ___________________________________________________________________________
 ;;;; Defining a simple macro.
@@ -52,20 +52,20 @@
 (fact
   (let [x 99]
     (our-if-not-1 (> x 100)
-                  (do (println "It's large") :large)
-                  (do (println "It's small") :small)))
-  => :large)
+                  (do (println "x is small") :small)
+                  (do (println "x is large") :large)))
+  => :small)

 ;;;; What's happening?
 ;;;; - Before compilation, macro calls are replaced with their macro expansion.

 (fact "Let's look at macroexpansion"
   (macroexpand-1 '(our-if-not-1 (> x 100)
-                                (do (println "It's large") :large)
-                                (do (println "It's small") :small)))
+                                (do (println "x is small") :small)
+                                (do (println "x is large") :large)))
   => '(if (> x 100)
-        (do (println "It's small") :small)
-        (do (println "It's large") :large)))
+        (do (println "x is large") :large)
+        (do (println "x is small") :small)))

 ;;;; Why would you use this?

@@ -124,17 +124,17 @@
 (fact
   (let [x 99]
     (our-if-not-2 (> x 100)
-                  (do (println "It's large") :large)
-                  (do (println "It's small") :small)))
-  => :large)
+                  (do (println "x is small") :small)
+                  (do (println "x is large") :large)))
+  => :small)

 (fact "`our-if-not-2` macroexpands identically to `our-if-not-1`"
   (macroexpand-1 '(our-if-not-2 (> x 100)
-                                (do (println "It's large") :large)
-                                (do (println "It's small") :small)))
+                                (do (println "x is small") :small)
+                                (do (println "x is large") :large)))
   => '(if (> x 100)
-        (do (println "It's small") :small)
-        (do (println "It's large") :large)))
+        (do (println "x is large") :large)
+        (do (println "x is small") :small)))

 ;;;; Is this a good use of macros?
 ;;;; Yes, but...


add test that updated-at is added to notes

--- test/open_company/unit/resources/company/company_create.clj
+++ test/open_company/unit/resources/company/company_create.clj
@@ -79,6 +79,14 @@
         (= created-at (:created-at retrieved-company)) => true
         (= updated-at (:updated-at retrieved-company)) => true))

+    (facts "it adds timestamps to notes"
+      (let [co      (c/add-placeholder-sections (c/->company r/open r/coyote))
+            w-note  (assoc-in co [:growth :notes :body] "A Note")
+            company (c/create-company! co)
+            from-db (c/get-company (:slug r/open))]
+        (get-in from-db [:updated-at]) => (:updated-at company)
+        (get-in from-db [:growth :notes :updated-at]) => (:updated-at company)))
+
     (fact "it returns the pre-defined categories"
       (:categories (c/create-company! (c/->company r/open r/coyote))) => (contains common/category-names))


[lein] Use Ultra

[lein] Use Ultra

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -5,5 +5,6 @@
                   [lein-drip                         "0.1.1-SNAPSHOT"]
                   [com.jakemccrary/lein-test-refresh "0.3.4"]
                   [lein-pprint                       "1.1.1"]
-                  [cider/cider-nrepl                 "0.12.0"]]
+                  [cider/cider-nrepl                 "0.12.0"]
+                  [venantius/ultra                   "0.4.1"]]
         :signing {:gpg-key "E5B26621"}}}


Update lein dependencies

Update lein dependencies

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -1,9 +1,8 @@
-{:user {:plugins             [[refactor-nrepl "2.5.0"]
-                              [cider/cider-nrepl "0.25.4"]
-                              [com.billpiel/sayid "0.0.17"]
-                              [lein-kibit "0.1.6"]
-                              [s3-wagon-private "1.3.1" :upgrade false]
-                              [lein-ancient "0.6.15"]]
+{:user {:plugins             [[refactor-nrepl "2.5.1"]
+                              [cider/cider-nrepl "0.25.11"]
+                              [com.billpiel/sayid "0.1.0"]
+                              [s3-wagon-private "1.3.4" :upgrade false]
+                              [lein-ancient "1.0.0-RC3"]]
         :injections          [(require 'nu)]
         :repositories        [["central"  {:url "https://repo1.maven.org/maven2/"
                                            :snapshots false}]
@@ -11,15 +10,10 @@
                               ["nu-maven" {:url "s3p://nu-maven/releases/"
                                            :region "sa-east-1"}]]
         :plugin-repositories [["nu-maven" {:url "s3p://nu-maven/releases/"}]]
-        :dependencies        [[cljdev "0.8.0"]]}
-
- :pretty {:plugins      [[io.aviso/pretty "0.1.37"]]
-          :dependencies [[io.aviso/pretty "0.1.37"]]
-          :middleware   [io.aviso.lein-pretty/inject]}
-
- :repl {:plugins      [[cider/cider-nrepl "0.25.4"]
-                       [refactor-nrepl "2.5.0"]]
-        :dependencies [[nrepl "0.8.2"]
+        :dependencies        [[cljdev "0.10.0"]]}
+ :repl {:plugins      [[cider/cider-nrepl "0.25.11"]
+                       [refactor-nrepl "2.5.1"]]
+        :dependencies [[nrepl "0.8.3"]
                        [mvxcvi/puget "1.3.1"]]
         :repl-options {:timeout 120000}}}


Add docstrings

Add docstrings

--- src/caesium/crypto/hash.clj
+++ src/caesium/crypto/hash.clj
@@ -4,20 +4,38 @@
 (defconsts [sha256-bytes sha512-bytes])

 (defn sha256-to-buf!
+  "Hashes a message with optional key into a given output buffer using
+  SHA-256.
+
+  You only want this to manage the output byte array yourself. Otherwise, you
+  want [[sha256]]."
   [buf msg]
   (.crypto_hash_sha256 sodium buf msg (alength ^bytes msg)))

 (defn sha256
+  "Computes the SHA-256 hash of message in the given byte array.
+
+  This is higher-level than [[sha256-to-buf!]] because you don't have to
+  allocate your own output buffer."
   [msg]
   (let [buf (byte-array sha256-bytes)]
     (sha256-to-buf! buf msg)
     buf))

 (defn sha512-to-buf!
+  "Hashes a message with optional key into a given output buffer using
+  SHA-512.
+
+  You only want this to manage the output byte array yourself. Otherwise, you
+  want [[sha512]]."
   [buf msg]
   (.crypto_hash_sha512 sodium buf msg (alength ^bytes msg)))

 (defn sha512
+  "Computes the SHA-512 hash of message in the given byte array.
+
+  This is higher-level than [[sha512-to-buf!]] because you don't have to
+  allocate your own output buffer."
   [msg]
   (let [buf (byte-array sha512-bytes)]
     (sha512-to-buf! buf msg)


redirect after oauth

redirect after oauth

--- src/chat/server/handler.clj
+++ src/chat/server/handler.clj
@@ -90,7 +90,10 @@
       (let [{ext-id :extension-id} (-> state b64->str edn/read-string)
             ext (db/with-conn (db/extension-by-id ext-id))]
         (if ext
-          (ext/handle-oauth-token ext state code)
+          (do (ext/handle-oauth-token ext state code)
+              {:status 302
+               :headers {"Location" (str "/" (ext :group-id))}
+               :body ""})
           {:status 400 :body "No such extension"})))
     (POST "/webhook/:ext" [ext :as req]
       (if-let [ext (db/with-conn (db/extension-by-id (java.util.UUID/fromString ext)))]


Add http/patch

Add http/patch

--- src/cider_ci/utils/http.clj
+++ src/cider_ci/utils/http.clj
@@ -44,6 +44,23 @@
                :conn-timeout 1000 }
               params)))))

+; TODO dry-up
+(defn patch [url params]
+  (logging/debug post [url params])
+  (let [basic-auth (:basic_auth @conf)]
+    (with/logging
+      (logging/debug "http/patch" {:url url :basic-auth basic-auth})
+      (http-client/patch
+        url
+        (conj {:basic-auth [(:user basic-auth) (:secret basic-auth)]
+               :insecure? true
+               :content-type :json
+               :accept :json
+               :socket-timeout 1000
+               :conn-timeout 1000 }
+              params)))))
+
+

 (defn initialize [new-conf]


Add with/catch-and-fail-state

Add with/catch-and-fail-state

--- src/cider_ci/utils/with.clj
+++ src/cider_ci/utils/with.clj
@@ -47,5 +47,27 @@
      res#))

+(defmacro catch-and-fail-state
+  "Takes as the first argument the state-container, a hash wrapped inside
+  an atom. Executes the body and catches any exception thrown therein.
+  In the latter case, sets the :state property of the state-container
+  to \"failed\" and also populates the :error and :errors property.
+  Returns the state-container."
+  [state-container & body]
+  `(try
+     ~@body
+     (catch Exception e#
+       (let [error-msg# (exception/stringify e#)
+             swap-fun# (fn [curr#]
+                         (conj curr# {:state "failed",
+                                      :error error-msg#
+                                      :errors (conj (or (:errors curr#) [])
+                                                    error-msg#)}))]
+         (clj-logging/error error-msg#)
+         (swap! ~state-container swap-fun#)))
+     (finally ~state-container)))
+
+
+;(catch-and-fail-state (atom {}) (throw (IllegalStateException. "Blah")))
 ;(macroexpand-1 '(log-debug-result(+ 1 2)))


So you want a user-agent now, do you?

So you want a user-agent now, do you?

--- src/mars_ogler/scrape.clj
+++ src/mars_ogler/scrape.clj
@@ -110,7 +110,8 @@
   [i]
   (let [page (:body (http/post
                       "http://curiositymsl.com/localphp/loadmore.php"
-                      {:headers {"Cookie" "PHPSESSID=3v55ibi7c0l25836c2chenpmo1"
+                      {:headers {"Cookie" "PHPSESSID=3v55ibi7c0l25836c2chenpmo1;"
+                                 "User-Agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13 (KHTML, like Gecko) Chrome/24.0.1290.1 Safari/537.13"
                                  "X-Requested-With" "XMLHttpRequest"}
                        :form-params {:q "", :z "UTC", :s "etreleased",
                                      :l "all" :o "desc", :n 100


Remove unused spec

Remove unused spec

--- src/clj/libx/spec/lang.cljc
+++ src/clj/libx/spec/lang.cljc
@@ -54,9 +54,3 @@
   (s/or :tuple-2 ::tuple-2
         :tuple-3 ::tuple-3
         :tuple-4 ::tuple-4))
-
-(s/def :db/change
-  (s/tuple
-    (s/and some? #(not (s/valid? ::s-expr %)))
-    #{:db/change}
-    ::tuple))


Temporary comment ducksboard module code for properly ubjerjar creation.

--- src/clj/pfrt/ducksboard.clj
+++ src/clj/pfrt/ducksboard.clj
@@ -1,59 +1,59 @@
-(ns pfrt.ducksboard
-  (:import java.net.InetAddress)
-  (:require [pfrt.packetfilter :as pf]
-            [pfrt.util :as util]
-            [clojure.pprint :refer [pprint]]
-            [clojure.data.json :as json]
-            [org.httpkit.client :as http])
-  (:gen-class))
-
-;; TODO: logging instead of prints?
-
-(def ^:dynamic *token*)
-(def ^:dynamic *sleep-time*)
-
-(defn ip->hostname
-  [^String ip]
-  (let [addr (InetAddress/getByName (name ip))]
-    (.getHostName addr)))
-
-(defn data->ducksboard
-  [data dir]
-  {:pre [(or (= dir :in) (= dir :out))]}
-  (let [units   (* 1024 1024)
-        entries (for [[ip ipdata] (seq data)]
-                  {:name (ip->hostname ip)
-                   :values [(dir ipdata)]})
-        sort-fn (fn [x] (-> x (:values) (get 0)))]
-    {:value {:board (take 10 (reverse (sort-by sort-fn entries)))}}))
-
-(defn do-ducksboard-update
-  []
-  (binding [*token*       (util/system-property "ducksboard.token")
-            *sleep-time*  (util/system-property "ducksboard.interval" "60000")]
-    (let [options {:basic-auth [*token* "unused"]}]
-      (loop []
-        (let [data      (deref pf/hosts-data)
-              data-in   (data->ducksboard data :in)
-              data-out  (data->ducksboard data :out)]
-
-          (util/sleep (Integer/parseInt *sleep-time*))
-
-          (if (nil? *token*)
-            (do
-              (println "Ducksboard token is not set, disabling service.")
-              (println :in (json/write-str data-in))
-              (println :out (json/write-str data-out)))
-
-            (do
-              (http/post "https://push.ducksboard.com/v/266990"
-                         (assoc options :body (json/write-str data-in)))
-              (http/post "https://push.ducksboard.com/v/268310"
-                         (assoc options :body (json/write-str data-out))))))
-        (recur)))))
-
-(defn start-ducksboard
-  []
-  (let [t (Thread. do-ducksboard-update)]
-    (.start t)
-    t))
+;; (ns pfrt.ducksboard
+;;   (:import java.net.InetAddress)
+;;   (:require [pfrt.packetfilter :as pf]
+;;             [pfrt.util :as util]
+;;             [clojure.pprint :refer [pprint]]
+;;             [clojure.data.json :as json]
+;;             [org.httpkit.client :as http])
+;;   (:gen-class))
+;;
+;; ;; TODO: logging instead of prints?
+;;
+;; (def ^:dynamic *token*)
+;; (def ^:dynamic *sleep-time*)
+;;
+;; (defn ip->hostname
+;;   [^String ip]
+;;   (let [addr (InetAddress/getByName (name ip))]
+;;     (.getHostName addr)))
+;;
+;; (defn data->ducksboard
+;;   [data dir]
+;;   {:pre [(or (= dir :in) (= dir :out))]}
+;;   (let [units   (* 1024 1024)
+;;         entries (for [[ip ipdata] (seq data)]
+;;                   {:name (ip->hostname ip)
+;;                    :values [(dir ipdata)]})
+;;         sort-fn (fn [x] (-> x (:values) (get 0)))]
+;;     {:value {:board (take 10 (reverse (sort-by sort-fn entries)))}}))
+;;
+;; (defn do-ducksboard-update
+;;   []
+;;   (binding [*token*       (util/system-property "ducksboard.token")
+;;             *sleep-time*  (util/system-property "ducksboard.interval" "60000")]
+;;     (let [options {:basic-auth [*token* "unused"]}]
+;;       (loop []
+;;         (let [data      (deref pf/hosts-data)
+;;               data-in   (data->ducksboard data :in)
+;;               data-out  (data->ducksboard data :out)]
+;;
+;;           (util/sleep (Integer/parseInt *sleep-time*))
+;;
+;;           (if (nil? *token*)
+;;             (do
+;;               (println "Ducksboard token is not set, disabling service.")
+;;               (println :in (json/write-str data-in))
+;;               (println :out (json/write-str data-out)))
+;;
+;;             (do
+;;               (http/post "https://push.ducksboard.com/v/266990"
+;;                          (assoc options :body (json/write-str data-in)))
+;;               (http/post "https://push.ducksboard.com/v/268310"
+;;                          (assoc options :body (json/write-str data-out))))))
+;;         (recur)))))
+;;
+;; (defn start-ducksboard
+;;   []
+;;   (let [t (Thread. do-ducksboard-update)]
+;;     (.start t)
+;;     t))


Small fix for a simple mistype

Small fix for a simple mistype

--- src/cljs/zetawar/views.cljs
+++ src/cljs/zetawar/views.cljs
@@ -347,7 +347,8 @@
                           armor-type-abbrev]

                          :unit-type.armor-type/naval
-                         [:abbr {:title "Naval" :style {:cursor "inherit"}}])]
+                         [:abbr {:title "Naval" :style {:cursor "inherit"}}
+                          armor-type-abbrev])]
                   [:td movement]
                   [:td (if can-capture
                          [:abbr {:title (str "While capturing: " capturing-armor)


oops, did not compile

oops, did not compile

--- src/clojento/magento/db.clj
+++ src/clojento/magento/db.clj
@@ -61,12 +61,6 @@
   [params]
   ())

-(defn run-query [db query-name params & {:keys [debug] :or {debug false}}]
-  (let [q (get (:queries db) query-name)
-        stmt (yq/sqlvec-raw (:split q) params)]
-    (log/info  "fetching " stmt)
-    (raw-jdbc-fetch db stmt :debug debug)))
-
 (defn raw-jdbc-execute [db stmt-or-sqlvec & {:keys [debug] :or {debug false}}]
   (with-open [conn (jdbc/connection (:datasource db))]
     (let [starttime (System/nanoTime)
@@ -87,4 +81,10 @@
                            :time (/ (- (System/nanoTime) starttime) 1e6)})
         result))))

-; TODO run_and_time_query
+; ------------------------------------------------------------------------------
+
+(defn run-query [db query-name params & {:keys [debug] :or {debug false}}]
+  (let [q (get (:queries db) query-name)
+        stmt (yq/sqlvec-raw (:split q) params)]
+    (log/info  "fetching " stmt)
+    (raw-jdbc-fetch db stmt :debug debug)))


drop `volatile!` in favor of `with-local-vars`

--- src/clojure/fudje/sweet.clj
+++ src/clojure/fudje/sweet.clj
@@ -182,13 +182,15 @@

 (defmacro tabular [fact-expr & body]
-  (let [arga (volatile! #{})
-        _ (clojure.walk/prewalk (fn [x]
-                                  (if (fudje.util/qmark? x)
-                                    (do (vswap! arga conj x) x)
-                                    x))
-                                fact-expr)
-        [args assertions] (split-at (count @arga) body)]
-    `(fudje.sweet/are* ~(vec args) ~fact-expr ~@assertions)))
+  (with-local-vars [arga #{}]
+    (clojure.walk/prewalk (fn [x]
+                            (if (fudje.util/qmark? x)
+                              (do (var-set arga (conj @arga x)) x)
+                              x))
+                          fact-expr)
+    (let [[args assertions] (split-at (count @arga) body)]
+      `(fudje.sweet/are* ~(vec args) ~fact-expr ~@assertions))
+    )
+  )


comment

comment

--- src/om_tutorial/core.cljs
+++ src/om_tutorial/core.cljs
@@ -78,9 +78,10 @@
 (defmulti read om/dispatch)

 (defmethod read :default
-  [{:keys [state] :as env} k _]
+  [{:keys [state query] :as env} k _]
   (let [db (d/db state)]                                    ;; CACHING!!!
-    (l/debug "read for default" k)
+    (l/debug "READ DEFAULT key" k)
+    (l/debug "READ DEFAULT query" query)
     (debug (keys env))
     ;(d/q '[:find [(pull ?e [*]) ...] :where [?e :type :type/content]] (d/db conn))

@@ -92,7 +93,7 @@
 (defmethod read :posts
   [{:keys [state query] :as env} k _]
   (let [db (d/db state)]                                    ;; CACHING!!!
-    (debug "read for" k)
+    (debug "READ :posts query" query)
     (debug "env keys " (keys env))

     (let [posts (d/q '[:find [(pull ?e ?query) ...] :in $ ?query :where [?e :content/type :blog/post]] (d/db conn) query)]


Changing to basic limiter for bus mixer.

The white-noise is good for debugging, but for everyday use it can be really
frustrating.  Maybe we can swap out different bus mixers depending on what type
of limiting we want to use?

--- src/overtone/sc/mixer.clj
+++ src/overtone/sc/mixer.clj
@@ -31,6 +31,18 @@
 (defonce __BUS-MIXERS__
   (do
     (defsynth out-bus-mixer [out-bus 0
+                             volume 0.5 master-volume @master-vol*
+                             safe-recovery-time 3]
+      (let [source    (in out-bus)
+            source    (* volume master-volume source)
+            not-safe? (trig1 (a2k (> source 1)) safe-recovery-time)
+            safe-snd  (limiter source 0.99 0.001)]
+        (send-reply not-safe?
+                    "/server-audio-clipping-rogue-vol"
+                    out-bus)
+        (replace-out out-bus safe-snd)))
+
+    (comment defsynth out-bus-mixer [out-bus 0
                              volume 0.5 master-volume @master-vol*
                              safe-recovery-time 3]
       (let [source    (in out-bus)


Improve ugen input arg checker exception string:

* Now explicitly reports when it didn't get a ugen rather than giving opaque error

--- src/overtone/sc/synth.clj
+++ src/overtone/sc/synth.clj
@@ -57,9 +57,12 @@
   ugens according to the arguments in the initial definition."
   [ugen ugens constants grouped-params]
   (when-not (contains? ugen :args)
-    (throw (IllegalArgumentException.
-             (format "The %s ugen does not have any arguments."
-                     (:name ugen)))))
+    (if-not (sc-ugen? ugen)
+      (throw (IllegalArgumentException.
+              (str "Error: synth expected a ugen. Got: " ugen)))
+      (throw (IllegalArgumentException.
+              (format "The %s ugen does not have any arguments."
+                      (:name ugen))))))
   (when-not (every? #(or (sc-ugen? %) (number? %) (string? %)) (:args ugen))
     (throw (IllegalArgumentException.
              (format "The %s ugen has an invalid argument: %s"


Select input text on focus

Select input text on focus

--- src/app/ctl.cljs
+++ src/app/ctl.cljs
@@ -39,7 +39,8 @@
                                nil)}])))

 (def title-edit (with-meta title-input
-                 {:component-did-mount #(.focus (reagent/dom-node %))}))
+                  {:component-did-mount #(do (.focus (reagent/dom-node %))
+                                             (.select (reagent/dom-node %)))}))

 (defn display? [visible?]
@@ -68,7 +69,7 @@

 (defn data-items [items channel]
   (let [items (reaction (:items @channel))] ;;items update but not on the screen for some reason
-    (fn []
+    (fn []
       [:ul
        (for [item @items]
          [data-item item channel])])))


remove usages of (dag_unify.core/merge)

remove usages of (dag_unify.core/merge)

--- src/babel/writer.clj
+++ src/babel/writer.clj
@@ -1,5 +1,5 @@
 (ns babel.writer
-  (:refer-clojure :exclude [get-in merge])
+  (:refer-clojure :exclude [get-in])
   (:require
     [babel.encyclopedia :refer [sem-impl]]
     [babel.engine :as engine]
@@ -9,7 +9,7 @@
     [clojure.string :as string]
     [clojure.tools.logging :as log]
     [clojure.tools.namespace.repl :refer [refresh refresh-all]]
-    [dag_unify.core :refer [fail? get-in merge remove-top-values strip-refs serialize unify ref?]]
+    [dag_unify.core :refer [fail? get-in remove-top-values strip-refs serialize unify ref?]]
     [korma.core :refer [exec-raw]]))

 ;; TODO: more fine-grained approach to dealing with exceptions:
@@ -59,7 +59,7 @@
         ;; for example, (defn fill-language-by-spec) is passed a _spec_ param which, depending on the language's
         ;; writer implementation (e.g. babel.italiano/writer searches based on :comp and :head).
         target-language-sentence (if (:morph-walk-tree target-language-model)
-                                   (merge ((:morph-walk-tree target-language-model) target-language-sentence)
+                                   (clojure.core/merge ((:morph-walk-tree target-language-model) target-language-sentence)
                                           target-language-sentence)
                                    (do (log/warn (str "there is no morph-walk-tree function for the model:"
                                                       (:name target-language-model) " of language: "
@@ -116,7 +116,7 @@
                                                   source-language-model :truncate-children false)

         source-language-sentence (if (:morph-walk-tree source-language-model)
-                                   (merge ((:morph-walk-tree source-language-model) source-language-sentence)
+                                   (clojure.core/merge ((:morph-walk-tree source-language-model) source-language-sentence)
                                           source-language-sentence)
                                    (do (log/warn (str "there is no morph-walk-tree function for the model:"
                                                       (:name source-language-model) " of language: "


Fixed variable length byte strings

Fixed variable length byte strings

--- src/binary/core.cljs
+++ src/binary/core.cljs
@@ -50,17 +50,16 @@

 (defn read-data [dv {:keys [length formatter le js-type], :or {formatter no-process}} index]
   (let [get-func (.bind (aget dv (:js-get js-type)) dv)
-        adjusted-index (/ index 8)
         {:keys [size process] :or {process identity}} js-type]

     [(* length size)
      (formatter
        (if (> length 1)
          (loop [pos 0 data []]
-           (if (= pos length)
+           (if (= (/ pos size) length)
              data
-             (recur (inc pos) (conj data (process
-                                           (get-func (/ (+ index pos) 8) le)
+             (recur (+ size pos) (conj data (process
+                                           (get-func (/ (+ pos index) 8) le)
                                            (+ index pos))))))
          (process (get-func (/ index 8) le) index)))]))


Add a shortened version of ext-dependencies.

--- src/cake/project.clj
+++ src/cake/project.clj
@@ -132,6 +132,7 @@
                :war-name     (or (:war-name opts) artifact-version)
                :uberjar-name (or (:uberjar-name opts) (str artifact-version "-standalone")))
         (assoc-or :dependencies (:deps opts))
+        (assoc-or :ext-depencencies (:dev-deps opts))
         (assoc-or :dev-dependencies (:dev-deps opts))
         (update :dependencies     dep-map)
         (update :ext-dependencies dep-map)


Moved (-main) into (print-status) fn

Moved (-main) into (print-status) fn

--- src/clj_git/core.clj
+++ src/clj_git/core.clj
@@ -7,7 +7,7 @@
   (:use clj-git.tree)
   (:gen-class))

-(defn -main [& args]
+(defn print-status []
   (let [modified (->>  (read-index)
                        (map :name)
                        (filter is-file-modified))
@@ -24,6 +24,8 @@
       (doseq [x staged]
         (println (str "  " x)))))
 ))
+
+(defn -main [& args] (print-status))

 ; Creates a new commit object (and all required tree objects)
 ; from the current index


Use `into` so axis helper will work until #12 is addressed.

--- src/cljx/c2/svg.cljx
+++ src/cljx/c2/svg.cljx
@@ -33,22 +33,21 @@
                        major-tick-width 6
                        text-margin 9}}]

-  (let [[x y x1 x2 y1 y2] (case orientation
-                            (:left :right) [:x :y :x1 :x2 :y1 :y2]
-                            (:top :bottom) [:y :x :y1 :y2 :x1 :x2])
+  (let [[x y x1 x2 y1 y2] (match [orientation]
+                                 [(:or :left :right)] [:x :y :x1 :x2 :y1 :y2]
+                                 [(:or :top :bottom)] [:y :x :y1 :y2 :x1 :x2])

-        parity (case orientation
-                 (:left :top) -1
-                 (:right :bottom) 1)]
+        parity (match [orientation]
+                      [(:or :left :top)] -1
+                      [(:or :right :bottom)] 1)]

-    [:g.axis {:class (name orientation)}
-     [:line.rule (apply hash-map (interleave [y1 y2] (:range scale)))]
-
-     (map (fn [d]
+    (into [:g.axis {:class (name orientation)}
+           [:line.rule (apply hash-map (interleave [y1 y2] (:range scale)))]]
+           (map (fn [d]
             [:g.major-tick {:transform (translate {x 0 y (scale d)})}
              [:text {x (* parity text-margin)} (formatter d)]
              [:line {x1 0 x2 (* parity major-tick-width)}]])
-          ticks)]))
+          ticks))))

 (def ArcMax (- Tau 0.0000001))


code formatting

code formatting

--- src/copper/core.cljs
+++ src/copper/core.cljs
@@ -224,18 +224,19 @@

 (defn component [renderer]
   (let [react-component
-        (.createClass js/React
-                      (specify! (react-fns renderer)
-                        INotify
-                        (-notify [this path]
-                           (.forceUpdate this))
-
-                        IPrintWithWriter
-                        (-pr-writer [this writer _]
-                           (-write writer
-                                   (pr-str "COMPONENT"
-                                           {:value (aget (.-props this) "value")
-                                            :statics (aget (.-props this) "statics")})))))]
+        (.createClass
+         js/React
+         (specify! (react-fns renderer)
+          INotify
+          (-notify [this path]
+                   (.forceUpdate this))
+
+          IPrintWithWriter
+          (-pr-writer [this writer _]
+             (-write writer
+                     (pr-str "CopperComponent"
+                             {:value (aget (.-props this) "value")
+                              :statics (aget (.-props this) "statics")})))))]
     (fn [value static-opts]
       (js/React.createElement react-component
                               #js {:value value :statics static-opts}))))


Spelling tweaks

Spelling tweaks

--- src/shuppet/scheduler.clj
+++ src/shuppet/scheduler.clj
@@ -40,14 +40,14 @@
    (let [pool (get-pool environment)]
      (at-at/stop-and-reset-pool! pool :strategy :kill)
      (if (= action "stop")
-       {:message "Succefully stopped the shuppet scheduler"}
+       {:message "Successfully stopped the shuppet scheduler"}
        (let [interval (Integer/parseInt (or interval (env/env :service-scheduler-interval)))]
          (at-at/every (* interval 60 1000)
                       #(configure-apps environment)
                       pool
                       :desc (rfc2616-time))
          {:message
-          (str "Succesfully started the shuppet scheduler. The scheduler will run in every "
+          (str "Successfully started the shuppet scheduler. The scheduler will run every "
                interval " minutes.") })))
    (catch Exception e
      (error (str-stacktrace e))


Improve Exercise 3.53 implementation

Improve Exercise 3.53 implementation

--- src/sicp/chapter3/5_2.clj
+++ src/sicp/chapter3/5_2.clj
@@ -5,7 +5,12 @@
 ;;; 3.5.2  Infinite Streams

 ;; Exercise 3.53
-(def s (lazy-seq (cons 1 (map + s s))))
+(defn add-streams [s1 s2]
+  (map + s1 s2))
+
+(def s (lazy-seq (cons 1 (add-streams s s))))
+
+#_(take 10 s)

 ;; Exercise 3.54
 (defn mul-streams [s1 s2]
@@ -15,3 +20,5 @@

 (def factorials
   (lazy-seq (cons 1 (mul-streams (rest integers) factorials))))
+
+#_(take 10 factorials)