Dont create new fact in deconstructor. Fix join ixes

--- src/aurora/language.cljs
+++ src/aurora/language.cljs
@@ -414,7 +414,10 @@
 ;; PATTERNS

 (defn pattern->vars [pattern]
-  (vec (distinct (filter symbol? (.-values pattern)))))
+  (vec (for [value (.-values pattern)]
+         (if (symbol? value)
+           value
+           '_))))

 (defn pattern->filter [pattern]
   `(pattern->filter* ~(.-shape pattern)))
@@ -445,11 +448,9 @@
       (Fact. shape sink (fact-hash sink)))))

 (defn pattern->deconstructor [pattern]
-  (let [shape (.-shape pattern)
-        seen? (atom {})
+  (let [seen? (atom {})
         constant-values #js []
         constant-ixes #js []
-        var-ixes #js []
         dup-value-ixes #js []
         dup-var-ixes #js []]
     (doseq [[value ix] (map vector (.-values pattern) (range))]
@@ -458,15 +459,13 @@
           (do
             (apush dup-value-ixes dup-value-ix)
             (apush dup-var-ixes ix))
-          (do
-            (apush var-ixes ix)
-            (swap! seen? assoc value ix)))
+          (swap! seen? assoc value ix))
         (do
           (apush constant-values value)
           (apush constant-ixes ix))))
-    `(pattern->deconstructor* ~constant-values ~constant-ixes ~var-ixes ~dup-value-ixes ~dup-var-ixes)))
-
-(defn pattern->deconstructor* [constant-values constant-ixes var-ixes dup-value-ixes dup-var-ixes]
+    `(pattern->deconstructor* ~constant-values ~constant-ixes ~dup-value-ixes ~dup-var-ixes)))
+
+(defn pattern->deconstructor* [constant-values constant-ixes dup-value-ixes dup-var-ixes]
   (fn [fact]
     (let [source (.-values fact)]
       (loop [i 0]
@@ -477,10 +476,7 @@
             (if (< i (alength dup-value-ixes))
               (when (= (aget source (aget dup-value-ixes i)) (aget source (aget dup-var-ixes i)))
                 (recur (+ i 1)))
-              (let [sink (make-array (alength var-ixes))]
-                (dotimes [i (alength var-ixes)]
-                  (aset sink i (aget source (aget var-ixes i))))
-                (Fact. nil sink (fact-hash sink))))))))))
+              fact)))))))

 ;; CLAUSES

@@ -502,17 +498,17 @@
              [plan [node] (pattern->vars pattern)])
     Compute (let [{:keys [pattern]} clause]
               (condp = (.-shape pattern)
-                Let (when (every? (set vars) (:vars pattern))
+                Let (when (every? (conj (set vars) '_) (:vars pattern))
                       (let [fun&args (if (contains? (set vars) (:name pattern))
                                        `(when-let->fun ~(ix-of vars (:name pattern)) ~vars ~(:expr pattern))
                                        `(let->fun ~vars ~(:expr pattern)))
                             [plan node] (add-flow plan (->FilterMap nodes fun&args))]
                         [plan [node] (conj vars (:name pattern))]))
-                When (when (every? (set vars) (:vars pattern))
+                When (when (every? (conj (set vars) '_) (:vars pattern))
                        (let [[plan node] (add-flow plan (->FilterMap nodes `(when->fun ~vars ~(:expr pattern))))]
                          [plan [node] vars]))))
     Output (let [{:keys [memory pattern]} clause
-                 _ (assert (every? (set vars) (pattern->vars pattern)))
+                 _ (assert (every? (conj (set vars) '_) (pattern->vars pattern)))
                  [plan output-node] (add-flow plan (FilterMap. nodes (pattern->constructor vars pattern)))
                  output-memory (case memory
                                  :pretended :known|pretended
@@ -541,10 +537,10 @@
       (recur @plan&nodes&vars computes-skipped))))

 (defn join-clauses [plan nodes-a vars-a nodes-b vars-b]
-  (let [key-vars (intersection (set vars-a) (set vars-b))
+  (let [key-vars (disj (intersection (set vars-a) (set vars-b)) '_)
         key-vars-a (sort-by #(ix-of vars-a %) key-vars)
         key-vars-b (sort-by #(ix-of vars-b %) key-vars)
-        val-vars (union (set vars-a) (set vars-b))
+        val-vars (disj (union (set vars-a) (set vars-b)) '_)
         index-ixes-a (ixes-of vars-a key-vars-a)
         index-ixes-b (ixes-of vars-b key-vars-b)
         lookup-ixes-a (ixes-of vars-a key-vars-b)
@@ -557,7 +553,7 @@
         [plan index-b'] (add-flow plan (->Index nodes-b index-ixes-b))
         _ (assert (= index-b index-b'))
         [plan lookup-b] (add-flow plan (->Lookup [index-b] index-a lookup-ixes-b val-ixes-b))]
-    [plan [lookup-a lookup-b] (vec (distinct (concat vars-a vars-b)))]))
+    [plan [lookup-a lookup-b] (map #(nth (concat vars-a vars-b) %) val-ixes-a)]))

 (defn add-rule [plan rule]
   (let [recalls (filter #(= Recall (type %)) (:clauses rule))
@@ -754,6 +750,24 @@
                                                          (->edge i (inc i)))))
     (fixpoint! state)
     (get-facts state :known|pretended connected))
+
+  (deffact return "[x] is connected to 2")
+
+  (let [plan (-> empty-flow-plan
+                 (add-shape :known edge)
+                 (add-shape :pretended connected)
+                 (add-shape :pretended return)
+                 (add-rules [(Rule. [(Recall. :known|pretended (->edge 'x 'y))
+                                     (Output. :pretended (->connected 'x 'y))])
+                             (Rule. [(Recall. :known|pretended (->edge 'x 'y))
+                                     (Recall. :known|pretended (->connected 'y 'z))
+                                     (Output. :pretended (->connected 'x 'z))])
+                             (Rule. [(Recall. :known|pretended (->connected 'x 2))
+                                     (Output. :pretended (->return 'x))])]))
+        state (flow-plan->flow-state plan)]
+    (add-facts state :known|pretended edge #js [(->edge 0 1) (->edge 1 2) (->edge 2 3) (->edge 3 1)])
+    (time (fixpoint! state))
+    (get-facts state :known|pretended return))
   )

 (comment


make it easier to turn semantic implicature on or off

--- src/babel/lexiconfn.cljc
+++ src/babel/lexiconfn.cljc
@@ -376,8 +376,13 @@
         true
         lexical-entry))

+(def do-semantic-implicature? true)
+
 (defn semantic-implicature [lexical-entry]
-  (if (= (get-in lexical-entry [:synsem :cat]) :noun)
+  (if (and
+       do-semantic-implicature?
+       (= (get-in lexical-entry [:synsem :cat]) :noun))
+
     ;; this rule is only necessary with nouns: other parts of speech can select nouns based on their
     ;; semantics derived via the nouns' use of this rule.
     {:synsem {:sem (sem-impl (get-in lexical-entry [:synsem :sem]))}}


restore printlns.

restore printlns.

--- src/metabase/metabot.clj
+++ src/metabase/metabot.clj
@@ -37,7 +37,7 @@
                           {(if (true? dispatch-token)
                              (keyword symb)
                              dispatch-token) varr}))]
-    (log/debug (u/format-color 'cyan verb) fn-map)
+    (println (u/format-color 'cyan verb) fn-map)
     (fn dispatch*
       ([]
        (keys-description (format "Here's what I can %s:" verb) fn-map))
@@ -164,7 +164,7 @@
     (when-let [tokens (seq (edn/read-string (str "(" (-> s
                                                          (str/replace "“" "\"") ; replace smart quotes
                                                          (str/replace "”" "\"")) ")")))]
-      (log/debug (u/format-color 'magenta tokens))
+      (println (u/format-color 'magenta tokens))
       (apply apply-metabot-fn tokens))))

@@ -173,14 +173,14 @@
 (defn- message->command-str [{:keys [text]}]
   (u/prog1 (when (seq text)
              (second (re-matches #"^mea?ta?boa?t\s+(.*)$" text)))
-    (log/debug (u/format-color 'yellow <>))))
+    (println (u/format-color 'yellow <>))))

 (defn- respond-to-message! [message response]
   (when response
     (let [response (if (coll? response) (str "```\n" (u/pprint-to-str response) "```")
                        (str response))]
       (when (seq response)
-        (log/debug (u/format-color 'green response))
+        (println (u/format-color 'green response))
         (slack/post-chat-message! (:channel message) response)))))

 (defn- handle-slack-message [message]
@@ -199,14 +199,14 @@

 (defn- handle-slack-event [socket start-time event]
   (when-not (= socket @websocket)
-    (log/debug "Go home websocket, you're drunk.")
+    (println "Go home websocket, you're drunk.")
     (s/close! socket)
     (throw (Exception.)))

   (when-let [event (json/parse-string event keyword)]
     (when (and (human-message? event)
                (> (event-timestamp-ms event) start-time))
-      (log/debug (u/pprint-to-str 'cyan event))
+      (println (u/pprint-to-str 'cyan event))
       (binding [*channel-id* (:channel event)]
         (do-async (handle-slack-message event))))))


thought that `format` was easier to read than a long `str` concatted string

--- src/midje/semi_sweet.clj
+++ src/midje/semi_sweet.clj
@@ -21,7 +21,6 @@
 (immigrate 'midje.unprocessed)
 (immigrate 'midje.ideas.arrow-symbols)

- ;;; Conversions to unprocessed form

 ;; I want to use resolve() to compare calls to fake, rather than the string
@@ -78,7 +77,6 @@
                               :description (midje.internal-ideas.fact-context/nested-fact-description)
                               :position (:position check#)}))))

- ;;; Interface: unfinished

 (letfn [(unfinished* [names]
@@ -86,12 +84,9 @@
             `(do
                (defn ~name [& args#]
                  (let [pprint# (partial cl-format nil "~S")]
-                   (throw (user-error (str "#'" '~name
-                                           " has no implementation, but it was called like this:"
-                                           line-separator
-                                           "(" '~name " "
-                                           (join " " (map pprint# args#))
-                                           ")")))))
+                   (throw (user-error (format "#'%s has no implementation, but it was called like this:%s(%s %s)"
+                                        '~name line-separator '~name (join " " (map pprint# args#)))))))
+
                ;; A reliable way of determining if an `unfinished` function has since been defined.
                (alter-meta! (var ~name) assoc :midje/unfinished-fun ~name))))]

@@ -109,7 +104,6 @@

- ;;; Interface: production mode

 (defonce
@@ -119,7 +113,6 @@
   *include-midje-checks* true)

- ;;; Interface: Main macros

 (defmacro fake


add has-nth

add has-nth

--- src/matcha.clj
+++ src/matcha.clj
@@ -22,7 +22,6 @@
 ;;  if pass? if false
 ;;
 ;;  TODO: matchers list
-;;  - has-nth
 ;;  - has-numerator
 ;;  - has denominator
 ;;  - decimal?
@@ -158,6 +157,18 @@
    :describe-mismatch
    (fn [x] (str (standard-describe-mismatch x) " with count " (count x)))})

+(defn has-nth
+  "passes if the sequence received has the value matching the matcher given at
+  (nth n)
+
+  (matcha/run-match (matcha/has-count 1) [1]) ; => passes
+  (matcha/run-match (matcha/has-count 2) [])  ; => fails"
+  [m n]
+  {:match (fn [xs] ((:match m) (nth xs n)))
+   :description (str "a collection with the nth value " (:description m))
+   :describe-mismatch
+   (fn [x] (str (standard-describe-mismatch x) " with nth value " ((:describe-mismatch m) (nth x n))))})
+
 (defn includes
   "passes if the sequence received includes the given item

@@ -183,7 +194,7 @@

 (defn describe-class-mismatch [x]
   (str "was " (pr-str x)
-       (if (nil? x)
+       (if (clojure.core/nil? x)
          ""
          (str " <" (class x) ">"))))


orbifoldInvariant3d.clj: computes the raw orbifold graph

--- clojure/org/gavrog/clojure/orbifoldInvariant3d.clj
+++ clojure/org/gavrog/clojure/orbifoldInvariant3d.clj
@@ -1,3 +1,37 @@
 (ns org.gavrog.clojure.orbifoldInvariant3d
   (:use (org.gavrog.clojure
-          delaney)))
+          delaney
+          delaney2d)))
+
+(defn- orbifold-type [ds idcs D]
+  (case (count idcs)
+    0 "1"
+    1 (if (= D (s ds (first idcs) D)) "1*" "1")
+    2 (let [[i j] idcs, n (v ds i j D)]
+        (if (orbit-loopless? ds idcs D) (str n) (str n "*")))
+    3 (orbifold-symbol (orbit ds idcs D))))
+
+(defn- sublists
+  ([i j k] [[i j] [i k] [j k]])
+  ([i j]   [[i] [j]])
+  ([i]     []))
+
+(defn- raw-orbifold-graph [ds]
+  (let [[i j k m] (indices ds)
+        index-combinations [[i] [j] [k] [m]
+                            [i j] [i k] [i m] [j k] [j m] [k m]
+                            [i j k] [i j m] [i k m] [j k m]]
+        to-rep (into {} (for [idcs index-combinations
+                              D (orbit-reps ds idcs)
+                              E (orbit-elements ds idcs D)]
+                          [[idcs E] [idcs D]]))
+        sub-orbits (fn [idcs D]
+                     (let [o (orbit ds idcs D)]
+                       (for [is (apply sublists idcs)
+                             D (orbit-reps o is)]
+                         (to-rep [is D]))))]
+    (into {} (for [idcs index-combinations
+                   D (orbit-reps ds idcs)]
+               [[idcs D] {:type (orbifold-type ds idcs D)
+                          :elms (orbit-elements ds idcs D) ;; for debugging
+                          :subs (sub-orbits idcs D)}]))))


Enabled command line switches for pcbo

Enabled command line switches for pcbo

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

--- src/conexp/contrib/algorithms/parallel_cbo.clj
+++ src/conexp/contrib/algorithms/parallel_cbo.clj
@@ -18,7 +18,7 @@
 ;;;

 (define-external-program pcbo
-  pcbo #_(-P :threads -L :depth -S :min-support) :input-file :fcalgs)
+  pcbo :threads :depth :min-support :input-file :fcalgs)
 (alter-meta! (var pcbo) assoc :private true)

 (defn- to-fcalgs-context
@@ -32,7 +32,7 @@
   [threads depth min-support context]
   (let [[ctx obj-vec att-vec] (to-fcalgs-context context)]
     (map #(read-string (str "#{" % "}"))
-         (split-lines (pcbo #_(threads depth min-support) ctx)))))
+         (split-lines (pcbo (str "-P" threads) (str "-L" depth) (str "-S" min-support) ctx)))))

 ;;;


Update generator.clj

Update generator.clj

--- src/swagger_gen/examples/scala/generator.clj
+++ src/swagger_gen/examples/scala/generator.clj
@@ -21,4 +21,4 @@
         (fn [spec]
           (merge additional-params
             (assoc spec :normalized-definitions
-            (map expand-model (:normalized-definitions spec)))))))))
+              (map expand-model (:normalized-definitions spec)))))))))


+(require fo-ps-en)

+(require fo-ps-en)

--- test/babel/test/en.cljc
+++ test/babel/test/en.cljc
@@ -4,7 +4,7 @@
             [babel.english :refer [analyze generate parse]]
             [babel.english.grammar :refer [small small-plus-plus-np small-plus-vp-pronoun medium]]
             [babel.english.lexicon :refer [lexicon]]
-            [babel.english.morphology :refer [fo get-string]]
+            [babel.english.morphology :refer [fo fo-ps-en get-string]]

             ;; TODO: add parsing tests
             [babel.parse :as parse]


+(def small)

+(def small)

--- test/babel/test/en.cljc
+++ test/babel/test/en.cljc
@@ -20,6 +20,7 @@
             [dag_unify.core :refer [fail? fail-path-between get-in strip-refs unifyc]]))

 (def medium (grammar/medium))
+(def small (grammar/small))

 (deftest generate-irregular-present-1
   (let [form {:english {:a {:cat :verb,


simplify debugging my moving reader-related variables out of test

--- test/babel/test/la.cljc
+++ test/babel/test/la.cljc
@@ -46,31 +46,49 @@
                               :tense :present}}}
               model)))))

-(deftest reader1
-  (let [source-language :en
+(def source-language :en)
+
+;; function to generate expression in target langage
+(def source-generate-fn (-> models source-language :generate-fn))
+
+;; function to render target expression as text. show-notes=false because
+;; we are translating from Latin which (at least for the purposes of this
+;; implemetation) lacks the same kind of gender differences that Italian, for
+;; example, has.
+(def source-format-fn #((-> models source-language :morph) % :show-notes false))
+
+(def target-language :la)

         ;; function to generate expression in target langage
-        source-generate-fn (-> models source-language :generate-fn)
+(def target-generate-fn (-> models target-language :generate-fn))

-        ;; function to render target expression as text. show-notes=false because
-        ;; we are translating from Latin which (at least for the purposes of this
-        ;; implemetation) lacks the same kind of gender differences that Italian, for
-        ;; example, has.
-        source-format-fn #((-> models source-language :morph) % :show-notes false)
+(def target-format-fn (-> models target-language :morph))

-        generated (->
-                   {:synsem {:sem {:subj {:pred :lui}
-                                   :obj :unspec
-                                   :tense :past
-                                   :aspect :progressive
-                                   :pred :answer}}}
-                   source-generate-fn
-                   source-format-fn)]
-
-    (or (= generated "he used to answer")
-        (= generated "he was answering"))))
+(deftest reader1
+  (let [source (->
+                {:synsem {:sem {:subj {:pred :lui}
+                                :obj :unspec
+                                :tense :past
+                                :aspect :progressive
+                                :pred :answer}}}
+                source-generate-fn
+                source-format-fn)
+        target (->
+                {:synsem {:sem {:subj {:pred :lui}
+                                :obj :unspec
+                                :tense :past
+                                :aspect :progressive
+                                :pred :answer}}}
+                target-generate-fn
+                target-format-fn)]
+    (is (or (= source "he used to answer")
+            (= source "he was answering")))))
+
+;    (is (or (= target "foobar")))))

+
+


remove for merge

remove for merge

--- src/navigator/schema.clj
+++ src/navigator/schema.clj
@@ -2,72 +2,83 @@
   (:require [datomic-schematode.constraints :as constraints]))

 (def schema
-  [[:comp {:attrs [[:id-sk :string "Shared key for 3rd parties" :db.unique/identity]
-                   [:name :string :indexed] ; not null
-                   [:description :string :indexed]
-                   [:version :string]               ; not null
-                   [:status :enum [:active :archived :preactive]] ; not null
-                   [:tags :ref :many]]
-           :dbfns [(constraints/unique :comp :name :version)]}]
-   [:comp-tag {:attrs [[:name :string :indexed] ; not null
-                       [:description :string]
-                       [:version :string]     ; not null
-                       [:type :string :indexed] ; not null
-                       [:isrequestable :boolean] ; default f
-                       [:icon :uri]
-                       [:status :enum [:active :archived]] ; not null
-                       [:isfinal :boolean] ; default f
-                       [:disp-ctxs :ref :many]
-                       [:child-tags :ref :many]
-                       [:child-perf-asmts :ref :many]
-                       [:child-comps :ref :many]]
-               :dbfns [(constraints/unique :comp-tag :name :version)]}]
-   [:comp-tag-disp-ctx {:attr [[:name :string]]}]
-   [:perf-asmt {:attrs [[:id-sk :string "Shared key from 3rd parties"]
-                        [:id-sk-origin :keyword] ; e.g., :moodle, :show-evidence, etc.
-                        [:name :string]
-                        [:version :string] ; not null
+  [{:namespace :comp
+    :attrs [[:id-sk :string "Shared key for 3rd parties" :db.unique/identity]
+            [:name :string :indexed] ; not null
+            [:description :string :indexed]
+            [:version :string]               ; not null
+            [:status :enum [:active :archived :preactive]] ; not null
+            [:tags :ref :many]]
+    :dbfns [(constraints/unique :comp :name :version)]}
+   {:namespace :comp-tag
+    :attrs [[:name :string :indexed] ; not null
+            [:description :string]
+            [:version :string]     ; not null
+            [:type :string :indexed] ; not null
+            [:isrequestable :boolean] ; default f
+            [:icon :uri]
+            [:status :enum [:active :archived]] ; not null
+            [:isfinal :boolean] ; default f
+            [:disp-ctxs :ref :many]
+            [:child-tags :ref :many]
+            [:child-perf-asmts :ref :many]
+            [:child-comps :ref :many]]
+    :dbfns [(constraints/unique :comp-tag :name :version)]}
+   {:namespace :comp-tag-disp-ctx
+    :attrs [[:name :string]]}
+   {:namespace :perf-asmt
+    :attrs [[:id-sk :string "Shared key from 3rd parties"]
+            [:id-sk-origin :keyword] ; e.g., :moodle, :show-evidence, etc.
+            [:id-sk-with-origin :string "Combined id-sk and id-sk-origin" :db.unique/identity]
+            [:name :string]
+            [:version :string] ; not null

-                        ;; Example types: :project :course-competency ... TODO: enum?
-                        [:type :string] ; not null
-                        [:duration-rating-days :bigint]
-                        [:comps :ref :many]
-                        [:credit-value-numerator :bigint]
-                        [:credit-value-denominator :bigint]]
-               :dbfns [(constraints/unique :perf-asmt :name :version :type)
-                       (constraints/unique :perf-asmt :id-sk :id-sk-origin)]}]
-   [:task {:attrs [[:id-sk :string]
-                   [:id-sk-origin :keyword] ; e.g., :moodle, :show-evidence, etc.
-                   [:name :string]
-                   [:version :string]
-                   [:description :string]
+            ;; Example types: :project :course-competency ... TODO: enum?
+            [:type :string] ; not null
+            [:duration-rating-days :bigint]
+            [:comps :ref :many]
+            [:credit-value-numerator :bigint]
+            [:credit-value-denominator :bigint]]
+    :dbfns [(constraints/unique :perf-asmt :name :version :type)
+            (constraints/unique :perf-asmt :id-sk :id-sk-origin)]}
+   {:namespace :task
+    :attrs [[:id-sk :string]
+            [:id-sk-origin :keyword] ; e.g., :moodle, :show-evidence, etc.
+            [:id-sk-with-origin :string "Combined id-sk and id-sk-origin" :db.unique/identity]
+            [:name :string]
+            [:version :string]
+            [:description :string]

-                   ;; TODO: is this correct?
-                   [:comps :ref :many]]
-           :dbfns [(constraints/unique :perf-asmt :id-sk :id-sk-origin)]}]
-   [:user2comp {:attrs [[:sis-user-id :bigint :indexed]
-                        [:comp :ref :indexed]
-                        [:start-date :instant]
-                        [:iscomplete :boolean] ; default f
-                        [:isoverridden :boolean] ; default f
-                        [:completion-date :instant]
-                        [:proposed-completion-date :instant]
-                        [:current-score :string]
-                        [:final-score :string]
-                        [:score-denominator :bigint]
-                        [:score-type :enum [:numeric :letter :pass-fail :qualitative]] ; enum is what we want here, n'est-ce pas?
-                        [:qualitative-notes :string]]}]
+            ;; TODO: is this correct?
+            [:comps :ref :many]]
+    :dbfns [(constraints/unique :perf-asmt :id-sk :id-sk-origin)]}
+   {:namespace :user2comp
+    :attrs [[:sis-user-id :bigint :indexed]
+            [:comp :ref :indexed]
+            [:start-date :instant]
+            [:iscomplete :boolean] ; default f
+            [:isoverridden :boolean] ; default f
+            [:completion-date :instant]
+            [:proposed-completion-date :instant]
+            [:current-score :string]
+            [:final-score :string]
+            [:score-denominator :bigint]
+            [:score-type :enum [:numeric :letter :pass-fail :qualitative]] ; enum is what we want here, n'est-ce pas?
+            [:qualitative-notes :string]]}

-   [:user2perf-asmt {:attrs [[:user :ref]
-                             [:perf-asmt :ref]
-                             ;; TODO: finish this
-                             [:grade :boolean]]}]
+   {:namespace :user2perf-asmt
+    :attrs [[:user :ref]
+            [:perf-asmt :ref]
+            ;; TODO: finish this
+            [:grade :boolean]]}

-   [:user2task {:attrs [[:user :ref]
-                        [:task :ref]
-                        ;; TODO: finish this
-                        [:progress :boolean]]}]
+   {:namespace :user2task
+    :attrs [[:user :ref]
+            [:task :ref]
+            ;; TODO: finish this
+            [:progress :boolean]]}

-   [:config {:attrs [[:key :string :indexed] ; not null
-                     [:value :string :indexed]]}]
+   {:namespace :config
+    :attrs [[:key :string :indexed] ; not null
+            [:value :string :indexed]]}
    ])


Fix invite message copy.

Fix invite message copy.

--- src/oc/email/content.clj
+++ src/oc/email/content.clj
@@ -23,7 +23,7 @@

 (def sent-by-text "Sent by Carrot")

-(def invite-message "invited you to join your team on Carrot")
+(def invite-message "invited you to his team on Carrot")

 (def share-message "sent you a post")
 (def share-cta "View the post")


Use different ports.

Use different ports.

--- test/kabel/core_test.clj
+++ test/kabel/core_test.clj
@@ -46,7 +46,7 @@
   (testing "Pushing a thousand messages through."
     (let [sid #uuid "fd0278e4-081c-4925-abb9-ff4210be271b"
           cid #uuid "898dcf36-e07a-4338-92fd-f818d573444a"
-          url "ws://localhost:47291"
+          url "ws://localhost:47292"
           handler (http-kit/create-http-kit-handler! S url sid)
           speer (peer/server-peer S handler sid pong-middleware identity)
           cpeer (peer/client-peer S cid (fn [[S peer [in out]]]


matcher-combinators: Move all explicit matchers to same section

--- test/com/nomistech/clojure_the_language/c_800_libraries/s_106_matcher_combinators/matcher_generators_test.clj
+++ test/com/nomistech/clojure_the_language/c_800_libraries/s_106_matcher_combinators/matcher_generators_test.clj
@@ -43,10 +43,6 @@
   (is (match? inc ; not normally considered a predicate, but used as one here
               1)))

-(deftest equals-overrides-predicate-test
-  (is (match? (m/equals even?)
-              even?)))
-
 ;;;; ___________________________________________________________________________
 ;;;; ---- Maps ----

@@ -64,13 +60,6 @@
     (is (match? {:a 1}
                 {:a 1 :b 2})))

-  (testing "Use m/equals for exact match"
-    (is (match? (m/equals {:a 1 :b 2})
-                {:a 1 :b 2}))
-    (is (match? (m/mismatch ; see ++use-of-mismatch++ at top of file
-                 (m/equals {:a 1}))
-                {:a 1 :b 2})))
-
   (testing "Use m/absent to check for absence of a key"
     (is (match? {:a 1 :b m/absent}
                 {:a 1}))
@@ -81,10 +70,6 @@
 (deftest predicates-for-map-values-test
   (is (match? {:a even?}
               {:a 1234})))
-
-(deftest predicates-within-equals-test
-  (is (match? (m/equals {:a 1 :b even?})
-              {:a 1 :b 1234})))

 ;;;; ___________________________________________________________________________
 ;;;; ---- Sequences ----
@@ -156,6 +141,22 @@
               1234)) ; TODO: I guess we need this in contexts where `even?` would not be treated as a pred -- but what are those contexts?
   )

+(deftest equals-overrides-predicate-test
+  (is (match? (m/equals even?)
+              even?)))
+
+(deftest equals-overrides-map-embeds-test
+  (testing "Use m/equals for exact match"
+    (is (match? (m/equals {:a 1 :b 2})
+                {:a 1 :b 2}))
+    (is (match? (m/mismatch ; see ++use-of-mismatch++ at top of file
+                 (m/equals {:a 1}))
+                {:a 1 :b 2}))))
+
+(deftest predicates-within-equals-test
+  (is (match? (m/equals {:a 1 :b even?})
+              {:a 1 :b 1234})))
+
 (deftest WIP-embeds-test ; TODO
   (is (match? (m/embeds [1 3 5])
               [1 2 3 4 5])))


add invitation stuff to server-side of sync

--- src/chat/server/sync.clj
+++ src/chat/server/sync.clj
@@ -118,6 +118,38 @@
             (println "sending reply")
             (?reply-fn {:error "Group name already taken"})))))))

+(defmethod event-msg-handler :chat/invite-to-group
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
+  (when-let [user-id (get-in ring-req [:session :user-id])]
+    (if (db/with-conn (db/user-in-group? user-id (?data :group-id)))
+      (let [data (assoc data :inviter-id user-id)
+            invitation (db/with-conn (db/create-invitation! data))]
+        (when-let [invited-user (db/with-conn (db/user-with-email (invitation :to)))]
+          (chsk-send! (invited-user :id) [:chat/invitation-recieved invitation])))
+      ; TODO: indicate permissions error to user?
+      (timbre/warnf "User %s attempted to invite %s to a group %s they don't have access to"
+                    user-id (?data :invitee-email) (?data :group-id)))))
+
+(defmethod event-msg-handler :chat/invitation-accept
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
+  (when-let [user-id (get-in ring-req [:session :user-id])]
+    (if-let [invite (db/with-conn (db/get-invite (?data :id)))]
+      (do
+        (db/with-conn
+          ; TODO: need to send group info to user
+          (db/user-add-to-group! user-id (invite :group-id))
+          (db/retract-invitation! (invite :id))))
+      (timbre/warnf "User %s attempted to accept nonexistant invitaiton %s"
+                    user-id (?data :id)))))
+
+(defmethod event-msg-handler :chat/invitation-decline
+  [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
+  (when-let [user-id (get-in ring-req [:session :user-id])]
+    (if-let [invite (db/with-conn (db/get-invite (?data :id)))]
+      (db/with-conn (db/retract-invitation! (invite :id)))
+      (timbre/warnf "User %s attempted to decline nonexistant invitaiton %s"
+                    user-id (?data :id)))))
+
 (defmethod event-msg-handler :session/start
   [{:as ev-msg :keys [event id ?data ring-req ?reply-fn send-fn]}]
   (when-let [user-id (get-in ring-req [:session :user-id])]
@@ -128,6 +160,7 @@
                             :user-threads (db/get-open-threads-for-user user-id)
                             :user-subscribed-tag-ids (db/get-user-subscribed-tag-ids user-id)
                             :users (db/fetch-users-for-user user-id)
+                            :invitations (db/fetch-invitations-for-user user-id)
                             :tags (db/fetch-tags-for-user user-id)})])))

 (defonce router_ (atom nil))


Add not-found route to handler.clj

Add not-found route to handler.clj

--- src/leiningen/new/re_frame/src/clj/handler.clj
+++ src/leiningen/new/re_frame/src/clj/handler.clj
@@ -1,14 +1,15 @@
 (ns {{ns-name}}.handler
   (:require
     [compojure.core :refer [GET defroutes]]
-    [compojure.route :refer [resources]]
+    [compojure.route :refer [resources not-found]]
     [ring.util.response :refer [resource-response]]
     [ring.middleware.reload :refer [wrap-reload]]
     [shadow.http.push-state :as push-state]))

 (defroutes routes
   (GET "/" [] (resource-response "index.html" {:root "public"}))
-  (resources "/"))
+  (resources "/")
+  (not-found "Page not found"))

 (def dev-handler (-> #'routes wrap-reload push-state/handle))


preserve sym meta in var

preserve sym meta in var

--- src/main/clojure/clojure/tools/analyzer/js.clj
+++ src/main/clojure/clojure/tools/analyzer/js.clj
@@ -166,9 +166,10 @@

 (defn create-var
   [sym {:keys [ns]}]
-  {:op   :var
-   :name sym
-   :ns   ns})
+  (with-meta {:op   :var
+              :name sym
+              :ns   ns}
+    (meta sym)))

 (defn var? [x]
   (= :var (:op x)))


remove variation from base gene doc

remove variation from base gene doc

--- src/wb_es/datomic/data/variation.clj
+++ src/wb_es/datomic/data/variation.clj
@@ -12,9 +12,6 @@
     {:wbid (:variation/id entity)
      :label (:variation/public-name entity)
      :species (data-util/format-entity-species :variation/species entity)
-     :gene (->> (:variation/gene entity)
-                (map :variation.gene/gene)
-                (map data-util/pack-obj))
      }))

 (deftype Gene [gene]


move seq test into individual save callbacks on todo input so handling of blank can be differentiated

--- examples/todomvc/src/todomvc/views.cljs
+++ examples/todomvc/src/todomvc/views.cljs
@@ -9,7 +9,7 @@
         stop #(do (reset! val "")
                   (when on-stop (on-stop)))
         save #(let [v (-> @val str str/trim)]
-                (when (seq v) (on-save v))
+                (on-save v)
                 (stop))]
     (fn [props]
       [:input (merge props
@@ -44,7 +44,9 @@
           [todo-input
             {:class "edit"
              :title title
-             :on-save #(dispatch [:save id %])
+             :on-save #(if (seq %)
+                          (dispatch [:save id %])
+                          (dispatch [:delete-todo id]))
              :on-stop #(reset! editing false)}])])))

@@ -91,7 +93,8 @@
     [todo-input
       {:id "new-todo"
        :placeholder "What needs to be done?"
-       :on-save #(dispatch [:add-todo %])}]])
+       :on-save #(when (seq %)
+                    (dispatch [:add-todo %]))}]])

 (defn todo-app


adding dedup versions of from and to

adding dedup versions of from and to

--- src/ophion/aggregate.clj
+++ src/ophion/aggregate.clj
@@ -14,6 +14,19 @@
 (defn dollar
   [s]
   (str "$" (name s)))
+
+(defn dedup
+  []
+  [{:$group {:_id "$gid" :dedup {:$first "$$ROOT"}}}
+   {:$replaceRoot {:newRoot "$dedup"}}])
+
+(defn dedup-on
+  [field]
+  (let [path (dollar field)]
+    [{:$group {:_id path :dedup {:$first "$$ROOT"}}}
+     {:$replaceRoot {:newRoot "$dedup"}}]))
+
+    ;; {:$group {:_id dollar (keyword field) {:$first dollar} :_history {:$addToSet "$_history"}}}

 (defn where
   [where]
@@ -89,6 +102,22 @@
     (to-edge edge-label)
     (to-vertex vertex-label where))))

+(defn from-dedup
+  ([edge-label vertex-label] (from edge-label vertex-label {}))
+  ([edge-label vertex-label where]
+   (concat
+    (from-edge edge-label)
+    (dedup-on "from")
+    (from-vertex vertex-label where))))
+
+(defn to-dedup
+  ([edge-label vertex-label] (to edge-label vertex-label {}))
+  ([edge-label vertex-label where]
+   (concat
+    (to-edge edge-label)
+    (dedup-on "to")
+    (to-vertex vertex-label where))))
+
 (defn values
   [values]
   [{:$project
@@ -124,19 +153,6 @@
 (defn qount
   []
   [{:$count "count"}])
-
-(defn dedup
-  []
-  [{:$group {:_id "$gid" :dedup {:$first "$$ROOT"}}}
-   {:$replaceRoot {:newRoot "$dedup"}}])
-
-(defn dedup-on
-  [field]
-  (let [path (dollar field)]
-    [{:$group {:_id path :dedup {:$first "$$ROOT"}}}
-     {:$replaceRoot {:newRoot "$dedup"}}]))
-
-    ;; {:$group {:_id dollar (keyword field) {:$first dollar} :_history {:$addToSet "$_history"}}}

 (defn offset
   [n]
@@ -232,6 +248,8 @@
    :toVertex to-vertex
    :from from
    :to to
+   :fromDedup from-dedup
+   :toDedup to-dedup
    :root root
    :dedup dedup
    :dedupOn dedup-on


Rename live-node? to node-live? and add node-loading? and active-active? Redefine exception behaviour for live nodes in terms of being active (therefore including the loading state). Also throw an exception when attempting to kill a non-active node. Fixes #200.

--- src/overtone/sc/node.clj
+++ src/overtone/sc/node.clj
@@ -159,10 +159,21 @@
   [obj]
   (isa? (type obj) ::node))

-(defn live-node?
+(defn node-live?
+  "Returns true if n is a live synth node."
+  [n]
+  (and (node? n) (= :live @(:status n))))
+
+(defn node-loading?
+  "Returns true if n is a loading synth node."
+  [n]
+  (and (node? n) (= :loading @(:status n))))
+
+(defn node-active?
   "Returns true if n is an active synth node."
   [n]
-  (and (node? n) (= :live @(:status n))))
+  (or (node-live? n)
+      (node-loading? n)))

 (defn node-free*
   "Free the specified nodes on the server. The allocated id is
@@ -170,8 +181,9 @@
   for /n_end which will call node-destroyed."
   [node]
   {:pre [(server-connected?)]}
-  (when (live-node? node)
-    (snd "/n_free" (to-synth-id node))))
+  (if (node-active? node)
+    (snd "/n_free" (to-synth-id node))
+    (throw (Exception. (str "Trying to free a synth node that has been destroyed: " node)))))

 (defn- node-destroyed
   "Frees up a synth node to keep in sync with the server."
@@ -315,7 +327,7 @@
   [node name-values]
   (ensure-connected!)
   (let [node-id (to-synth-id node)]
-    (if (live-node? node)
+    (if (node-active? node)
       (apply snd "/n_set" node-id (floatify (stringify (bus->id name-values))))
       (throw (Exception. (str "Trying to control a synth node that has been destroyed: " node))))
     node-id))


format layout

format layout

--- src/overtone/sc/ugen.clj
+++ src/overtone/sc/ugen.clj
@@ -5,20 +5,20 @@
   (:refer-clojure :exclude (deftype))

   (:use
-    clojure.contrib.pprint
-    overtone.sc.ugen.defaults
-    [overtone util]
-    [overtone.sc buffer]
-    [overtone.sc.ugen special-ops common categories]
-    [clojure.contrib.types :only (deftype)]
-    [clojure.contrib.generic :only (root-type)])
+   clojure.contrib.pprint
+   overtone.sc.ugen.defaults
+   [overtone util]
+   [overtone.sc buffer]
+   [overtone.sc.ugen special-ops common categories]
+   [clojure.contrib.types :only (deftype)]
+   [clojure.contrib.generic :only (root-type)])
   (:require
-    overtone.sc.core
-    [overtone.sc.ugen.doc :as doc]
-    [clojure.set :as set]
-    [clojure.contrib.generic.arithmetic :as ga]
-    [clojure.contrib.generic.comparison :as gc]
-    [clojure.contrib.generic.math-functions :as gm]))
+   overtone.sc.core
+   [overtone.sc.ugen.doc :as doc]
+   [clojure.set :as set]
+   [clojure.contrib.generic.arithmetic :as ga]
+   [clojure.contrib.generic.comparison :as gc]
+   [clojure.contrib.generic.math-functions :as gm]))

 (def UGEN-SPEC-EXPANSION-MODES
   {:not-expanded false
@@ -44,7 +44,7 @@
         n (.replaceAll n "([A-Z])([A-Z][a-z])" "$1-$2")
         n (.replaceAll n "_" "-")
         n (.toLowerCase n)]
-  n))
+    n))

 (defn- derived? [spec]
   (contains? spec :extends))
@@ -55,23 +55,23 @@
   Recursively reduces the specs to support arbitrary levels of derivation."
   ([specs] (derive-ugen-specs specs {} 0))
   ([children adults depth]
-   ; Make sure a bogus UGen doesn't spin us off into infinity... ;-)
-   {:pre [(< depth 8)]}
-
-   (let [[adults children]
-         (reduce (fn [[full-specs new-children] spec]
-                   (if (derived? spec)
-                     (if (contains? full-specs (:extends spec))
-                       [(assoc full-specs (:name spec)
-                               (merge (get full-specs (:extends spec)) spec))
-                        new-children]
-                       [full-specs (conj new-children spec)])
-                     [(assoc full-specs (:name spec) spec) new-children]))
-                 [adults []]
-                 children)]
-     (if (empty? children)
-       (vals adults)
-       (recur children adults (inc depth))))))
+     ;; Make sure a bogus UGen doesn't spin us off into infinity... ;-)
+     {:pre [(< depth 8)]}
+
+     (let [[adults children]
+           (reduce (fn [[full-specs new-children] spec]
+                     (if (derived? spec)
+                       (if (contains? full-specs (:extends spec))
+                         [(assoc full-specs (:name spec)
+                                 (merge (get full-specs (:extends spec)) spec))
+                          new-children]
+                         [full-specs (conj new-children spec)])
+                       [(assoc full-specs (:name spec) spec) new-children]))
+                   [adults []]
+                   children)]
+       (if (empty? children)
+         (vals adults)
+         (recur children adults (inc depth))))))

 (defn- with-rates
   "Add the default ugen rates to any ugen that doesn't explicitly set it."
@@ -88,7 +88,7 @@
               (= 1 (count rates)) (first rates)
               :default (first (filter rates
                                       UGEN-DEFAULT-RATE-PRECEDENCE)))
-       rate (if (or (= :ir rate) (:auto-rate spec))
+        rate (if (or (= :ir rate) (:auto-rate spec))
                :auto
                rate)]
     (assoc spec :default-rate rate)))
@@ -109,7 +109,7 @@
                                  false
                                  (get UGEN-SPEC-EXPANSION-MODES
                                       (get arg :mode :standard)))]
-                (assoc arg :expands? expands?)))
+                  (assoc arg :expands? expands?)))
               (:args spec))))

 (defn- with-fn-names
@@ -136,7 +136,7 @@
         name-rates (zipmap (map #(str base-name %) rate-vec)
                            rate-vec)]
     (assoc spec
-           :fn-names (assoc name-rates base-name base-rate))))
+      :fn-names (assoc name-rates base-name base-rate))))

 (defn- args-with-specs
   "Creates a list of (arg-value, arg-spec-item) pairs."
@@ -151,9 +151,9 @@
   (let [args (:args ugen)
         args-specs (args-with-specs args spec :map)
         mapped-args (map (fn [[arg map-val]] (if (and (map? map-val)
-                                                      (keyword? arg))
-                                               (arg map-val)
-                                               arg))
+                                                     (keyword? arg))
+                                              (arg map-val)
+                                              arg))
                          args-specs)]
     (assoc ugen :args mapped-args)))

@@ -191,8 +191,8 @@
                               [[] (:n-outputs ugen)]
                               args-specs)]
     (assoc ugen
-           :n-outputs n-outs
-           :args args)))
+      :n-outputs n-outs
+      :args args)))

 (defn- with-floated-args [spec ugen]
   (assoc ugen :args (floatify (:args ugen))))
@@ -258,28 +258,28 @@
     (assoc spec :init
            (fn [ugen]
              (-> ugen
-               defaulter
-               mapper
-               initer
-               n-outputer
-               floater
-               buffer->id
-               appender
-               auto-rater
-               rate-checker)))))
+                 defaulter
+                 mapper
+                 initer
+                 n-outputer
+                 floater
+                 buffer->id
+                 appender
+                 auto-rater
+                 rate-checker)))))

 (defn- decorate-ugen-spec
   "Interpret a ugen-spec and add in additional, computed meta-data."
   [spec]
   (-> spec
-    (with-rates)
-    (with-categories)
-    (with-expands)
-    (with-init-fn)
-    (with-default-rate)
-    (with-fn-names)
-    (doc/with-arg-defaults)
-    (doc/with-full-doc)))
+      (with-rates)
+      (with-categories)
+      (with-expands)
+      (with-init-fn)
+      (with-default-rate)
+      (with-fn-names)
+      (doc/with-arg-defaults)
+      (doc/with-full-doc)))

 (defn- specs-from-namespaces [namespaces]
   (reduce (fn [mem ns]
@@ -287,10 +287,10 @@
                   _ (require [full-ns :only '[specs specs-collide]])
                   specs (var-get (ns-resolve full-ns 'specs))]

-              ; TODO: Currently colliders must be loaded before specs in order
-              ; for this to run properly, because some ugens in specs derive
-              ; from the 'index' ugen in colliders.  Maybe the derivation
-              ; process should get smarter...
+              ;; TODO: Currently colliders must be loaded before specs in order
+              ;; for this to run properly, because some ugens in specs derive
+              ;; from the 'index' ugen in colliders.  Maybe the derivation
+              ;; process should get smarter...
               (if-let [colliders (ns-resolve full-ns 'specs-collide)]
                 (concat mem (var-get colliders) specs)
                 (concat mem specs))))
@@ -313,8 +313,8 @@

 (def UGEN-SPECS (load-ugen-specs UGEN-NAMESPACES))
 (def UGEN-SPEC-MAP (zipmap
-                     (map #(normalize-ugen-name (:name %)) UGEN-SPECS)
-                     UGEN-SPECS))
+                    (map #(normalize-ugen-name (:name %)) UGEN-SPECS)
+                    UGEN-SPECS))

 (defn get-ugen [word]
   (get UGEN-SPEC-MAP (normalize-ugen-name word)))
@@ -322,7 +322,7 @@
 (defn find-ugen [regexp]
   (map #(second %)
        (filter (fn [[k v]] (re-find (re-pattern (normalize-ugen-name regexp))
-                                    (str k)))
+                                   (str k)))
                UGEN-SPEC-MAP)))

 (defn inf!
@@ -336,12 +336,12 @@
 (defn- inf? [obj]
   (:infinite-sequence (meta obj)))

-; Does it really make sense to cycle over the values of a collection when
-; doing expansion?  I don't think maps should be allowed as arguments, unless
-; this is a strategy at having named arguments, but then the ordering wouldn't
-; make sense.
-;(defn- cycle-vals [coll]
-;  (cycle (if (map? coll) (vals coll) coll)))
+;; Does it really make sense to cycle over the values of a collection when
+;; doing expansion?  I don't think maps should be allowed as arguments, unless
+;; this is a strategy at having named arguments, but then the ordering wouldn't
+;; make sense.
+;;(defn- cycle-vals [coll]
+;;  (cycle (if (map? coll) (vals coll) coll)))

 (defn- expandable? [arg]
   (and (coll? arg)
@@ -361,21 +361,21 @@
     [[]]
     (let [gc-seqs (fn [[gcount seqs flags] arg]
                     (cond
-                      ; Infinite seqs can be used to generate values for expansion
-                      (inf? arg) [gcount
-                                  (conj seqs arg)
-                                  (next flags)]
-
-                      ; Regular, non-infinite and non-map collections get expanded
-                      (and (expandable? arg)
-                           (first flags)) [(max gcount (count arg))
-                                           (conj seqs (cycle arg))
-                                           (next flags)]
-
-                      :else ; Basic values get used for all expansions
-                      [gcount
-                       (conj seqs (repeat arg))
-                       (next flags)]))
+                     ;; Infinite seqs can be used to generate values for expansion
+                     (inf? arg) [gcount
+                                 (conj seqs arg)
+                                 (next flags)]
+
+                     ;; Regular, non-infinite and non-map collections get expanded
+                     (and (expandable? arg)
+                          (first flags)) [(max gcount (count arg))
+                                          (conj seqs (cycle arg))
+                                          (next flags)]
+
+                          :else ;; Basic values get used for all expansions
+                          [gcount
+                           (conj seqs (repeat arg))
+                           (next flags)]))
           [greatest-count seqs] (reduce gc-seqs [1 [] expand-flags] args)]
       (take greatest-count (parallel-seqs seqs)))))

@@ -389,8 +389,8 @@
         (first expanded)
         expanded))))

-; TODO: Finish me!
-; Need to execute the check predicates to do things like verify argument rates, etc...
+;; TODO: Finish me!
+;; Need to execute the check predicates to do things like verify argument rates, etc...
 (defn check-ugen-args [spec rate special args]
   (if (vector? (:check spec))
     (doseq [check (:check spec)]
@@ -416,16 +416,16 @@
 (def *constants* nil)

 (defn ugen [spec rate special args]
-  ;(check-ugen-args spec rate special args)
+  ;;(check-ugen-args spec rate special args)
   (let [rate (or (get RATES rate) rate)
         ug (UGen.
-             (next-id :ugen)
-             (:name spec)
-             rate
-             (REVERSE-RATES rate)
-             special
-             args
-             (or (:num-outs spec) 1))
+            (next-id :ugen)
+            (:name spec)
+            rate
+            (REVERSE-RATES rate)
+            special
+            args
+            (or (:num-outs spec) 1))
         ug (if (contains? spec :init) ((:init spec) ug) ug)]
     (when (and *ugens* *constants*)
       (set! *ugens* (conj *ugens* ug))
@@ -467,7 +467,7 @@
               :outputs (repeat n-outputs {:rate (rate RATES)})
               :n-inputs 0
               :inputs []}
-            {:type :ugen}))
+    {:type :ugen}))

 (defn control? [obj]
   (isa? (type obj) ::control))
@@ -492,7 +492,7 @@
                   :arglists (list (vec (map #(symbol (:name %))
                                             (:args spec))))}
         ugen-fns (map (fn [[uname rate]] [(with-meta (symbol uname) metadata)
-                                          (make-ugen-fn spec rate special)])
+                                         (make-ugen-fn spec rate special)])
                       (:fn-names spec))]
     (doseq [[ugen-name ugen-fn] ugen-fns]
       (intern to-ns ugen-name ugen-fn))))
@@ -521,19 +521,19 @@
       (overload-ugen-op to-ns ugen-name ugen-fn)
       (intern to-ns ugen-name ugen-fn))))

-; We define this uniquely because it has to be smart about its rate.
-; TODO: I think this should probably be handled by one of the ugen modes
-; that is currently not yet implemented...
+;; We define this uniquely because it has to be smart about its rate.
+;; TODO: I think this should probably be handled by one of the ugen modes
+;; that is currently not yet implemented...
 (def mul-add
   (make-expanding
-    (fn [in mul add]
-      (ugen {:name "MulAdd",
-                       :args [{:name "in"}
-                              {:name "mul", :default 1.0}
-                              {:name "add", :default 0.0}]
-                       :doc "Multiply and add, equivalent to (+ add (* mul in))"}
-            (op-rate in) 0 (list in mul add)))
-    [true true true]))
+   (fn [in mul add]
+     (ugen {:name "MulAdd",
+            :args [{:name "in"}
+                   {:name "mul", :default 1.0}
+                   {:name "add", :default 0.0}]
+            :doc "Multiply and add, equivalent to (+ add (* mul in))"}
+           (op-rate in) 0 (list in mul add)))
+   [true true true]))

 (load "ugen/generic_ops")

@@ -545,13 +545,13 @@
     (doseq [ugen (filter #(not (or (= "UnaryOpUGen" (:name %))
                                    (= "BinaryOpUGen" (:name %))))
                          UGEN-SPECS)]
-              (def-ugen to-ns ugen 0))
+      (def-ugen to-ns ugen 0))
     (doseq [[op-name special] UNARY-OPS]
       (def-unary-op to-ns op-name special))
     (doseq [[op-name special] BINARY-OPS]
       (def-binary-op to-ns op-name special))
-    ;(intern to-ns 'mul-add (make-expanding mul-add [true true true]))
-    ;(refer 'overtone.sc.ugen.extra)
+    ;;(intern to-ns 'mul-add (make-expanding mul-add [true true true]))
+    ;;(refer 'overtone.sc.ugen.extra)
     ))

 (defn intern-ugens-collide
@@ -561,13 +561,13 @@
         generics #{"+" "-" "*" "/"}]
     (doseq [op generics]
       (let [func (var-get (resolve (symbol "clojure.contrib.generic.arithmetic" op)))]
-      (ns-unmap to-ns (symbol op))
-      (intern to-ns (symbol op) (make-expanding func [true true]))))
-
-    ; intern div-meth so we can access the division operator since / is special cased
+        (ns-unmap to-ns (symbol op))
+        (intern to-ns (symbol op) (make-expanding func [true true]))))
+
+    ;; intern div-meth so we can access the division operator since / is special cased
     (intern to-ns 'div-meth
             (make-expanding (var-get (resolve
-                                       (symbol "clojure.contrib.generic.arithmetic" "/")))
+                                      (symbol "clojure.contrib.generic.arithmetic" "/")))
                             [true true]))

     (doseq [[op-name special] UNARY-OPS-COLLIDE]


oops, fix jitter

oops, fix jitter

--- src/clj/tictag/slack.clj
+++ src/clj/tictag/slack.clj
@@ -32,7 +32,7 @@

 (dh/defretrypolicy retry-policy
   {:backoff-ms [11 1009]
-   :jitter-ms 0.1
+   :jitter-factor 0.1
    :max-retries 8})

@@ -46,7 +46,7 @@
                                            (http/post opts)
                                            (deref 5000 {:error :timeout}))]
       (when error
-        (throw (ex-info "HTTP Exception occurred" {:exception exception
+        (throw (ex-info "HTTP Exception occurred" {:exception error
                                                    :cmd cmd
                                                    :opts opts})))
       (some-> response


Adds doc strings to Album calls and first half of Artists calls.

--- src/clj_spotify/core.clj
+++ src/clj_spotify/core.clj
@@ -43,30 +43,64 @@
     (build-new-url "" split-url act-tmplt-keys)
     )))

-;TODO - deal with search for nice formatting. Do you want docstrings?
 (defmacro spotify-api-call
-  [f verb uri doc-string]
+  ""
+  [f verb url doc-string]
   `(defn ~f
      ~doc-string
-     ([args#] (~f args# nil))
-     ([args# oauth-token#]
-      (let [query-params# {:query-params (apply dissoc args# template-keys) :oauth-token oauth-token#}]
+     ([m#] (~f m# nil))
+     ([m# t#]
+      (let [query-params# {:query-params (apply dissoc m# template-keys) :oauth-token t#}]
         (->
           (try
-            (~verb (replace-url-values args# ~uri) query-params#)
+            (~verb (replace-url-values m# ~url) query-params#)
             (catch Exception e# (ex-data e#))
             )
           (response-to-map)
           )))))

 ;Albums
-(spotify-api-call get-album client/get (str spotify-api-url "albums/id") "")
-(spotify-api-call get-several-albums client/get (str spotify-api-url "albums") "")
-(spotify-api-call get-tracks-of-album client/get (str spotify-api-url "albums/id/tracks") "")
+(spotify-api-call get-album client/get (str spotify-api-url "albums/id")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory key in m is :id, optional key is :market.
+    :id has to have the value of an existing album's id.
+    :market is an ISO 3166-1 alpha-2 country code.
+
+    Example: (get-album {:id \"0MnG7y5F1n4Wns63RjEItx\" :market \"SE\"} \"BQBw-JtC..._7GvA\")")
+
+(spotify-api-call get-several-albums client/get (str spotify-api-url "albums")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory key in m is :ids, optional key is :market.
+    :ids has to be a comma separated string of spotify album ids.
+    :market is an ISO 3166-1 alpha-2 country code.
+
+    Example: (get-several-albums {:ids \"4hTil0JVdMyxK2vH11ZbiX,4RjjFbiqFaO8mKTDM2Kzna\" :market \"SE\"} \"BQBw-JtC..._7GvA\") ")
+
+(spotify-api-call get-tracks-of-album client/get (str spotify-api-url "albums/id/tracks")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory key in m is :id, optional keys are :limit, :offset and :market.
+    :id has to have the value of an existing album's id.
+    :limit is the maxium number of tracks to return, default is 20.
+    :offset is the index of the first track to return, default is 0.
+    :market is an ISO 3166-1 alpha-2 country code.
+
+    Example: (get-tracks-of-album {:id \"3XCGFOBqESirxxICswSity\" :market \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

 ;Artists
-(spotify-api-call get-artist client/get (str spotify-api-url "artists/id") "")
-(spotify-api-call get-several-artists client/get (str spotify-api-url "artists") "")
+(spotify-api-call get-artist client/get (str spotify-api-url "artists/id")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory key in m is :id.
+    :id has to have the value of an existing artist's id.
+
+    Example: (get-artist {:id \"5CE2IfdYZEQGIDsfiRm8SI\"} \"BQBw-JtC..._7GvA\")")
+
+(spotify-api-call get-several-artists client/get (str spotify-api-url "artists")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory key in m is :ids.
+    :ids has to be a comma separated string of spotify artist ids.
+
+    Example: (get-several-artists {:ids \"1kK2LYgoP3raZNngbb1qMT,2RitCPbwEYyYNw5LkbXTGv\"} \"BQBw-JtC..._7GvA\")")
+
 (spotify-api-call get-artists-albums client/get (str spotify-api-url "artists/id/albums") "")
 (spotify-api-call get-artists-top-tracks client/get (str spotify-api-url "artists/id/top-tracks") "")
 (spotify-api-call get-artists-related-artists client/get (str spotify-api-url "artists/id/related-artists") "")


switch to new-login for form

switch to new-login for form

--- src/cljs/ohds/views.cljs
+++ src/cljs/ohds/views.cljs
@@ -4,6 +4,7 @@
    [ohds.model :as ml]
    [ohds.admin :as admin]
    [ohds.login.view :as login]
+   [ohds.login :as new-login]
    [ohds.hierarchy.view :as hierarchy]
    [ohds.location.view :as location]
    [ohds.socialgroup.view :as socialgroup]
@@ -98,14 +99,13 @@
       [:div.col-md-6
        (debug app)]
       [:div.cold-md-4 {} " "])
-
     [:div.col-md-4
      [:div.well.well-lg
       [:fieldset
        (if (= (:mode app) :not-authorized)
          (login/login ch (:user app))
          (case (:page app)
-           :login [login/login ch
+           :login [new-login/login ch
                    (:user app)]
            :admin-home [admin/form ch app]
            :hierarchy [hierarchy/form ch


Acceptance test changes.

Acceptance test changes.

--- test/onix/acceptance.clj
+++ test/onix/acceptance.clj
@@ -141,12 +141,14 @@
           (let [response (client/put (url+ "/applications/myapp/newkey") {:throw-exceptions false})]
             response => (contains {:status 404}))))

-   (fact "Create metadata for application fails when no data is supplied."
-         (rest-driven
-          [(dynamo-get-request :table "onix-applications" :key "myapp")
-           (dynamo-get-response :item {:name "myapp"})]
-          (let [response (client/put (url+ "/applications/myapp/newkey") {:throw-exceptions false})]
-            response => (contains {:status 404}))))
+   ;; Need to have validation to make sure value submitted isn't empty/null.
+
+   ;; (fact "Create metadata for application fails when no data is supplied."
+   ;;       (rest-driven
+   ;;        [(dynamo-get-request :table "onix-applications" :key "myapp")
+   ;;         (dynamo-get-response :item {:name "myapp"})]
+   ;;        (let [response (client/put (url+ "/applications/myapp/newkey") {:throw-exceptions false})]
+   ;;          response => (contains {:status 404}))))

    (fact "Create metadata for application succeeds."
          (rest-driven
@@ -154,11 +156,11 @@
            (dynamo-get-response :item {"name" {"S" "myapp"}})
            (dynamo-request :table "onix-applications" :action "PutItem")
            (dynamo-put-response)]
-          (let [response (client/put (url+ "/applications/myapp/newkey") {:body "newvalue"
+          (let [response (client/put (url+ "/applications/myapp/newkey") {:body "{\"value\":\"newvalue\"}"
                                                                           :throw-exceptions false})
                 body (read-body response)]
-            response => (contains {:status 200})
-            body => "newvalue")))
+            response => (contains {:status 201})
+            body => {:newkey "newvalue"})))

    (fact "Getting application is successful"
          (rest-driven
@@ -185,8 +187,8 @@
          (rest-driven
           [(dynamo-get-request :table "onix-applications" :key "myapp")
            (dynamo-get-response :item {"name" {"S" "myapp"}
-                                       "mykey" {"S" "myvalue"}})]
+                                       "metadata" {"S" "{\"mykey\":\"myvalue\"}"}})]
           (let [response (client/get (url+ "/applications/myapp/mykey"))
                 body (read-body response)]
             response => (contains {:status 200})
-            body => "myvalue"))))
+            body => {:mykey "myvalue"}))))


fix warning

fix warning

--- src/codeitlater/core.clj
+++ src/codeitlater/core.clj
@@ -8,7 +8,7 @@
             )
   (:gen-class))

-(def *help-url* "https://raw.githubusercontent.com/ccqpein/codeitlater/master/doc/help")
+(def ^:dynamic *help-url* "https://raw.githubusercontent.com/ccqpein/codeitlater/master/doc/help")

 (defn read-json [^String path]
   (if path (json/read-str (slurp path)) nil))


Update test/cats/runner.cljs

Update test/cats/runner.cljs

The cljs tests should fail for this commit.

- Cosmetic tweaks
- Rename main to -main
- Use when-not and (aget js/process "exit")
  instead of (set! (.-exitCode js/process) n)

See #158

--- test/cats/runner.cljs
+++ test/cats/runner.cljs
@@ -21,8 +21,7 @@

 (enable-console-print!)

-(defn main
-  []
+(defn -main []
   (test/run-tests
    (test/empty-env)
    'cats.core-spec
@@ -41,13 +40,10 @@
    'cats.labs.crdt.pncounter-spec
    'cats.labs.crdt.gcounter-spec
    'cats.labs.crdt.gset-spec
-   'cats.labs.lens-spec
-   ))
+   'cats.labs.lens-spec))

-(defmethod test/report [:cljs.test/default :end-run-tests]
-  [m]
-  (if (test/successful? m)
-    (set! (.-exitCode js/process) 0)
-    (set! (.-exitCode js/process) 1)))
+(defmethod test/report [:cljs.test/default :end-run-tests] [m]
+  (when-not (test/successful? m)
+    ((aget js/process "exit") 1)))

-(set! *main-cli-fn* main)
+(set! *main-cli-fn* -main)


Covered in immutant.xa/wrap

Covered in immutant.xa/wrap

--- modules/xa/src/main/clojure/immutant/xa/wrappers.clj
+++ modules/xa/src/main/clojure/immutant/xa/wrappers.clj
@@ -15,7 +15,7 @@
 ;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 ;; 02110-1301 USA, or see the FSF site: http://www.fsf.org.

-(ns immutant.xa.wrappers
+(ns ^{:no-doc true} immutant.xa.wrappers
   "Provide XA-compliant wrappers for java.sql interfaces"
   (:import [java.sql PreparedStatement Connection])
   (:require [immutant.xa.transaction :as tx]))


fix missing ui updates (compile, release didn't show progress)

--- src/main/shadow/cljs/devtools/graph/builds.clj
+++ src/main/shadow/cljs/devtools/graph/builds.clj
@@ -172,12 +172,17 @@
                  :mode mode
                  :log []})

-          log-chan
-          (async/chan 10)
+          build-logger
+          (reify
+            build-log/BuildLog
+            (log*
+              [_ state event]
+              (sys-bus/publish! system-bus ::m/build-log {:type :build-log
+                                                          :build-id build-id
+                                                          :event event})))

           pub-msg
           (fn [msg]
-            (>!! log-chan msg)
             ;; FIXME: this is not worker output but adding an extra channel seems like overkill
             (sys-bus/publish! system-bus ::m/worker-broadcast msg)
             (sys-bus/publish! system-bus [::m/worker-output build-id] msg))]
@@ -192,8 +197,7 @@

         (let [build-state
               (-> (util/new-build build-config mode {})
-                  (build-api/with-logger
-                    (util/async-logger log-chan))
+                  (build-api/with-logger build-logger)
                   (build/configure mode build-config {})
                   (build/compile)
                   (cond->
@@ -211,8 +215,7 @@
                     :report (binding [warnings/*color* false]
                               (errors/error-format e))
                     }))
-        (finally
-          (async/close! log-chan))))))
+        ))))

 (add-mutation 'shadow.cljs.ui.transactions/build-compile
   {::pc/input #{:build-id}


remove print statements

remove print statements

--- src/polismath/poller.clj
+++ src/polismath/poller.clj
@@ -111,7 +111,6 @@
                                    end (System/currentTimeMillis)
                                    duration (- end start)]
                                (metric "math.pca.compute.ok" duration)
-                               (pprint foo)
                                foo)))
                   (catch Exception e
                     (do
@@ -142,11 +141,9 @@
                   json (generate-string
                         (prep-for-uploading-bidToPid-mapping
                          (@conversations zid)))
-              obj (parse-string json)]
-
-              (println json)
-              (println
-               (meter
+                  obj (parse-string json)]
+
+              (meter
                 "db.math.bidToPid.put"
                 (mongo-upsert-results
                  "polismath_bidToPid_april9"
@@ -154,7 +151,7 @@
                  lastVoteTimestamp
                  (assoc obj
                    "lastVoteTimestamp" lastVoteTimestamp
-                   "zid" zid)))))
+                   "zid" zid))))

             ; Upload primary math results
             (let [
@@ -164,20 +161,16 @@
                         (prep-for-uploading-to-client
                          (@conversations zid)))
               obj (parse-string json)]
-
-              (println json)
-              ; (debug-repl)
-              (println
-               (meter
-                "db.math.pca.put"
-                (mongo-upsert-results
-                 "polismath_test_april9"
-                 zid
-                 lastVoteTimestamp
-                 (assoc obj
-                   "lastVoteTimestamp" lastVoteTimestamp
-                   "zid" zid)))))
-            )))
+              (meter
+               "db.math.pca.put"
+               (mongo-upsert-results
+                "polismath_test_april9"
+                zid
+                lastVoteTimestamp
+                (assoc obj
+                  "lastVoteTimestamp" lastVoteTimestamp
+                  "zid" zid)))
+              ))))


use-spec-cache? false by default

use-spec-cache? false by default

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -16,7 +16,7 @@
                         result))
 (def ^:dynamic truncate? false)
 (def ^:dynamic println? false)
-(def ^:dynamic use-spec-cache? true)
+(def ^:dynamic use-spec-cache? false)
 (declare gen)
 (declare get-lexemes)
 (declare grow)


warnings if no index is found

warnings if no index is found

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -110,13 +110,11 @@
           (when (= false (get-in spec [:head :phrasal] false))
             (lazy-mapcat
              (fn [parent]
-               (let [subset (if-let [index-fn (:index-fn language-model)]
-                              (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))
-                                  []))]
+               (let [lexicon (or (-> :generate :lexicon language-model) (:lexicon language-model))
+                     subset (if-let [index-fn (:index-fn language-model)]
+                              (index-fn (get-in parent [:head] :top))
+                              (do (log/warn (str "lightning-bolts: no index-fn for model:" (:name language-model) ": using entire lexicon."))
+                                  (flatten (vals lexicon))))]
                  (if (not (empty? subset))
                    (log/debug (str "lightning-bolts: " (get-in parent [:rule])
                                    " : (optimizeme) size of subset of candidate heads: "
@@ -227,7 +225,8 @@
             (do (log/debug (str "add-complement-to-bolt with bolt: " (show-bolt bolt language-model)
                                 " calling index-fn with spec: " spec ))
                 (index-fn spec))
-            (flatten (vals lexicon))))
+            (do (log/warn (str "add-complement-to-bolt: no index-fn for model:" (:name language-model) ": using entire lexicon."))
+                (flatten (vals lexicon)))))
         debug
         (log/trace (str "lexical-complements (pre-over):"
                         (string/join ","


s/8/6/

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -10,7 +10,7 @@

 ;; during generation, will not decend deeper than this when creating a tree:
 ;; TODO: should also be possible to override per-language.
-(def ^:const max-total-depth 8)
+(def ^:const max-total-depth 6)

 ;; TODO support setting max-generated-complements to :unlimited
 (def ^:const max-generated-complements 20000)


:bug: Fix wrong reference to component.

:bug: Fix wrong reference to component.

--- frontend/src/uxbox/main/ui/dashboard/projects.cljs
+++ frontend/src/uxbox/main/ui/dashboard/projects.cljs
@@ -85,7 +85,7 @@
 (mf/defc grid-item-thumbnail
   [{:keys [file] :as props}]
   [:div.grid-item-th
-   [:& exports/page-svg2 {:data (:data file)
+   [:& exports/page-svg {:data (:data file)
                           :width "290"
                           :height "150"}]])


more appropriate naming

more appropriate naming

--- test/benjaminwarfield/views_test.clj
+++ test/benjaminwarfield/views_test.clj
@@ -1,23 +0,0 @@
-(ns benjaminwarfield.views-test
-  (:use [kerodon.core]
-        [kerodon.test]
-        [clojure.test]
-        [benjaminwarfield.routes]))
-
-(deftest index-test
-  (-> (session app)
-      (visit "/")
-      (has (status? 200)
-          "Page was found")
-      (within [:.container :h1]
-        (has (text? "Benjamin Warfield Smith")
-            "Index page has expected text"))))
-
-(deftest four-oh-four-test
-  (-> (session app)
-      (visit "/404")
-      (has (status? 404)
-          "Page was not found")
-      (within [:.container :h1]
-        (has (text? "404 - U MAD?")
-            "404 page has expected text"))))


Release version 0.7.10.

Release version 0.7.10.

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject org.onyxplatform/onyx-metrics "0.7.10-SNAPSHOT"
+(defproject org.onyxplatform/onyx-metrics "0.7.10"
   :description "Instrument Onyx workflows"
   :url "https://github.com/MichaelDrogalis/onyx"
   :license {:name "Eclipse Public License"


Fix defroute structure.

Fix defroute structure.

--- src/ruuvi_server/api.clj
+++ src/ruuvi_server/api.clj
@@ -152,18 +152,16 @@
        (-> #'client-api/fetch-events))
   ;; Tracker-API
   (POST "/events" []
-        (-> #'tracker-api/handle-create-event))
+        (-> #'tracker-api/handle-create-event)))

-
-  (defroutes api-routes
-    (context url-prefix []
-             (-> api-routes-internal
-                 (wrap-keyword-params)
-                 (wrap-params)
-                 (wrap-json-params)
-                 (util/wrap-cors-headers)
-                 (util/wrap-exception-logging)
-                 (wrap-error-handling)
-                 (wrap-request-logger) ))
-    (fn [request] (util/json-error-response request "resource not found" 404)))
-    )+(defroutes api-routes
+  (context url-prefix []
+           (-> api-routes-internal
+               (wrap-keyword-params)
+               (wrap-params)
+               (wrap-json-params)
+               (util/wrap-cors-headers)
+               (util/wrap-exception-logging)
+               (wrap-error-handling)
+               (wrap-request-logger) ))
+  (fn [request] (util/json-error-response request "Resource not found" 404)))


OM-656

--- src/cellophane/next.clj
+++ src/cellophane/next.clj
@@ -131,10 +131,13 @@
     (map? x)))

 (defn- focused-join [expr ks]
-  (cond
-    (map? expr) {(ffirst expr) (focus-query (-> expr first second) ks)}
-    (seq? expr) (list (focused-join (first expr) ks) (second expr))
-    :else       expr))
+  (let [expr-meta (meta expr)
+        expr' (cond
+                (map? expr) {(ffirst expr) (focus-query (-> expr first second) ks)}
+                (seq? expr) (list (focused-join (first expr) ks) (second expr))
+                :else       expr)]
+    (cond-> expr'
+      (some? expr-meta) (with-meta expr-meta))))

 (defn focus-query
   "Given a query, focus it along the specified path.


Fail unless you supply credentials, see <https://apps.twitter.com/app/8673064/keys>

--- test/layzee/integration/twitter_examples.clj
+++ test/layzee/integration/twitter_examples.clj
@@ -3,14 +3,18 @@
   (:require [clojure.test :refer :all]
             [layzee.adapters.twitter :refer :all :as twitter]))

-(defn- env[name] (or (System/getenv name) "UNKNOWN"))
+(defn- fail[reason & args]
+  ((throw (Exception. (apply format reason args)))))
+
+(defn- env[name] (or (System/getenv name) (fail "You need to supply the <%s> environment variable" name)))
+
 (def ^{:private true} consumer-token
      {:key (env "TWITTER_CONSUMER_KEY") :secret (env "TWITTER_CONSUMER_SECRET")})

 (facts
- (fact "Can read the timeline"
+ (fact "Can read the timeline (and the oage size is 15)"
        (let [result (twitter/lazy-web consumer-token)]
-         (< 0 (count result)) => true)))
+         (count result) => 15)))

 (facts
  (fact "Each tweet contains the tag #lazyweb"


Deleted test

Deleted test

--- test/layzee/integration/twitter_examples.clj
+++ test/layzee/integration/twitter_examples.clj
@@ -8,13 +8,3 @@
  (fact "Can read the timeline (and the page size is 15)"
        (let [result (twitter/lazy-web settings/oauth-credential)]
          (count result) => 15)))
-
-(facts
- (fact "Each tweet contains the tag #lazyweb"
-       (let [result (first (twitter/lazy-web settings/oauth-credential))]
-         (.contains (.toLowerCase (:text result)) "#lazyweb") => true)))
-
-;(facts
-; (fact "Get replies to a tweet like this"
-;       (let [result (first (twitter/replies settings/consumer-token "633472387497902080"))]
-;         (println result))))


Use co-dependency in system

Use co-dependency in system

--- lein-template/src/leiningen/new/modular/system.clj
+++ lein-template/src/leiningen/new/modular/system.clj
@@ -7,7 +7,7 @@
    [clojure.string :as str]
    [clojure.tools.reader.reader-types :refer (indexing-push-back-reader)]
    [com.stuartsierra.component :refer (system-map system-using using)]
-   [tangrammer.component.co-dependency :refer (co-using)]
+   [tangrammer.component.co-dependency :refer (co-using system-co-using)]
    [modular.maker :refer (make)]
    {{#refers}}
    [{{namespace}} :refer ({{{refers}}})]
@@ -85,4 +85,5 @@
   "Create the production system"
   []
   (-> (new-system-map (config))
-      (system-using (new-dependency-map))))
+      (system-using (new-dependency-map))
+      (system-co-using (new-co-dependency-map))))


Rename ui-root to root

Rename ui-root to root

--- desktop/src/nightmod/core/desktop_launcher.clj
+++ desktop/src/nightmod/core/desktop_launcher.clj
@@ -87,7 +87,7 @@
   [& args]
   (window/set-theme! args)
   (s/invoke-later
-    (s/show! (reset! ui/ui-root (create-window)))
+    (s/show! (reset! ui/root (create-window)))
     (binding [editors/*editor-widgets* editor-widgets]
       (reset! ui/tree-selection "")))
   (Keyboard/enableRepeatEvents true))


Add new conf-web.edn conf file handling.

--- src/clj/aspire/conf.clj
+++ src/clj/aspire/conf.clj
@@ -3,12 +3,15 @@
             [clojure.edn :as edn])
   (:import [java.io File]))

-(def confdir "/etc/aspire/")
+(def confdir "/etc/aspire")

 ;; The --long-opt for each conf file must match the :conf-key.
 (def configs {:conf-sql-db
               {:file "conf-sql-db.edn"
-               :opts ["-s" "--conf-sql-db"]}})
+               :opts ["-s" "--conf-sql-db"]}
+              :conf-web
+              {:file "conf-web.edn"
+               :opts ["-w" "--conf-web"]}})

 (defn confpath-default [configs conf-key]
   (str confdir "/" (:file (configs conf-key))))


continuing to remove

continuing to remove

--- src/clj/speclj/core.clj
+++ src/clj/speclj/core.clj
@@ -161,7 +161,7 @@
          (-fail (str "Expected: " (-to-s expected#) speclj.platform/endl "     got: " (-to-s actual#) " (using =)")))))
   ([expected-form actual-form delta-form]
     `(let [expected# ~expected-form actual# ~actual-form delta# ~delta-form]
-       (when (platform-macros/expected-larger-than-delta expected# actual# delta#)
+       (when (speclj.platform/expected-larger-than-delta expected# actual# delta#)
          (-fail (str "Expected: " (-to-s expected#) speclj.platform/endl "     got: " (-to-s actual#) " (using delta: " delta# ")"))))))

 (defmacro should-be


Optimize count for arrays and strings, fix bug in nth incorrect handling of IIndexed on native types

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -728,9 +728,6 @@
      (prim-seq array i)))

 (extend-type array
-  ICounted
-  (-count [a] (alength a))
-
   IReduce
   (-reduce [col f] (array-reduce col f))
   (-reduce [col f start] (array-reduce col f start)))
@@ -841,9 +838,22 @@
   "Returns the number of items in the collection. (count nil) returns
   0.  Also works on strings, arrays, and Maps"
   [coll]
-  (if (counted? coll)
-    (-count coll)
-    (accumulating-seq-count coll)))
+  (if-not (nil? coll)
+    (cond
+      (satisfies? ICounted coll false)
+      (-count ^not-native coll)
+
+      (array? coll)
+      (alength coll)
+
+      (string? coll)
+      (alength coll)
+
+      (type_satisfies_ ICounted coll)
+      (-count coll)
+
+      :else (accumulating-seq-count coll))
+    0))

 (defn- linear-traversal-nth
   ([coll n]
@@ -883,6 +893,9 @@
          (string? coll)
          (when (< n (.-length coll))
            (aget coll n))
+
+         (type_satisfies_ IIndexed coll)
+         (-lookup coll n)

          :else
          (linear-traversal-nth coll (.floor js/Math n)))))
@@ -902,6 +915,9 @@
            (aget coll n)
            not-found)

+         (type_satisfies_ IIndexed coll)
+         (-lookup coll n)
+
          :else
          (linear-traversal-nth coll (.floor js/Math n) not-found))
        not-found)))
@@ -2003,10 +2019,7 @@

 (extend-type string
   IHash
-  (-hash [o] (goog.string/hashCode o))
-
-  ICounted
-  (-count [s] (alength s)))
+  (-hash [o] (goog.string/hashCode o)))

 (deftype Keyword [k]
   IFn


Calling watches after the value change and returning the new value.  Modified the validator fail to throw js/Error instead of string.  Finally, modified docs to be more Cljs relevant.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -2766,7 +2766,7 @@
   atom. validate-fn must be nil or a side-effect-free fn of one
   argument, which will be passed the intended new state on any state
   change. If the new state is unacceptable, the validate-fn should
-  return false or throw an exception."
+  return false or throw an Error."
   ([x] (Atom. x nil nil nil))
   ([x & {:keys [meta validator]}] (Atom. x meta validator nil)))

@@ -2776,9 +2776,10 @@
   [a newval]
   (when-let [v (.validator a)]
     (when-not (v newval)
-      (throw "Validator rejected reference state")))
+      (throw (js/Error. "Validator rejected reference state"))))
+  (set! (.state a) newval)
   (-notify-watches a (.state a) newval)
-  (set! (.state a) newval))
+  newval)

 (defn swap!
   "Atomically swaps the value of atom to be:
@@ -2813,12 +2814,12 @@
   (-deref o))

 (defn set-validator!
-  "Sets the validator-fn for a var/ref/agent/atom. validator-fn must be nil or a
+  "Sets the validator-fn for an atom. validator-fn must be nil or a
   side-effect-free fn of one argument, which will be passed the intended
   new state on any state change. If the new state is unacceptable, the
-  validator-fn should return false or throw an exception. If the current state (root
-  value if var) is not acceptable to the new validator, an exception
-  will be thrown and the validator will not be changed."
+  validator-fn should return false or throw an Error. If the current state
+  is not acceptable to the new validator, an Error will be thrown and the
+  validator will not be changed."
   [iref val]
   (set! (.validator iref) val))

@@ -2837,7 +2838,7 @@
   (set! (.meta iref) (apply f (.meta iref) args)))

 (defn reset-meta!
-  "Atomically resets the metadata for a namespace/var/ref/agent/atom"
+  "Atomically resets the metadata for an atom"
   [iref m]
   (set! (.meta iref) m))

@@ -2848,10 +2849,9 @@
   fn of 4 args: a key, the reference, its old-state, its
   new-state. Whenever the reference's state might have been changed,
   any registered watches will have their functions called. The watch
-  fn will be called synchronously. Note that an atom's or ref's state
+  fn will be called synchronously. Note that an atom's state
   may have changed again prior to the fn call, so use old/new-state
-  rather than derefing the reference. Note also that watch fns may be
-  called from multiple threads simultaneously. Keys must be unique per
+  rather than derefing the reference. Keys must be unique per
   reference, and can be used to remove the watch with remove-watch,
   but are otherwise considered opaque by the watch mechanism."
   [iref key f]


It makes sense for this to be case-insensitive

--- src/cljs_rest/core.cljs
+++ src/cljs_rest/core.cljs
@@ -120,7 +120,7 @@
     m))

 (def link-pattern
-  #"<(.*?)>; rel=\"(.*?)\"")
+  #"(?i)<(.*?)>; rel=\"(.*?)\"")

 (defn parse-url-query-params [url]
   (let [uri (uri/parse url)


Avoid `apply` on lua calls

Avoid `apply` on lua calls

Micro-optimisation

--- src/taoensso/carmine.clj
+++ src/taoensso/carmine.clj
@@ -154,25 +154,31 @@

 (def script-hash (memoize (fn [script] (sha1-str script))))

+(defn- -evalsha* [script numkeys args]
+  (redis-call (into [:evalsha (script-hash script) numkeys] args)))
+
 (defn evalsha* "Like `evalsha` but automatically computes SHA1 hash for script."
-  [script numkeys & args] (apply evalsha (script-hash script) numkeys args))
-
-(defn eval*
-  "Optimistically tries to send `evalsha` command for given script. In the event
-  of a \"NOSCRIPT\" reply, reattempts with `eval`. Returns the final command's
-  reply. Redis Cluster note: keys need to all be on same shard."
-  [script numkeys & args]
+  [script numkeys & args] (-evalsha* script numkeys args))
+
+(defn- -eval* [script numkeys args]
   (let [parser ; Respect :raw-bulk, otherwise ignore parser:
         (if-not (:raw-bulk? (meta protocol/*parser*))
           nil ; As `parse-raw`:
           (with-meta identity {:raw-bulk? true}))
         [r & _] ; & _ for :as-pipeline
         (parse parser (with-replies :as-pipeline
-                        (apply evalsha* script numkeys args)))]
+                        (-evalsha* script numkeys args)))]
+
     (if (= (:prefix (ex-data r)) :noscript)
       ;;; Now apply context's parser:
-      (apply eval script numkeys args)
+      (redis-call (into [:eval script numkeys] args))
       (return r))))
+
+(defn eval*
+  "Optimistically tries to send `evalsha` command for given script. In the event
+  of a \"NOSCRIPT\" reply, reattempts with `eval`. Returns the final command's
+  reply. Redis Cluster note: keys need to all be on same shard."
+  [script numkeys & args] (-eval* script numkeys args))

 (comment
   (wcar {} (redis-call ["eval" "return 10;" 0]))


fix typo

fix typo

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -779,7 +779,7 @@
      conditions)))

 (defn query
-  "Retries items from a table (indexed) with options:
+  "Retrieves items from a table (indexed) with options:
     prim-key-conds - {<key-attr> [<comparison-operator> <val-or-vals>] ...}.
     :last-prim-kvs - Primary key-val from which to eval, useful for paging.
     :span-reqs     - {:max _ :throttle-ms _} controls automatic multi-request


Use procedures for creating harmony

Use procedures for creating harmony

--- src/tenor/constructs.clj
+++ src/tenor/constructs.clj
@@ -151,9 +151,10 @@

 ;; --- Chords --- ;;

-(defn chordify [entity-map]
+(defn chordify [entity-map construct-harmony]
   "Pick random notes from an entity map to assign chords."
-  (filter (fn [x] (weighted-coin 0.2)) entity-map))
+  (filter (fn [x] (not (nil? x)))
+          (map #(construct-harmony (:pos %) (:note %)) entity-map)))

 ;; --- Playback --- ;;


Separate handle-unselected from handle-editing

--- src/constraint/edit.cljs
+++ src/constraint/edit.cljs
@@ -1,5 +1,6 @@
 (ns constraint.edit
-  (:require [constraint.common :refer [edge-id]]))
+  (:require [constraint.common :refer [edge-id
+                                       vert-id]]))

 (def edge-id-len (count edge-id))

@@ -62,22 +63,33 @@
       (toggle-vertex-size selected world-state)
       (add-or-delete-edge selected clicked-vertex world-state))))

+(def vertex-regex (re-pattern (str vert-id ".*")))
+(def edge-regex (re-pattern (str edge-id ".*")))

 (defn handle-selected [clicked-what event world-state]
-  (let [clicked-vertex? (re-matches #"vertex.*" clicked-what)]
+  (let [clicked-vertex? (re-matches vertex-regex clicked-what)]
     (if clicked-vertex?
       (edit-vertex-or-connections clicked-what world-state)
       (move-the-vertex event world-state))))

+(defn select-vertex [world-state clicked-vertex]
+  (merge world-state {:selected clicked-vertex}))
+
+(defn toggle-edge-value [world-state clicked-edge]
+  (let [clicked-edge-color [:edges clicked-edge 2]
+        toggle-color {:red :blue :blue :red}]
+    (update-in world-state clicked-edge-color toggle-color)))
+
+(defn handle-unslected [clicked-what world-state]
+  (let [clicked-edge? (re-matches edge-regex clicked-what)
+        clicked-vertex? (re-matches vertex-regex clicked-what)]
+    (cond
+        clicked-edge? (toggle-edge-value world-state clicked-what)
+        clicked-vertex? (select-vertex world-state clicked-what)
+        :else world-state)))

 (defn handle-editing [clicked-what event world-state]
-  (let [unselect #(merge % {:selected nil})
-        clicked-edge? (re-matches #"edge.*" clicked-what)
-        clicked-vertex? (re-matches #"vertex.*" clicked-what) ]
+  (let [unselect #(merge % {:selected nil})]
     (if (:selected world-state)
       (unselect (handle-selected clicked-what event world-state))
-      (cond
-        clicked-edge? (update-in world-state [:edges clicked-what 2]
-                                 #(if (= :blue %) :red :blue))
-        clicked-vertex? (merge world-state {:selected clicked-what})
-        :else world-state))))
+      (handle-unslected clicked-what world-state))))


qualify :serialized with :dag_unify.core

--- src/babel/over.cljc
+++ src/babel/over.cljc
@@ -191,7 +191,7 @@
          (log/debug (str "overh: " (get-in parent [:rule]) " -> " (get-in head [:rule]
                                                                         (get-in head [:synsem :sem :pred]
                                                                                "(no pred for head)"))))
-         (log/trace (str "overh successful result: " (strip-refs (dissoc result :serialized))))
+         (log/trace (str "overh successful result: " (strip-refs (dissoc result :dag_unify.core/serialized))))
          (list result))))))

 ;; Haskell-looking signature:
@@ -282,9 +282,10 @@
         nil

         (and (map? parents)
-             (not (nil? (:serialized parents))))
+             (not (nil? (:dag_unify.core/serialized parents))))
         ;; In this case, supposed 'parent' is really a lexical item: for now, definition of 'lexical item' is,
-        ;; it has a non-nil value for :serialized - just return nil, nothing else to do.
+        ;; it has a non-nil value for :dag_unify.core/serialized - just return nil, nothing else to do.
+        ;; TODO: above test of 'lexical item' is not right: a parent might very well have a :serialized key.
         (throw (exception (str "Don't know what to do with this parent: " parents)))

         ;; if parent is a symbol, evaluate it; should evaluate to a list of expansions (which might also be symbols, etc).
@@ -292,7 +293,7 @@
         #?(:clj (over (eval parents) child1 child2))

         true
-        (let [parent (first parents)]
+        (let [parent (first parents)] ;; TODO: use recur
           (cond
             (nil? (get-in parent [:schema-symbol] nil))
             (throw (exception (str "no schema symbol for parent: " (:rule parent))))
@@ -379,8 +380,8 @@

 (defn truncate [input truncate-paths language-model]
   (log/debug (str "truncating@" truncate-paths ":" (show-bolt input language-model)))
-  (let [serialized (if (:serialized input)
-                     (:serialized input)
+  (let [serialized (if (:dag_unify.core/serialized input)
+                     (:dag_unify.core/serialized input)
                      (serialize input))
         paths-and-vals (rest serialized)
         path-sets (mapfn first paths-and-vals)


Allow inline typehinting for assoc-record

--- src/useful/datatypes.clj
+++ src/useful/datatypes.clj
@@ -39,14 +39,17 @@
                        (into-map attrs))]
     `(new ~type ~@vals)))

-(defn- type-hint [^Compiler$LocalBinding binding]
-  (and binding (.hasJavaClass binding) (.getJavaClass binding)))
+(defn- type-hint [form &env fn-name]
+  (or (:tag (meta form))
+      (let [^Compiler$LocalBinding binding (get &env form)]
+        (and binding (.hasJavaClass binding) (.getJavaClass binding)))
+      (throw (Exception. (str "type hint required on record to use " fn-name)))))

 (defmacro assoc-record
   "Assoc attrs into a record. Mapping fields into constuctor arguments is done at compile time,
    so this is more efficient than calling assoc on an existing record."
   [record & attrs]
-  (let [type   (or (type-hint (get &env record)) (throw (Exception. "type hint required on record to use assoc-record")))
+  (let [type   (type-hint record &env 'assoc-record)
         fields (record-fields type)
         index  (position fields)
         vals   (reduce (fn [vals [field val]]
@@ -63,7 +66,7 @@
   into constuctor arguments is done at compile time, so this is more efficient than calling assoc on
   an existing record."
   [record & forms]
-  (let [type   (or (type-hint (get &env record)) (throw (Exception. "type hint required on record to use update-record")))
+  (let [type   (type-hint record &env 'update-record)
         fields (record-fields type)
         index  (position fields)
         vals   (reduce (fn [vals [f field & args]]


Add doc strings.

Add doc strings.

--- src/cli4clj/cli.clj
+++ src/cli4clj/cli.clj
@@ -176,7 +176,11 @@
           :help {:short-info "Show help."
                  :long-info "Display a help text that lists all available commands including further detailed information about these commands."}}})

-(defmulti print-err-fn (fn [arg] (instance? Exception arg)))
+(defmulti print-err-fn
+  "This is the default function for printing error messages.
+   If the supplied argument is an exception, the exception message will be printed to stderr.
+   Otherwise, the string representation of the passed argument is printed to stderr."
+  (fn [arg] (instance? Exception arg)))
 (defmethod print-err-fn true [arg]
   (println-err (.getMessage arg)))
 (defmethod print-err-fn false [arg]
@@ -243,6 +247,9 @@
   (add-args-info opts))

 (defmacro start-cli
+  "This is the primary entry point for starting and configuring cli4clj.
+   Please note that the configuration options can also be defined in a global or local var.
+   However, in order to lookup arguments defined in anonymous functions, the configuration options have to be defined directly in the function call."
   ([]
     (start-cli {}))
   ([user-options]
@@ -257,23 +264,28 @@

 (defn cmd-vector-to-test-input-string
+  "This function takes a vector of string commands and creates a one-line command that is suited to being passed to a cli instance during testing."
   [cmd-vec]
   (reduce (fn [s c] (str s c "\n")) "" cmd-vec))

 (defn create-repl-read-test-fn
+  "This function creates a repl read function for testing."
   [cmds prompt-string]
   (create-repl-read-fn cmds))

 (defn exec-tested-fn
+  "This function takes another function as argument and executes it in a way that is suited for testing."
   [tested-fn]
   (binding [*read-factory* create-repl-read-test-fn]
     (tested-fn)))

 (defn test-cli-stdout
+  "Takes a function to be tested and a vector of string input commands and returns the string that was printed to stdout as a result of executing the supplied commands in the cli provided by the tested-fn."
   [tested-fn in-cmds]
   (.trim (with-out-str (with-in-str (cmd-vector-to-test-input-string in-cmds) (exec-tested-fn tested-fn)))))

 (defn test-cli-stderr
+  "Takes a function to be tested and a vector of string input commands and returns the string that was printed to stderr as a result of executing the supplied commands in the cli provided by the tested-fn."
   [tested-fn in-cmds]
   (.trim (with-err-str (with-out-str (with-in-str (cmd-vector-to-test-input-string in-cmds) (exec-tested-fn tested-fn))))))


Remove superfluous try/catch block.

Remove superfluous try/catch block.

--- src/cli4clj/cli.clj
+++ src/cli4clj/cli.clj
@@ -142,16 +142,13 @@
             (.addCompleter in-rdr compl))
         rdr-fn (create-repl-read-fn opts)]
     (fn [request-prompt request-exit]
-      (try
-        (let [line (.readLine in-rdr)]
-          (if (and (not (nil? line))
-                   (not (.isEmpty line))
-                   (not (-> line (.trim) (.startsWith *comment-begin-string*))))
-            (binding [*in* (PushbackReader. (StringReader. (str line *cli4clj-line-sep*)))]
-              (rdr-fn request-prompt request-exit))
-            request-prompt))
-        (catch Exception e
-          (err-fn e opts))))))
+      (let [line (.readLine in-rdr)]
+        (if (and (not (nil? line))
+                 (not (.isEmpty line))
+                 (not (-> line (.trim) (.startsWith *comment-begin-string*))))
+          (binding [*in* (PushbackReader. (StringReader. (str line *cli4clj-line-sep*)))]
+            (rdr-fn request-prompt request-exit))
+          request-prompt)))))

 (defn resolve-cmd-alias
   "This function is used to resolve the full command definition for a given command alias.


bumped up cljs/figwheel

bumped up cljs/figwheel

--- resources/leiningen/new/reagent_frontend/project.clj
+++ resources/leiningen/new/reagent_frontend/project.clj
@@ -5,11 +5,11 @@
             :url "http://www.eclipse.org/legal/epl-v10.html"}

   :dependencies [[org.clojure/clojure "1.8.0" :scope "provided"]
-                 [org.clojure/clojurescript "1.9.92" :scope "provided"]
+                 [org.clojure/clojurescript "1.9.93" :scope "provided"]
                  [reagent "0.6.0-rc"]]

   :plugins [[lein-cljsbuild "1.1.3"]
-            [lein-figwheel "0.5.4-4"]]
+            [lein-figwheel "0.5.4-5"]]

   :min-lein-version "2.5.0"

@@ -46,6 +46,6 @@

   :aliases {"release" ["do" "clean" ["cljsbuild" "once" "release"]]}

-  :profiles {:dev {:dependencies [[figwheel-sidecar "0.5.4-4"]
+  :profiles {:dev {:dependencies [[figwheel-sidecar "0.5.4-5"]
                                   [org.clojure/tools.nrepl "0.2.12"]
                                   [com.cemerick/piggieback "0.2.2-SNAPSHOT"]]}})


Tones linear test to run within 1 min.

Tones linear test to run within 1 min.

--- test/onyx/peer/simulant/linear_cluster_sim.clj
+++ test/onyx/peer/simulant/linear_cluster_sim.clj
@@ -14,7 +14,7 @@

 (def out-queue (str (java.util.UUID/randomUUID)))

-(def n-messages 2000)
+(def n-messages 40000)

 (def batch-size 1320)

@@ -147,7 +147,7 @@
 (def linear-cluster-model-data
   [{:db/id linear-model-id
     :model/type :model.type/linear-cluster
-    :model/peek-peers 4
+    :model/peek-peers 5
     :model/peer-rate 200
     :model/silence-gap 5000}])

@@ -173,7 +173,7 @@
   (sim/create-test sim-conn
                    linear-cluster-model
                    {:db/id (d/tempid :test)
-                    :test/duration (u/hours->msec 1)}))
+                    :test/duration 60000}))

 (def linear-cluster-sim
   (sim/create-sim sim-conn
@@ -186,7 +186,7 @@

 (sim/create-action-log sim-conn linear-cluster-sim)

-(doseq [n (range 2)]
+(doseq [n (range 3)]
   (swap! cluster conj (onyx.api/start-peers conn 1 peer-opts)))

 (def pruns


CMR-4586: Searching for invalid /search/services endpoint returns 500 error.

--- search-app/src/cmr/search/api/concepts_search.clj
+++ search-app/src/cmr/search/api/concepts_search.clj
@@ -146,7 +146,7 @@

 (def search-routes
   "Routes for /search/granules, /search/collections, etc."
-  (context ["/:path-w-extension" :path-w-extension #"(?:(?:granules)|(?:collections)|(?:variables)|(?:services))(?:\..+)?"] [path-w-extension]
+  (context ["/:path-w-extension" :path-w-extension #"(?:(?:granules)|(?:collections)|(?:variables))(?:\..+)?"] [path-w-extension]
     (OPTIONS "/" req common-routes/options-response)
     (GET "/"
       {params :params headers :headers ctx :request-context query-string :query-string}