update dev/user.clj

update dev/user.clj

--- dev/user.clj
+++ dev/user.clj
@@ -6,6 +6,7 @@
             [polismath.math.conversation :as conv]
             [polismath.components.postgres :as postgres]
             [polismath.math.named-matrix :as nm]
+            [honeysql.core :as honey]
             [clojure.core.matrix :as matrix]
             [clojure.core.async :as async :refer [>! <! >!! <!! go go-loop thread]]
             [environ.core :as env]
@@ -30,9 +31,12 @@
 (comment
   ;; Run one of these to interactively test out a particular system or subsystem
   (runner/stop!)
-  ;(runner/run! system/base-system)
-  (runner/run! system/task-system)
-  (runner/run! system/task-system {:math-env :preprod :poll-from-days-ago 0.1})
+  (runner/run! system/base-system {:math-env :prod})
+  ;(runner/run! system/task-system)
+  ;(runner/run! system/task-system {:math-env :preprod :poll-from-days-ago 0.1})
+  ;(runner/run! system/full-system {:math-env :preprod :poll-from-days-ago 0.1})
+  ;(runner/run! system/full-system {:math-env :dev :poll-from-days-ago 0.1})
+  ;(runner/run! system/full-system {:math-env :preprod})
   ;(runner/run! system/darwin-system)
   ;(runner/run! system/full-system {:poll {:poll-from-days-ago 0.1}})

@@ -43,13 +47,13 @@

   ;; Setting up load and interactive testing for a specific conversation
-  (def args {:zid 11547})
+  (def args {:zid 16906})
+  (def conv
+    (-> (load-conv args)
+        (conv/conv-update [])))
   (def conv
     (-> (load-conv args)
         (conv/conv-update [{:zid 11547 :pid 0 :tid 0 :vote 2.0 :created (System/currentTimeMillis)}])))
-  (keys (:pca conv))
-  (:comps (:pca conv))
-  (:comment-projection (:pca conv))

   (def updated-conv
     (-> conv
@@ -72,8 +76,42 @@
     (:subgroup-clusters updated-conv'))
     ;(:repness updated-conv'))

-  ;(get-conv args)
+
+  ;; Postgres/db testbench
+  (postgres/query
+    (:postgres runner/system)
+    ["select * from votes
+      limit 10;"])
+
+  (postgres/query
+    (:postgres runner/system)
+    ["select * from votes
+      where zid = ?;"
+     4])
+
+  (postgres/query
+    (:postgres runner/system)
+    (honey/format
+      {:select [:*]
+       :from [:votes]
+       :limit 10}))
+
+
+  ;; Debugging issue
+  (postgres/query
+    (:postgres runner/system)
+    (honey/format
+      {:select [:*]
+       :from [:math_tasks]
+       :limit 10}))
+
+
+  ;; Getting config settings
   (-> runner/system :config)
+  (-> runner/system :config :webserver-url)
+
+  (-> runner/system :config :darwin)
+  (-> runner/system :config :darwin :webserver-url)
   (-> runner/system :conversation-manager :conversations deref)


replaced $push with $addToSet

replaced $push with $addToSet

--- src/foreclojure/problems.clj
+++ src/foreclojure/problems.clj
@@ -46,7 +46,7 @@
         (if user
           (do
             (when (not-any? #{id} (get-solved user))
-              (update! :users {:user user} {:$push {:solved id}})
+              (update! :users {:user user} {:$addToSet {:solved id}})
               (update! :problems {:_id id} {:$inc {:times-solved 1}}))
             "Congratulations, you've solved the problem!")
           "You've solved the problem! If you log in we can track your progress.")]


wip: new introspection resolvers

wip: new introspection resolvers

--- src/graphql_clj/resolver.clj
+++ src/graphql_clj/resolver.clj
@@ -47,24 +47,59 @@
                                         (:required inner-type) (introspection/type-resolver inner-type)
                                         (get-in inner-type [:type-name]) (introspection/type-resolver (get-type-in-schema schema (get-in inner-type [:type-name])))
                                         inner-type (introspection/type-resolver inner-type)
-                                        :default (throw (ex-info (format "Unable to process ofType for: %s." parent) {})))))
-                         "fields" (fn [context parent args]
-                                    (map introspection/field-resolver (:fields parent)))
-                         "enumValues" (fn [context parent args]
-                                        (map introspection/enum-resolver (:enumValues parent)))
-                         "inputFields" (fn [context parent args]
-                                         (map introspection/input-field-resolver (:inputFields parent)))}
-               "__Field" {"type" (fn [context parent args]
+                                        :default (throw (ex-info (format "Unable to process ofType for: %s." parent) {})))))}
+               "__Field" {"name" (fn [context parent args]
+                                   (:name parent))
+                          "description" (fn [context parent args]
+                                          (:description parent))
+                          "args" (fn [context parent args]
+                                   (:arguments parent))
+                          "type" (fn [context parent args]
                                    ;; (cond
                                    ;;   (:required parent) (introspection/type-resolver parent)
                                    ;;   (t:inner-ype parent) (introspection/type-resolver parent)
                                    ;;   (:type-name parent) (introspection/type-resolver parent)
                                    ;;   :default (throw (ex-info (format "Unhandled type: %s" parent) {})))
-                                   (introspection/type-resolver parent))
-                          "args" (fn [context parent args]
-                                   (map introspection/args-resolver (:args parent)))}
-               "__InputValue" {"type" (fn [context parent args]
-                                        (introspection/type-resolver parent))}}
+                                   ;; (prn "type parent:" parent)
+                                   (:type parent))
+                          "isDeprecated" (fn [context parent args]
+                                           ;; TODO
+                                           false)
+                          "deprecationReason" (fn [context parent args]
+                                                ;; TODO
+                                                nil)
+                          ;; "args" (fn [context parent args]
+                          ;;          (map introspection/args-resolver (:args parent)))
+                          }
+               "__InputValue" {"name" (fn [context parent args]
+                                        (:name parent))
+                               "description" (fn [context parent args]
+                                               (:description parent))
+                               "type" (fn [context parent args]
+                                        (:type parent))
+                               "defaultValue" (fn [context parent args]
+                                                ;; (prn "defaultValue parent:" parent)
+                                                (get-in parent [:default-value :value]))}
+               "__EnumValue" {"name" (fn [context parent args]
+                                       (:name parent))
+                              "description" (fn [context parent args]
+                                              (:description parent))
+                              "isDeprecated" (fn [context parent args]
+                                               ;; TODO
+                                               nil)
+                              "deprecationReason" (fn [context parent args]
+                                                    ;; TODO
+                                                    nil)}
+               "__Directive" {"name" (fn [context parent args]
+                                       (:name parent))
+                              "description" (fn [context parent args]
+                                              (:description parent))
+                              "locations" (fn [context parent args]
+                                            ;; TODO
+                                            nil)
+                              "args" (fn [context parent args]
+                                       ;; TODO
+                                       nil)}}
               [type-name field-name])
       )))

@@ -75,3 +110,5 @@
       (or (and resolver-fn (resolver-fn type-name field-name))
           (schema-resolver-fn type-name field-name)
           (default-resolver-fn type-name field-name)))))
+
+;; (def intro-str "query {__schema { types {name}}}")


Made things faster

Made things faster

--- src/hitchhiker/tree/core.clj
+++ src/hitchhiker/tree/core.clj
@@ -4,6 +4,7 @@
             [taoensso.nippy :as nippy]
             [clojure.pprint :as pp])
   (:import java.io.Writer
+           java.util.Arrays
            java.util.Collections))

 (defrecord Config [index-b data-b op-buf-size])
@@ -83,7 +84,11 @@
 (extend-protocol IKeyCompare
   ;; By default, we use the default comparator
   Object
-  (compare [key1 key2] (clojure.core/compare key1 key2)))
+  (compare [key1 key2] (clojure.core/compare key1 key2))
+  Double
+  (compare [^Double key1 key2] (.compareTo key1 key2))
+  Long
+  (compare [^Long key1 key2] (.compareTo key1 key2)))

 ;; TODO enforce that there always (= (count children) (inc (count keys)))
 ;;
@@ -130,7 +135,12 @@
                  (catvec op-buf (:op-buf other))
                  cfg))
   (lookup [root key]
-    (let [x (Collections/binarySearch (index-node-keys children) key compare)]
+    ;;This is written like so because it's performance critical
+    (let [l (dec (count children))
+          a (object-array l)
+          _ (dotimes [i l]
+              (aset a i (last-key (nth children i))))
+          x (Arrays/binarySearch a 0 l key compare)]
       (if (neg? x)
         (- (inc x))
         x))))
@@ -215,8 +225,8 @@
   (underflow? [this]
     (< (count children) (:data-b cfg)))
   (split-node [this]
-    (->Split (data-node cfg (into (sorted-set) (take (:data-b cfg)) children))
-             (data-node cfg (into (sorted-set) (drop (:data-b cfg)) children))
+    (->Split (data-node cfg (into (sorted-set-by compare) (take (:data-b cfg)) children))
+             (data-node cfg (into (sorted-set-by compare) (drop (:data-b cfg)) children))
              (nth-of-set children (dec (:data-b cfg)))))
   (merge-node [this other]
     (data-node cfg (into children (:children other))))
@@ -369,7 +379,7 @@
 (defn insert
   [{:keys [cfg] :as tree} key]
   (let [path (lookup-path tree key) ; don't care about the found key or its index
-        {:keys [children] :or {children (sorted-set)}} (peek path)
+        {:keys [children] :or {children (sorted-set-by compare)}} (peek path)
         updated-data-node (data-node cfg (conj children key))]
     (loop [node updated-data-node
            path (pop path)]
@@ -402,7 +412,7 @@
 (defn delete
   [{:keys [cfg] :as tree} key]
   (let [path (lookup-path tree key) ; don't care about the found key or its index
-        {:keys [children] :or {children (sorted-set)}} (peek path)
+        {:keys [children] :or {children (sorted-set-by compare)}} (peek path)
         updated-data-node (data-node cfg (disj children key))]
     (loop [node updated-data-node
            path (pop path)]
@@ -451,7 +461,7 @@

 (defn b-tree
   [cfg & keys]
-  (reduce insert (data-node cfg (sorted-set)) keys))
+  (reduce insert (data-node cfg (sorted-set-by compare)) keys))

 (defrecord TestingAddr [last-key node]
   IResolve


support compiling against dev code

support compiling against dev code

--- src/cake/ant.clj
+++ src/cake/ant.clj
@@ -94,7 +94,7 @@
     path))

 (defn classpath [& paths]
-  (apply path "src" "lib/*" paths))
+  (apply path "src" "lib/*" "dev" "lib/dev/*" paths))

 (defn args [task & args]
   (doseq [a (remove nil? (flatten args))]


Mark some functions private

Mark some functions private

--- src/io/aviso/twixt/rhino.clj
+++ src/io/aviso/twixt/rhino.clj
@@ -6,13 +6,13 @@
             [io.aviso.twixt.tracker :as tracker]))

-(defn load-script [context scope file]
+(defn- load-script [context scope file]
   (with-open [content-reader (-> file io/resource io/reader)]
     (tracker/trace
      (str "Loading JavaScript from " file)
      (.evaluateReader context scope content-reader file 1 nil))))

-(defn invoke-function [context scope function-name arguments]
+(defn- invoke-function [context scope function-name arguments]
   (let [js-fn (.get scope function-name scope)]
     (.call js-fn context scope nil (into-array arguments))))


chat: hide emoji keyboard when tapping inside chat

--- src/status_im/chat/views/message/message.cljs
+++ src/status_im/chat/views/message/message.cljs
@@ -390,7 +390,10 @@
        :reagent-render
        (fn [{:keys [outgoing group-chat content-type content] :as message}]
          [message-container message
-          [touchable-highlight {:on-press #(when platform/ios? (dismiss-keyboard!))
+          [touchable-highlight {:on-press #(when platform/ios?
+                                             (dispatch [:set-chat-ui-props
+                                                        {:show-emoji? false}])
+                                             (dismiss-keyboard!))
                                 :on-long-press #(cond (= content-type text-content-type)
                                                       (share content (label :t/message))
                                                       (and (= content-type content-type-command) (= "location" (:content-command content)))


Remove redundant vec call

Remove redundant vec call

--- src/test/clojure/clojure/test/check/test.cljc
+++ src/test/clojure/clojure/test/check/test.cljc
@@ -92,7 +92,7 @@

 (defn first-is-gone
   [l]
-  (not (some #{(first l)} (vec (rest l)))))
+  (not (some #{(first l)} (rest l))))

 (deftest bad-remove
   (testing "For all vectors L, if we remove the first element E, E should not


Update garden

Update garden

--- dev/garden_development.clj
+++ dev/garden_development.clj
@@ -37,7 +37,7 @@
 (defrecord GardenServer [builds]
   component/Lifecycle
   (start [component]
-    (println "Start garden for builds" builds)
+    (println "Start garden for builds" (map #(:id %) builds))
     (compile-builds builds)
     component)
   (stop [component]


Make port configurable and add main function.

--- src/boss_work_manager_configuration/app.clj
+++ src/boss_work_manager_configuration/app.clj
@@ -37,7 +37,10 @@
         (wrap-data {::model model ::real-chains real-chains}))))

 (defn run-web-app
-  []
+  [port]
   (jetty/run-jetty (web-app "resources/class-names")
-                   {:port 8080
+                   {:port port
                     :join? false}))
+
+(defn -main [port]
+  (run-web-app (Integer. port)))


Generalized weapon system

Generalized weapon system

--- src/asteroids/core.clj
+++ src/asteroids/core.clj
@@ -7,13 +7,12 @@
            (java.awt.event ActionListener KeyListener)
            (javax.sound.sampled AudioSystem FloatControl$Type))
   (:require [asteroids.matrix-math :as m])
-  #_(:use examples.import-static))
+  (:use clojure.java.io))
 #_(import-static java.awt.event.KeyEvent VK_LEFT VK_RIGHT VK_UP VK_DOWN)

 ; ----------------------------------------------------------
 ; functional model
 ; ----------------------------------------------------------
-; START: constants

 (def width 160)
 (def height 85)
@@ -35,6 +34,19 @@
 (def asteroid-max-rotation-speed 4)
 (def asteroid-damage 1)
 (def debris-life-millis 3000)
+
+(defn random-int [from to]
+  (let [range (- to from)]
+    (+ from (rand-int range))))
+
+(defn random [from to]
+  (let [range (- to from)]
+    (+ from (rand range))))
+
+(defn vary [variance n]
+  (let [from (* n (- 1 variance))
+        to (* n (+ 1 variance))]
+    (random from to)))

 (def ammunition-types {:projectile {:size         (/ ship-size 10)
                                     :shape        [[-1.0 -5.0] [1.0 -5.0] [0.0 1.0]]
@@ -65,18 +77,7 @@
               (int \J) {:fire-weapon :launcher}
               (int \K) {:fire-weapon :machinegun}})

-; END: constants
-
 (def sqrt (memoize #(Math/sqrt %)))
-
-(defn random [from to]
-  (let [range (- to from)]
-    (+ from (rand range))))
-
-(defn vary [variance n]
-  (let [from (* n (- 1 variance))
-        to (* n (+ 1 variance))]
-    (random from to)))

 (defn get-transformation-matrix [{:keys [size position direction]} scale]
   (let [[x y] position]
@@ -133,26 +134,37 @@
    :collidable?    false                                    ; is set to ship-damage at first movement / shooting
    })

-(defn create-shot [ammunition-type {:keys [position size direction speed] :as ship}]
-  (let [dir-vec (m/rotate-vec direction [0 1])
-        position (m/vec+vec position (m/num*vec size dir-vec))
-        speed (m/vec+vec speed (m/num*vec (-> ammunition-types ammunition-type :speed) dir-vec))
-        ammunition (get ammunition-types ammunition-type)]
-    {:type           ammunition-type
-
-     :size           (:size ammunition)
-     :shape          (:shape ammunition)
-     :color          (:color ammunition)
-     :paint-method   fill-polygon
-
-     :position       position
-     :speed          speed
-     :acceleration   (:acceleration ammunition)
-
-     :direction      direction
-     :rotation-speed 0
-
-     :collidable?    (:damage ammunition)}))
+(defn get-expr-value
+  ([expr default]
+   (cond
+     (nil? expr) default
+     (fn? expr) (expr)
+     :else expr))
+  ([expr] (get-expr-value expr nil)))
+
+(defn create-shot ([ammunition-type {ship-pos :position ship-size :size ship-dir :direction ship-speed :speed}]
+   (let [{:keys [spread size shape color acceleration direction rotation-speed damage life-time]} (get ammunition-types ammunition-type)
+         move-dir (if spread (+ ship-dir (random (- spread) spread)) ship-dir)
+         dir-vec (m/rotate-vec move-dir [0 1])
+         position (m/vec+vec ship-pos (m/num*vec ship-size dir-vec))
+         speed (m/vec+vec ship-speed (m/num*vec (-> ammunition-types ammunition-type :speed) dir-vec))]
+     {:type           ammunition-type
+
+      :size           (get-expr-value size)
+      :shape          (get-expr-value shape)
+      :color          (get-expr-value color)
+      :paint-method   fill-polygon
+
+      :position       position
+      :speed          speed
+      :acceleration   (get-expr-value acceleration 0)
+
+      :direction      (get-expr-value direction move-dir)
+      :rotation-speed (get-expr-value rotation-speed 0)
+
+      :collidable?    (get-expr-value damage)
+
+      :life-time      (get-expr-value life-time)})))

 (defn create-explosion [position {:keys [size color life-time damage] :as explosion}]
   (if explosion
@@ -224,17 +236,19 @@

 (defn play-sound
   ([sound gain]
-   (let [file (str "resources/" sound ".wav")
-         audio-stream (AudioSystem/getAudioInputStream (java.io.File. file))
-         clip (AudioSystem/getClip)
-         ;volume (.getControl clip FloatControl$Type/MASTER_GAIN)
-         ]
-     #_(doto volume
-         (.setValue gain))
-     (doto clip
-       (.open audio-stream)
-       (.setFramePosition 0)
-       (.start))))
+   (let [file (str "resources/" sound ".wav")]
+     (when (.exists (as-file file))
+       (let [audio-stream (AudioSystem/getAudioInputStream (File. file))
+             clip (AudioSystem/getClip)
+             ;volume (.getControl clip FloatControl$Type/MASTER_GAIN)
+             ]
+         #_(doto volume
+             (.setValue gain))
+         (doto clip
+           (.open audio-stream)
+           (.setFramePosition 0)
+           (.start))
+         ))))
   ([sound] (play-sound sound 0)))

 (defn out-of-bounds? [{[x y] :position size :size}]
@@ -386,7 +400,7 @@
   (basic-move asteroid))

 (defmethod move :debris [{:keys [life-time size] :as debris}]
-  (if (<= life-time 0)
+  (if (< life-time turn-millis)
     nil
     (let [debris (basic-move debris)
           size (* size (- 1 (/ turn-millis life-time)))


uncomment build

uncomment build

--- src/ci3/controller.clj
+++ src/ci3/controller.clj
@@ -8,8 +8,7 @@
 (defonce stop (atom nil))

 (defn process-build [builds]
-  (println builds)
-  #_(when-let [items (:items builds)]
+  (when-let [items (:items builds)]
     (doseq [i items]
       (when-not (:pod i)
         (let [id (get-in i [:metadata :name])]


Made modifier functions for General Sorted Sets to have an ! at the end

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

--- src/conexp/contrib/dl/playground.clj
+++ src/conexp/contrib/dl/playground.clj
@@ -65,9 +65,9 @@
   [gss x]
   (find-neighbours gss #((:order-fn gss) (:node %) x) (comp deref :uppers) @(:minimal-elements gss) #{}))

-(defn add-to-gss
+(defn add-to-gss!
   "Adds the element elt to the general sorted set gss returning the
-  result."
+  result. Note that this function modifies gss."
   [gss elt]
   (dosync
    (let [order-fn (:order-fn gss),
@@ -106,7 +106,7 @@

      gss)))

-(defn remove-from-gss
+(defn remove-from-gss!
   "Removes the element elt from the general sorted set gss."
   [gss elt]
   (unsupported-operation "Removing elements from a general sorted set has not been thought of!"))


More time before stopping kafka server for circle

--- test/onyx/plugin/input_broker_reboot_test.clj
+++ test/onyx/plugin/input_broker_reboot_test.clj
@@ -121,7 +121,7 @@

 (def stopped-server (component/stop kafka-server))

-(Thread/sleep 2000)
+(Thread/sleep 4000)

 (def started-again (component/start stopped-server))


minor refactoring

minor refactoring


Checkpoint

Checkpoint

Signed-off-by: Gregory Haskins <640d9fe47775e6723f0355b7315e38f7d98d3539@gmail.com>

--- src/obcc/build/interface.clj
+++ src/obcc/build/interface.clj
@@ -66,8 +66,9 @@
         (recur (zip/right loc) (assoc fields (:index attrs) attrs))))))

 (defn buildmessage [ast]
-  (let [name (->> zip/right zip/node)
-        fields (buildfields (->> zip/right zip/right))]))
+  (let [name (->> ast zip/right zip/node)
+        fields (buildfields (->> ast zip/right zip/right))]
+      [name fields]))

 ;;(defn generateproto [intf ast template]
 ;;  (loop [loc ast]


Remove comment.

Remove comment.

--- src/oc/storage/api/label.clj
+++ src/oc/storage/api/label.clj
@@ -145,7 +145,7 @@
     :options true
     :get (fn [ctx] (access/allow-members conn org-slug (:user ctx)))
     :post (fn [ctx] (access/allow-members conn org-slug (:user ctx)))
-    :delete (fn [ctx] (access/allow-admins conn org-slug (:user ctx)))}) ; don't allow non-team-admins to get stuck w/ no org
+    :delete (fn [ctx] (access/allow-admins conn org-slug (:user ctx)))})

   :processable? (by-method {
     :options true


Update checksum.clj

Update checksum.clj

--- src/pandect/gen/checksum.clj
+++ src/pandect/gen/checksum.clj
@@ -12,7 +12,7 @@

 (deftype CRC32CodeGen []
   CodeGen
-  (algorithm-string [_] "ADLER-32")
+  (algorithm-string [_] "CRC-32")
   (bytes->hash [_ form]
     `(let [buf# ~form
            a# (CRC32.)]


proc improvements

proc improvements

--- src/webdriver/proc.clj
+++ src/webdriver/proc.clj
@@ -1,11 +1,38 @@
 (ns webdriver.proc
-  (:require [clojure.test :refer [is deftest]])
+  (:require [clojure.test :refer [is deftest]]
+            [clojure.java.io :as io])
   (:import java.lang.Runtime
            java.lang.IllegalThreadStateException))

-(defn run [& args]
-  (let [params (->> args (map str) into-array)]
-    (-> (Runtime/getRuntime) (.exec params))))
+(defmulti run2 (fn [& attrs] (mapv class attrs)))
+
+(defmethod run2 [clojure.lang.PersistentVector & foo] [params]
+  (print 42))
+
+;; (defmethod run [clojure.lang.PersistentVector APersistentMap]
+;;   )
+
+
+(defn run3
+
+  ;; ([cmd]
+  ;;  (run cmd ))
+  ;; ([cmd params]
+  ;;  (run cmd []))
+
+  [cmd params env dir]
+  (let [java-params (->> params
+                         (cons cmd)
+                         (map str)
+                         (into-array String))
+        env-pair (fn [[k v]] (format "%s=%s" (name k) v))
+        java-env (->> env (map env-pair) (into-array String))
+        java-file (io/file dir)
+        runtime (Runtime/getRuntime)]
+    (.exec runtime
+           java-params
+           java-env
+           java-file)))

 (defn alive? [proc]
   (-> proc .isAlive))
@@ -18,7 +45,8 @@
 (defn kill [proc]
   (-> proc .destroy))

+(defn run-server [command host port & args]
+  )
+
 (defn run-gecko [host port & args]
-  ;;(run "/usr/local/bin/geckodriver")
-  (apply run "geckodriver" "--host" host "--port" port args)
-  )
+  (apply run "geckodriver" "--host" host "--port" port args))


Abstract assortment to make adding specialized assortments easier

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -625,6 +625,65 @@
         (perun/report-info task-name (str task-name " found nothing to render"))
         []))))

+(defn- assortment-impl
+  [task-name tracer grouper options]
+  (cond (not (fn? (:comparator options)))
+        (u/fail (str task-name " task :comparator option should implement Fn\n"))
+        (not (ifn? (:filterer options)))
+        (u/fail (str task-name " task :filterer option value should implement IFn\n"))
+        (not (ifn? (:sortby options)))
+        (u/fail (str task-name " task :sortby option value should implement IFn\n"))
+        (not (ifn? grouper))
+        (u/fail (str task-name " task :grouper option value should implement IFn\n"))
+        :else
+        (let [assortment-paths (partial grouped-paths task-name)
+              ;; Make sure task-level metadata gets added to each entry
+              meta-grouper (fn [entries]
+                             (->> entries
+                                  grouper
+                                  (map (fn [[path data]]
+                                         [path (update-in data [:group-meta] #(merge (:meta options) %))]))
+                                  (into {})))
+              options (assoc options :grouper meta-grouper)]
+          (render-pre-wrap assortment-paths options tracer))))
+
+(def ^:private +assortment-defaults+
+  {:out-dir "public"
+   :filterer :has-content
+   :sortby (fn [file] (:date-published file))
+   :comparator (fn [i1 i2] (compare i2 i1))
+   :grouper #(-> {"index.html" {:entries %}})})
+
+(deftask assortment
+  "Render multiple collections
+   The symbol supplied as `renderer` should resolve to a function
+   which will be called with a map containing the following keys:
+    - `:meta`, global perun metadata
+    - `:entry`, the metadata for this collection
+    - `:entries`, all entries
+
+   The `grouper` function will be called with a seq containing the
+   entries to be grouped, and it should return a map with keys that
+   are filenames and values that are maps with the keys:
+    - `:entries`: the entries for each collection
+    - `:group-meta`: (optional) page metadata for this collection
+
+   Entries can optionally be filtered by supplying a function
+   to the `filterer` option.
+
+   The `sortby` function can be used for ordering entries before rendering."
+  [o out-dir    OUTDIR     str  "the output directory"
+   r renderer   RENDERER   sym  "page renderer (fully qualified symbol resolving to a function)"
+   g grouper    GROUPER    code "group posts function, keys are filenames, values are to-be-rendered entries"
+   _ filterer   FILTER     code "predicate to use for selecting entries (default: `:has-content`)"
+   s sortby     SORTBY     code "sort entries by function"
+   c comparator COMPARATOR code "sort by comparator function"
+   m meta       META       edn  "metadata to set on each collection entry"
+   n task-name  TASKNAME   str  "name to use for logging messages; only for tasks that use assortment under the hood"
+   t tracer     TRACER     kw   "value to put in `:io.perun/trace`; only for tasks that use assortment under the hood"]
+  (let [options (merge +assortment-defaults+ (dissoc *opts* :grouper))]
+    (assortment-impl "assortment" :io.perun/assortment (:grouper *opts*) options)))
+
 (def ^:private +collection-defaults+
   {:out-dir "public"
    :filterer :has-content
@@ -651,79 +710,10 @@
    c comparator COMPARATOR code "sort by comparator function"
    p page       PAGE       str  "collection result page path"
    m meta       META       edn  "metadata to set on each collection entry"]
-  (let [options (merge +collection-defaults+
-                       (dissoc *opts* :page)
-                       (if-let [p (:page *opts*)]
-                         {:grouper #(-> {p {:entries %
-                                            :group-meta (:meta *opts*)}})}
-                         {:grouper #(-> {"index.html" {:entries %
-                                                       :group-meta (:meta *opts*)}})}))]
-    (cond (not (fn? (:comparator options)))
-          (u/fail "collection task :comparator option should implement Fn\n")
-          (not (ifn? (:filterer options)))
-          (u/fail "collection task :filterer option value should implement IFn\n")
-          (not (ifn? (:sortby options)))
-          (u/fail "collection task :sortby option value should implement IFn\n")
-          :else
-          (let [collection-paths (partial grouped-paths "collection")]
-            (render-pre-wrap collection-paths options :io.perun/collection)))))
-
-(def ^:private +assortment-defaults+
-  {:out-dir "public"
-   :filterer :has-content
-   :sortby (fn [file] (:date-published file))
-   :comparator (fn [i1 i2] (compare i2 i1))})
-
-(deftask assortment
-  "Render multiple collections
-   The symbol supplied as `renderer` should resolve to a function
-   which will be called with a map containing the following keys:
-    - `:meta`, global perun metadata
-    - `:entry`, the metadata for this collection
-    - `:entries`, all entries
-
-   The `grouper` function will be called with a seq containing the
-   entries to be grouped, and it should return a map with keys that
-   are filenames and values that are maps with the keys:
-    - `:entries`: the entries for each collection
-    - `:group-meta`: (optional) page metadata for this collection
-
-   Entries can optionally be filtered by supplying a function
-   to the `filterer` option.
-
-   The `sortby` function can be used for ordering entries before rendering."
-  [o out-dir    OUTDIR     str  "the output directory"
-   r renderer   RENDERER   sym  "page renderer (fully qualified symbol resolving to a function)"
-   g grouper    GROUPER    code "group posts function, keys are filenames, values are to-be-rendered entries"
-   _ filterer   FILTER     code "predicate to use for selecting entries (default: `:has-content`)"
-   s sortby     SORTBY     code "sort entries by function"
-   c comparator COMPARATOR code "sort by comparator function"
-   m meta       META       edn  "metadata to set on each collection entry"]
-  (let [options (merge +assortment-defaults+
-                       *opts*
-                       (if-let [grouper* (:grouper *opts*)]
-                         {:grouper (fn [metas]
-                                     (->> metas
-                                          grouper*
-                                          (reduce
-                                           (fn [paths [page data]]
-                                             (assoc paths page
-                                                    (update-in data [:group-meta]
-                                                               #(merge (:meta *opts*) %))))
-                                           {})))}
-                         {:grouper #(-> {"index.html" {:entries %
-                                                       :group-meta (:meta *opts*)}})}))]
-    (cond (not (fn? (:comparator options)))
-          (u/fail "assortment task :comparator option should implement Fn\n")
-          (not (ifn? (:filterer options)))
-          (u/fail "assortment task :filterer option value should implement IFn\n")
-          (not (ifn? (:grouper options)))
-          (u/fail "assortment task :grouper option value should implement IFn\n")
-          (not (ifn? (:sortby options)))
-          (u/fail "assortment task :sortby option value should implement IFn\n")
-          :else
-          (let [assortment-paths (partial grouped-paths "assortment")]
-            (render-pre-wrap assortment-paths options :io.perun/assortment)))))
+  (let [p (or (:page *opts*) "index.html")
+        options (merge +collection-defaults+ (dissoc *opts* :page))
+        grouper #(-> {p {:entries %}})]
+    (assortment-impl "collection" :io.perun/collection grouper options)))

 (deftask inject-scripts
   "Inject JavaScript scripts into html files.


Let boot.util/{sh,dosh} accpet nil arguments (fixes #141)

--- boot/pod/src/boot/util.clj
+++ boot/pod/src/boot/util.clj
@@ -168,18 +168,20 @@
 (def ^:dynamic *sh-dir* nil)

 (defn sh [& args]
-  {:pre [(every? string? args)]}
-  (let [opts (into [:redirect-err true] (when *sh-dir* [:dir *sh-dir*]))
-        proc (apply conch/proc (concat args opts))]
-    (future (conch/stream-to-out proc :out))
-    #(.waitFor (:process proc))))
+  (let [args (remove nil? args)]
+    (assert (every? string? args))
+    (let [opts (into [:redirect-err true] (when *sh-dir* [:dir *sh-dir*]))
+          proc (apply conch/proc (concat args opts))]
+      (future (conch/stream-to-out proc :out))
+      #(.waitFor (:process proc)))))

 (defn dosh [& args]
-  {:pre [(every? string? args)]}
-  (let [status ((apply sh args))]
-    (when-not (= 0 status)
-      (throw (Exception. (-> "%s: non-zero exit status (%d)"
-                           (format (first args) status)))))))
+  (let [args (remove nil? args)]
+    (assert (every? string? args))
+    (let [status ((apply sh args))]
+      (when-not (= 0 status)
+        (throw (Exception. (-> "%s: non-zero exit status (%d)"
+                               (format (first args) status))))))))

 (defmacro without-exiting
   "Evaluates body in a context where System/exit doesn't work.


Make less cluttered

Make less cluttered

--- frontend/components/integrations.cljs
+++ frontend/components/integrations.cljs
@@ -191,6 +191,6 @@
                [:div.graphic
                 [:div {:dangerouslySetInnerHTML {:__html "<iframe src='//www.youtube.com/embed/Hfs_1yuWDf4?rel=0&showinfo=0' width='300' height='200' frameborder='0' allowfullscreen></iframe>"}}]]]]
              [:div.bottom-section
-              [:h2 "Ready for world-class" [:br] "continuous delivery?"]
+              [:h2 "Ready for world-class continuous delivery?"]
               [:a {:role "button"} "Sign up for Free"]
-              [:p "Want more information? See our complete" [:br] [:a {:href "/docs/continuous-deployment-with-heroku"} "documentation on deploying to Heroku."]]]]))))
+              [:p "Want more information? See our " [:a {:href "/docs/continuous-deployment-with-heroku"} "complete documentation"] " on deploying to Heroku."]]]))))


cljs wish-li function

cljs wish-li function

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -1,3 +1,9 @@
-(ns overtoneinterface.client.main)
+(ns overtoneinterface.client.main
+  (:require [crate.core :as crate])
+  (:use-macros [crate.macros :only [defpartial]]))

-(js/alert "hey!")+(defpartial wish-li [desc url]
+  [:li.wish
+   [:div.delete]
+   [:input {:type "text" :class "description" :value desc}]
+   [:input {:type "text" :class "url" :value url}]])


use group-by :zid

use group-by :zid

--- src/polismath/simulation.clj
+++ src/polismath/simulation.clj
@@ -1,6 +1,5 @@
 (ns polismath.simulation
   (:require [clojure.tools.cli :refer [parse-opts]]
-            [polismath.poller :refer [split-by-conv]]
             [clojure.string :as string])
   (:use polismath.utils
         polismath.named-matrix
@@ -78,7 +77,7 @@
         vote-rate (:vote-rate opts)]
     (endlessly (:poll-interval opts)
       (let [new-votes (take vote-rate @simulator)
-            split-votes (split-by-conv new-votes)]
+            split-votes (group-by :zid new-votes)]
         (swap! simulator #(drop vote-rate %))
         (doseq [[zid votes] split-votes]
           (swap! conversations


Comments on structural sharing

Comments on structural sharing

--- src/polismath/storm_spec.clj
+++ src/polismath/storm_spec.clj
@@ -37,6 +37,8 @@

 ; This is a little bit of a hack. Need to get pca working on matrices with just a couple of elements still...
 ;(def init-matrix (->RatingMatrix ["p1" "p2" "p3"] ["c1" "c2" "c3"] [[1 1 0] [0 1 -1] [0 -1 1]]))
+; this might actually be really bad for structural sharing (keeping a head around); don't understand all of
+; the intricacies of structural sharing though
 (def init-matrix (->RatingMatrix [] [] [[]]))

 (defbolt rating-matrix ["conv-id" "rating-matrix"] {:prepare true}


core: when-let

core: when-let

--- data/core.clj
+++ data/core.clj
@@ -1132,3 +1132,18 @@
           (let [~form temp#]
             ~then)
           ~else)))))
+
+(defmacro when-let
+  "bindings => binding-form test
+
+  When test is true, evaluates body with binding-form bound to the value of test"
+  {:added "1.0"}
+  [bindings & body]
+  (assert-args
+   (vector? bindings) "a vector for its binding"
+   (= 2 (count bindings)) "exactly 2 forms in binding vector")
+  (let [form (bindings 0) tst (bindings 1)]
+    `(let [temp# ~tst]
+       (when temp#
+         (let [~form temp#]
+           ~@body)))))


Got defcmd2 working.

Got defcmd2 working.

--- core.clj
+++ core.clj
@@ -107,26 +107,91 @@
                                           (make-delegate ~typeargs ~args ~fn-name)))
      #'~fn-name))

+(defmacro separate-types [f args]
+          `{:typeargs (->> '~args
+                           (mapv meta)
+                           (mapv :tag))
+          :typeresult (:tag (meta '~f))})
+
+;; (defmacro separate-types-oldform [f args]
+;;           `(let [{:keys [typeargs# typeresult#]} (separate-types ~f ~args)]
+;;                 (if typeresult#
+;;                     (conj typeargs# typeresult#)
+;;                   typeargs#)))
+
+(defmacro separate-types-oldform [f args]
+          `(let [h# (separate-types ~f ~args)]
+                (if (:typeresult h#)
+                    (conj (:typeargs h#) (:typeresult h#))
+                  (:typeargs h#))))
+
+(defmacro huh [f args]
+          (list (mapv name args)
+                (str "(defn " (name f) " ["
+                     (clojure.string/join " " (map name args)) "] ...)"))
+          )
+(macroexpand '(huh g [x y z]))
+
+(defmacro defcmd2
+    "Define a Minibuffer command and function. The docstring is required.
+  The typeargs define what C# types the function accepts and optionally what it
+  returns. Minibuffer makes extensive use of the type information. Consider the
+  following example.
+
+  e.g. (defcmd say-hello \"Says hello. Return int.\" [String Int32]
+          [x]
+          (message \"Hello, \" x)
+          1)
+
+  The function `say-hello` be defined as if it were a normal `defn` but it may
+  additionally be run interactively by typing `M-x say-hello` which will then
+  prompt for a string. Functions with a String output will be `message`'d
+  automatically. Functions with a IEnumerator output will be run as coroutines."
+  [fn-name docstring args & body]
+  `(do
+       (defn ~fn-name
+         ~docstring
+         ~args
+         ~@body)
+       (register-command { :name ~(name fn-name)
+                         :description ~docstring
+                         :signature ~(str "(defn " (name fn-name) " ["
+                                         (clojure.string/join " " (map name args)) "] ...)")
+                         :parameter-names ~(mapv name args) }
+                         (separate-types-oldform ~fn-name ~args)
+                         '~args
+                         '~fn-name)
+     #'~fn-name))
+
+
 (defn register-command
-  [cmd-name typeargs args f attrs]
-  (with-minibuffer m
-                   (.RegisterCommand m
-                                     (doto (Command. cmd-name)
-                                           (.set_description (:description attrs nil))
-                                           (.set_keySequence (:keysequence attrs nil))
-                                           (.set_signature   (:signature attrs nil))
-                                           (.set_parameterNames
-                                            (if (:parameter-names attrs nil)
-                                                (into-array String (into ["closure"] (:parameter-names attrs nil)))
-                                              nil)))
-                                     (eval `(make-delegate ~typeargs ~args ~f)))))
+  [cmd-name-or-attrs typeargs args f]
+  (let [attrs (if (string? cmd-name-or-attrs)
+                  {:name cmd-name-or-attrs}
+                  cmd-name-or-attrs)]
+   (with-minibuffer
+    m
+    (.RegisterCommand m
+                      (doto (Command. (:name attrs nil))
+                            (.set_description (:description attrs nil))
+                            (.set_keySequence (:keysequence attrs nil))
+                            (.set_signature   (:signature attrs nil))
+                            (.set_parameterNames
+                             (if (:parameter-names attrs nil)
+                                 ;; There's an extra "closure "parameter in the
+                                 ;; generated method.
+                                 (into-array String (into ["closure"]
+                                                          (:parameter-names attrs nil)))
+                               nil)))
+                      (eval `(make-delegate ~typeargs ~args ~f))))))

 (defn message
   "Print a message to the echo area."
   [& strings] ;; or concatenate or format?
   (let [msg (apply str strings)]
-       (. Minibuffer/instance Message msg)
+       (with-minibuffer m
+                        #_(.Message m msg))
        msg))

 ;; Thanks, Joseph (@selfsame), for the repl environment tip!
@@ -153,9 +218,30 @@

 (defn do-thing [] (message "do-thing"))
 (make-delegate [] [] do-thing)
+
+(pprint (macroexpand '(separate-types ^:hi do-thing2 [^String a ^Object b ])))
+(pprint (separate-types ^:hi ^Int32 do-thing2 [^String a ^Object b c]))
+(meta #'do-thing)
+
+(defmacro check-meta [f args & body]
+          (let [m (meta &form)]
+               `(list ~m (do
+                                        ;                     (with-meta (defn ~f ~args ~@body) {})
+                            (defn ~f ~args ~@body)
+                            (let [mf# (meta #'~f)
+                                 margs# (first (:arglists mf#))]
+                                 (list #_'(meta '&form)
+                                       mf#
+                                  (:tag mf#)
+                                  (->> margs#
+                                         (mapv meta)
+                                         (mapv :tag))))))))
+(pprint (check-meta ^:hi ^:bye ^Int32 do-thing [^String a b] 1))
+(meta #'do-thing)
+(pprint (macroexpand '(check-meta ^:hi do-thing [^String a] 1)))
 (register-command "do-thing-cmd" [] [] 'do-thing {})
 (register-command "say-hello2-cmd" [String] '[name] 'say-hello2 {:signature "(defn say-hello2 (^String name) ...)"
-                  :parameter-names ["name"]})
+                  :parameter-names ["name"] :description "Say hello!"})
 (defcmd say-hello3
   "Say hello to x. Return a number."
   [] ;; works
@@ -169,8 +255,18 @@
                  []
                  (message "Hi,  from Arcadia!")
                  ))
-
-
+(use 'clojure.pprint)
+(macroexpand '(defcmd2 say-hello3
+                "Say hello to x. Return a number."
+                [^String x]
+                (message "Hi, from Arcadia! " x)
+                ))
+
+(defcmd2 say-hello3
+  "Say hello to x. Return a number."
+  [^String x]
+  (message "Hi, from Arcadia! " x)
+  )
 (defcmd say-hello4
   "Say hello to x. Return a number."
   [String String] ;; this works. Probably a boxing error.
@@ -205,3 +301,6 @@
   [x & y]
   (message "Hi, " x " from Arcadia!")
   \a)
+
+(defn ^String wat [^String s]
+  (str s " wat?"))


Improves fs APi

Improves fs APi

--- src/node/fs.cljs
+++ src/node/fs.cljs
@@ -1,19 +1,88 @@
 (ns node.fs)
+
+;; TODO: improve comments

 (def ^:private fs (js/require "fs"))

-(defn exists?
-  "Test wheter or not the given path exists by checking the file system. If `callback` is provided, the execution is asynchronous and `callback` is invoked with either true or false."
-  [path & {:keys [callback]}]
+;; ===========
+;;
+;; Node fs API (https://nodejs.org/api/fs.html)
+;;
+;; ===========
+
+(defn path-exists?
+  "Test whether or not the given path exists by checking the file system. If `callback` is provided, the execution is asynchronous and `callback` is invoked with either true or false."
+  [path & [callback]]
   (if callback
     (.exists fs path callback)
     (.existsSync fs (clj->js path))))

-(defn mkdir
-  "mkdir(2). `mode` defaults to `0777`. If `callback` is provided ,  the execution is asynchronous and `callback` is invoked with no arguments other than a possible exception."
-  [path & {:keys [callback mode]
-           :or {mode "0777"}}]
-  (js/console.log path)
+(defn mkdir!
+  "mkdir(2). `mode` defaults to `0777`. If `callback` is provided, the execution is asynchronous and `callback` is invoked with no arguments other than a possible exception."
+  [path & [mode callback]]
   (if callback
     (.mkdir fs path mode callback)
     (.mkdirSync fs path mode)))
+
+(defn write-file!
+  "Write data to a file, replacing the file if it already exists. data can be a string or a buffer.
+
+The encoding option is ignored if data is a buffer. It defaults to 'utf8'.
+
+  - `filename` String
+  - `data` String | Buffer
+  - `options` Object
+    - `encoding` String | Null default = 'utf8'
+    - `mode` Number default = 438 (aka 0666 in Octal)
+  - `flag` String default = 'w'
+  - `callback` Function"
+  [filename data & [options callback]]
+  (if callback
+    (.writeFile fs filename data options callback)
+    (.writeFileSync fs filename data options)))
+
+(defn rename!
+  "Synchronous rename(2). If `callback` is provided the execution is asynchronous."
+  [old-path new-path & [callback]]
+  (if callback
+    (.rename fs old-path new-path callback)
+    (.renameSync fs old-path new-path)))
+
+(defn unlink!
+  "Synchronous unlink(2). If `callback` is provided the execution is asynchronous."
+  [path & [callback]]
+  (if callback
+    (.unlink fs path callback)
+    (.unlinkSync fs path)))
+
+(defn read-dir
+  "Synchronous readdir(3). Returns an array of filenames excluding '.' and '..'. If `callback` is provided the execution is asynchronous."
+  [path & [callback]]
+  (if callback
+    (.readdir fs path callback)
+    (.readdirSync fs path)))
+
+(defn rm-dir!
+  "Synchronous rmdir(2). If `callback` is provided the execution is asynchronous."
+  [path & [callback]]
+  (if callback
+    (.rmdir fs path callback)
+    (.rmdirSync fs path)))
+
+;; ===========
+;;
+;; New API
+;;
+;; ===========
+
+(defn ensure-dir!
+  "Ensure tha provided `path` exists on disk. If `callback` is provided, the execution is asynchronous."
+  [path & [callback]]
+  (if callback
+    (path-exists? path
+             #(when-not %
+                (mkdir! path
+                        nil
+                        callback)))
+    (when-not (path-exists? path)
+      (mkdir! path))))


Update PageParser.clj

Update PageParser.clj

--- src/adder/PageParser.clj
+++ src/adder/PageParser.clj
@@ -46,6 +46,8 @@
   [url]
   (vec (flatten (map #(re-find #"http.*jpg" %) (map :style (map :attrs (image+search url)))))))

+
+; RATINGS SECTION and Download Section is not used, dont bother looking into that

 ;RATINGS SECTION
 (def special-char "/")


add infer include-dirs when parsing

add infer include-dirs when parsing

--- src/quark/tree_tokenizer.clj
+++ src/quark/tree_tokenizer.clj
@@ -10,6 +10,8 @@
             [clojure.data.csv :as csv]
             [clojure.java.io :as io]
             [swiss.arrows :refer :all]
+            [clj-cdt.clj-cdt :refer :all]
+            [clj-cdt.writer-util :refer :all]
             )
   (:import
    [org.eclipse.cdt.core.dom.ast IASTNode IASTBinaryExpression
@@ -45,7 +47,9 @@
   "Serialize AST node into an edn list"
   [node]
   (let [poco (to-poco node)]
-    (cons poco (map to-edn (children node)))))
+    (if (leaf? node)
+      poco
+      (cons poco (map to-edn (children node))))))

 '((->> "x" pap parse-frag expr-typename pprint))
 '((->> "f(x)" pap parse-frag expr-typename pprint))
@@ -66,6 +70,74 @@

 '((time-mins (src-dir-to-edn linux-path "tmp/src-to-edn/linux4")))

+;(defn all-child-paths
+;  "given a directory path, find all relative paths under it"
+;  []
+;  (let [{true dirs false files}
+;        (->> "~/nyu/confusion/atom-finder/" expand-home files-in-dir
+;             (group-by (memfn isDirectory)))])
+
+(defn split-path [path] (str/split path #"/"))
+
+(defn all-child-paths
+  "given a directory path, find all relative paths under it"
+  [path]
+  (-<>> path files-in-dir (map (memfn getCanonicalPath))
+        ;(map #(str/replace % (re-pattern (str path "/?")) "")) ;; strip leading paths
+        ))
+
+(defn included-files
+  "extract the files included from this file"
+  [filename]
+  (->> filename
+       slurp-lines
+       (map (partial re-find #"#include *[\"<]([^\">]*)[\">]"))
+       (remove nil?)
+       (map last)))
+
+(def include-files (->> "~/opt/src/mongo/src/mongo/base/parse_number.cpp" expand-home included-files))
+
+(defn infer-include-paths
+  [all-paths include-paths]
+  (->> include-paths
+       (filter #(.contains % "/"))
+       (mapcat (fn [include-path]
+                 (->> all-paths
+                      (map (fn [child-path] [child-path (str/index-of child-path include-path)]))
+                      (remove (comp nil? last))
+                      (map (fn [[path idx]] (subs path 0 idx)))
+                      )))
+       distinct))
+
+(def stdlib-paths ["/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1" "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include"])
+
+(defn parent-dir [path] (->> path java.io.File. .getParent))
+
+(defn parse-file-with-proj-includes
+  "infer which project-level include paths might be useful then parse with them"
+  [all-paths file]
+  (let [include-paths (infer-include-paths all-paths include-files)]
+    (parse-file file {:include-dirs (concat [(parent-dir file)] stdlib-paths
+                                            include-paths
+                                            )})))
+
+(def mongo-files (->> "~/opt/src/mongo" expand-home all-child-paths))
+
+(->> "/Users/dgopstein/opt/src/mongo/src/mongo/base/secure_allocator.cpp"
+     expand-home
+     (parse-file-with-proj-includes mongo-files)
+     ;parse-file
+     flatten-tree
+     (remove from-include?)
+     (filter (partial instance? IASTExpression))
+     (map expr-typename)
+     frequencies
+     (group-by (comp not #(str/starts-with? % "problem-") first))
+     (map-values (%->> (map last) sum))
+     pprint
+     time-mins)
+
+
 (defn src-csv-to-edn
   [csv-path column-name]
   (with-open [reader (io/reader csv-path)


:construction: :bug: Fix icons collections


Broken sort example

Broken sort example

--- src/aurora/language.cljs
+++ src/aurora/language.cljs
@@ -481,7 +481,8 @@

 (.add-facts kn "know" "clauses" #js ["rule-id" "when|know|remember|forget" "clause-id" "name"] #js [#js ["count-overlap" "when" "get-more-foos" "foo"]
                                                                                #js ["count-overlap" "when" "some-more-interval" "interval"]
-                                                                                #js ["count-overlap" "remember" "rem-quux" "quux"]])
+                                                                                #js ["count-overlap" "remember" "rem-quux" "quux"]
+                                                                                #js ["count-overlap" "remember" "rem-frip" "frip"]])

 (.add-facts kn "know" "clause-fields" #js ["clause-id" "constant|variable|aggregate" "key" "val"] #js [#js ["get-more-foos" "variable" "x" "xx"]
                                                                                #js ["get-more-foos" "variable" "y" "yy"]
@@ -490,11 +491,17 @@
                                                                                #js ["some-more-interval" "variable" "in" "zz"]
                                                                                #js ["rem-quux" "variable" "x" "xx"]
                                                                                #js ["rem-quux" "variable" "y" "yy"]
-                                                                                #js ["rem-quux" "aggregate" "z" "count-zz"]])
-
-(.add-facts kn "know" "clause-aggregate-vars" #js ["aggregate-id" "ix" "var"] #js [#js ["count-zz" 0 "zz"]])
-
-(.add-facts kn "know" "clause-aggregate-funs" #js ["aggregate-id" "js"] #js [#js ["count-zz" "count"]])
+                                                                                #js ["rem-quux" "aggregate" "z" "count-zz"]
+                                                                                #js ["rem-frip" "variable" "x" "xx"]
+                                                                                #js ["rem-frip" "variable" "y" "yy"]
+                                                                                #js ["rem-frip" "aggregate" "z" "top-3-zz"]])
+
+(.add-facts kn "know" "clause-aggregate-vars" #js ["aggregate-id" "ix" "var"] #js [#js ["count-zz" 0 "zz"]
+                                                                                #js ["top-3-zz" 0 "zz"]
+                                                                                #js ["top-3-zz" 1 "zz"]])
+
+(.add-facts kn "know" "clause-aggregate-funs" #js ["aggregate-id" "js"] #js [#js ["count-zz" "count"]
+                                                                             #js ["top-3-zz" "top-3"]])

 (def flows (compile kn))


Revert "-(defn evaluate): not used or tested"

This reverts commit f6a55ea273e7a5f9b5db92d8d6af679d44681baf.

--- src/babel/lexiconfn.cljc
+++ src/babel/lexiconfn.cljc
@@ -781,6 +781,14 @@

       ))

+;; TODO: dangerous to (eval) code that we don't directly control:
+;; replace with a DSL that accomplishes the same thing without
+;; security problems.
+(defn evaluate [lexicon]
+  (into {}
+        (for [[k v] lexicon]
+          [k (eval v)])))
+
 (defn insert-lexeme [canonical lexemes language]
   (log/debug (str "insert-lexeme: canonical=" canonical ", language=" language))
   (exec-raw [(str "INSERT INTO lexeme
@@ -815,6 +823,7 @@
 (defn write-lexicon [language lexicon]
   (transaction
    (truncate-lexicon language)
+
    (let [canonicals (sort (keys lexicon))]
      (loop [remain canonicals
             result 0]


Fix --input text reading a blank field at the start of the line and getting it wrong

--- src/bltool/data/text.clj
+++ src/bltool/data/text.clj
@@ -1,13 +1,13 @@
 (ns bltool.data.text
   (:require [bltool.data.default :refer :all])
   (:require [bltool.flags :refer :all])
-  (:require [clojure.string :refer [split join]]))
+  (:require [clojure.string :refer [split join trim]]))

 (defn- to-text [game]
   (format "%8s  %-10s  %-10s  %s" (:id game) (:platform game) (:progress game) (:name game)))

 (defn- from-text [game]
-  (let [[id platform progress name] (split game #"\s+" 4)]
+  (let [[id platform progress name] (-> game trim (split #"\s+" 4))]
     {:id id :name name :platform platform :progress progress}))

 (defmethod read-games "text" [_]


Fix cljs.closure handling of namespaces with dashes. Refs #CLJS-23.

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -405,23 +405,27 @@
 (def compiled-cljs (atom {}))

 (defn get-compiled-cljs
-  "If not already compiled, compile the given cljs namespace. Return
+  "If not already compiled, compile the given cljs file. Return
   an IJavaScript for this file. Compiled output will be written to the
   working directory."
-  [opts ns]
-  (let [file (str (string/replace ns "." "/") ".cljs")
-        js-file (comp/rename-to-js file)
+  [opts {:keys [relative-path uri]}]
+  (let [js-file (comp/rename-to-js relative-path)
         out-file (io/file (output-directory opts) js-file)
-        javascript (cond (and (.exists out-file) (get @compiled-cljs ns)) (get @compiled-cljs ns)
+        javascript (cond (and (.exists out-file) (get @compiled-cljs relative-path))
+                         (get @compiled-cljs relative-path)
                          (.exists out-file) (let [ns-info (parse-js-ns
                                                            (string/split-lines (slurp out-file)))]
                                               (javascript-file (to-url out-file)
                                                                (:provides ns-info)
                                                                (:requires ns-info)))
-                         :else (-compile (io/resource file)
-                                         (merge opts {:output-file js-file})))]
-    (do (swap! compiled-cljs (fn [old] (assoc old ns javascript)))
+                         :else (-compile uri (merge opts {:output-file js-file})))]
+    (do (swap! compiled-cljs (fn [old] (assoc old relative-path javascript)))
         javascript)))
+
+(defn ns->file-name [s]
+  (let [ns (name s)
+        path (string/replace (munge ns) \. java.io.File/separatorChar)]
+    (str path ".cljs")))

 (defn cljs-dependencies
   "Given a list of all required namespaces, return a list of
@@ -429,20 +433,27 @@
   order. The returned list will not only include the explicitly
   required files but any transative depedencies as well. JavaScript
   files will be compiled to the working directory if they do not
-  already exist."
+  already exist.
+
+  Only load dependencies from the classpath."
   [opts requires]
   (let [index (js-dependency-index opts)]
-    (letfn [(cljs-deps [coll] (remove #(contains? index %) coll))]
-     (loop [requires (cljs-deps requires)
-            deps {}]
-       (if (seq requires)
-         (let [next-ns (first requires)
-               js (get-compiled-cljs opts next-ns)
-               new-requires (remove #(or (contains? deps %)
-                                         (contains? (set requires) %))
-                                    (cljs-deps (-requires js)))]
-           (recur (into (rest requires) new-requires) (assoc deps next-ns js)))
-         (dependency-order (vals deps)))))))
+    (letfn [(cljs-deps [coll]
+              (->> coll
+                   (remove #(contains? index %))
+                   (map #(let [f (ns->file-name %)] (hash-map :relative-path f :uri (io/resource f))))
+                   (remove #(nil? (:uri %)))))]
+      (loop [required-files (cljs-deps requires)
+             visited (set required-files)
+             js-deps []]
+        (if (seq required-files)
+          (let [next-file (first required-files)
+                js (get-compiled-cljs opts next-file)
+                transative (remove #(contains? visited %) (cljs-deps (-requires js)))]
+            (recur (into (rest required-files) transative)
+                   (conj visited transative)
+                   (conj js-deps js)))
+          (dependency-order js-deps))))))

 (comment
   ;; only get cljs deps
@@ -580,7 +591,7 @@
 (defn add-dep-string
   "Return a goog.addDependency string for an input."
   [opts input]
-  (letfn [(ns-list [coll] (when (seq coll) (apply str (interpose ", " (map #(str "'" % "'") coll)))))]
+  (letfn [(ns-list [coll] (when (seq coll) (apply str (interpose ", " (map #(str "'" (munge %) "'") coll)))))]
     (str "goog.addDependency(\""
          (path-relative-to (io/file (output-directory opts) "goog/base.js") input)
          "\", ["


add :elide-asserts compiler option

add :elide-asserts compiler option

Can now remove asserts (including pre/post conditions) from production
code

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -1126,6 +1126,7 @@
                             (not (false? (:static-fns opts))))
                        (:static-fns opts)
                        ana/*cljs-static-fns*)
+                   *assert* (not= (:elide-asserts opts) true)
                    ana/*cljs-warnings*
                    (let [enabled? (true? (opts :warnings))]
                      (merge ana/*cljs-warnings*


Changes spotify-api-call to def-spotify-api-call

--- src/clj_spotify/core.clj
+++ src/clj_spotify/core.clj
@@ -45,9 +45,9 @@
     )))

 ;TODO - better doc string
-;TODO - rename to def-spotify-api-call
+;TODO - rename to def-def-spotify-api-call
 ;TODO - Maybe change everything to be sent through request body?
-(defmacro spotify-api-call
+(defmacro def-spotify-api-call
   "Creates a function f with doc-string d that calls the http-verb verb for url url."
   [f verb url doc-string]
   `(defn ~f
@@ -66,7 +66,7 @@
 ;TODO - Replace all comma separated strings with maps?

 ;Albums
-(spotify-api-call get-an-album client/get (str spotify-api-url "albums/id")
+(def-spotify-api-call get-an-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.
@@ -74,7 +74,7 @@

     Example: (get-an-album {:id \"0MnG7y5F1n4Wns63RjEItx\" :market \"SE\"} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call get-several-albums client/get (str spotify-api-url "albums")
+(def-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.
@@ -82,7 +82,7 @@

     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")
+(def-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.
@@ -93,21 +93,21 @@
     Example: (get-tracks-of-album {:id \"3XCGFOBqESirxxICswSity\" :market \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

 ;Artists
-(spotify-api-call get-an-artist client/get (str spotify-api-url "artists/id")
+(def-spotify-api-call get-an-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-an-artist {:id \"5CE2IfdYZEQGIDsfiRm8SI\"} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call get-several-artists client/get (str spotify-api-url "artists")
+(def-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-an-artists-albums client/get (str spotify-api-url "artists/id/albums")
+(def-spotify-api-call get-an-artists-albums client/get (str spotify-api-url "artists/id/albums")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m is :id, optional keys are :album_type, :market, :limit and :offset.
     :id has to have the value of an existing artist's id.
@@ -119,7 +119,7 @@

     Example: (get-an-artists-albums {:id \"7lOJ7WXyopaxri0dbOiZkd\" :album_type \"album, single\" :market \"SE\" :limit 50 :offset 50}} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call get-an-artists-top-tracks client/get (str spotify-api-url "artists/id/top-tracks")
+(def-spotify-api-call get-an-artists-top-tracks client/get (str spotify-api-url "artists/id/top-tracks")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory keys in m are :id and :country.
     :id has to be a spotify artist id.
@@ -127,7 +127,7 @@

     Example: (get-an-artists-top-tracks {:id \"7hCsRnXtcbez8msLPfjbkz\" :country \"SE\"} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call get-an-artists-related-artists client/get (str spotify-api-url "artists/id/related-artists")
+(def-spotify-api-call get-an-artists-related-artists client/get (str spotify-api-url "artists/id/related-artists")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m is :id.
     :id has to be a spotify artist id.
@@ -135,7 +135,7 @@
     Example: (get-an-artists-related-artists {:id \"4EF5vIcCYKMM61oYOG2Tqa\"} \"BQBw-JtC..._7GvA\")")

 ;Browse
-(spotify-api-call get-a-list-of-featured-playlists client/get (str spotify-api-url "browse/featured-playlists")
+(def-spotify-api-call get-a-list-of-featured-playlists client/get (str spotify-api-url "browse/featured-playlists")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     There are no compulsary keys in m, optional keys are :locale, :country, :timestamp, :limit and :offset.
     :locale is an ISO 639 language code and a ISO 3166-1 alpha-2 country code joined with an underscore.
@@ -146,7 +146,7 @@

     Example: (get-a-list-of-featured-playlists {:locale \"sv_SE\" :country \"SE\" :timestamp \"2015-10-23T09:00:00\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call get-a-list-of-new-releases client/get (str spotify-api-url "browse/new-releases")
+(def-spotify-api-call get-a-list-of-new-releases client/get (str spotify-api-url "browse/new-releases")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     There are no compulsary keys in m, optional keys are :country, :limit and :offset.
     :country is an ISO 3166-1 alpha-2 country code.
@@ -155,7 +155,7 @@

     Example: (get-a-list-of-new-releases {:country \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call get-a-list-of-categories client/get (str spotify-api-url "browse/categories")
+(def-spotify-api-call get-a-list-of-categories client/get (str spotify-api-url "browse/categories")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     There are no compulsary keys in m, optional keys are :country, :limit and :offset.
     :country is an ISO 3166-1 alpha-2 country code.
@@ -164,7 +164,7 @@

     Example: (get-a-list-of-categories {:country \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call get-a-category client/get (str spotify-api-url "browse/categories/category_id")
+(def-spotify-api-call get-a-category client/get (str spotify-api-url "browse/categories/category_id")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m is :category_id, optional keys are :country and :locale.
     :category_id has to be a spotify category id.
@@ -173,7 +173,7 @@

     Example: (get-a-category {:category_id \"dinner\" :country \"SE\" :locale \"sv_SE\"} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call get-a-categorys-playlists client/get (str spotify-api-url "browse/categories/category_id/playlists")
+(def-spotify-api-call get-a-categorys-playlists client/get (str spotify-api-url "browse/categories/category_id/playlists")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m is :category_id, optional keys are :country, :limit and :offset.
     :category_id has to be a spotify category id.
@@ -184,7 +184,7 @@
     Example: (get-a-categorys-playlist {:category_id \"dinner\" :country \"SE\" :locale \"sv_SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\") ")

 ;Follow
-(spotify-api-call get-users-followed-artists client/get (str spotify-api-url "me/following")
+(def-spotify-api-call get-users-followed-artists client/get (str spotify-api-url "me/following")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m is :type, optional keys are :limit and :after.
     :type has to be set to \"artist\".
@@ -193,7 +193,7 @@

     Example: (get-users-followed-artists {:type \"artist\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\") ")

-(spotify-api-call follow-artists-or-users client/put (str spotify-api-url "me/following")
+(def-spotify-api-call follow-artists-or-users client/put (str spotify-api-url "me/following")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m is :type and :ids.
     :type has to be set to \"artist\" or \"user\".
@@ -201,7 +201,7 @@

     Example: (follow-artists-or-users {:type \"artist\" :ids \"2933wDUojoQmvqSdTAE5NB,1AUCkAIfT6Ig8lOegDGK3Z\" } \"BQBw-JtC..._7GvA\")")

-(spotify-api-call unfollow-artists-or-users client/delete (str spotify-api-url "me/following")
+(def-spotify-api-call unfollow-artists-or-users client/delete (str spotify-api-url "me/following")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m is :type and :ids.
     :type has to be set to \"artist\" or \"user\".
@@ -209,7 +209,7 @@

     Example: (unfollow-artists-or-users {:type \"artist\" :ids \"0uCCBpmg6MrPb1KY2msceF,1WsMRWV5KEC2AxpYkeb2Cf\" } \"BQBw-JtC..._7GvA\")")

-(spotify-api-call user-following-artists-or-users? client/get (str spotify-api-url "me/following/contains")
+(def-spotify-api-call user-following-artists-or-users? client/get (str spotify-api-url "me/following/contains")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m is :type and :ids.
     :type has to be set to \"artist\" or \"user\".
@@ -218,7 +218,7 @@
     Example: (user-following-artists-or-users? {:type \"artist\" :ids \"3H6Js0rhywEhHda3UwuhGW,4r8bVMyYyGyARs9OfBvyj4\" } \"BQBw-JtC..._7GvA\")")

 ;TODO - public:true in request body.
-(spotify-api-call follow-a-playlist client/put (str spotify-api-url "users/owner_id/playlists/playlist_id/followers")
+(def-spotify-api-call follow-a-playlist client/put (str spotify-api-url "users/owner_id/playlists/playlist_id/followers")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory keys in m are :owner_id and :playlist_id.
     :owner_id has to be the spotify user id of the user owning the playlist.
@@ -226,7 +226,7 @@

     Example: (follow-a-playlist {:owner_id \"sondre_lerche\" :playlist_id \"7q8QuE0YbAgbvzR0NJVwV8\" } \"BQBw-JtC..._7GvA\")")

-(spotify-api-call unfollow-a-playlist client/delete (str spotify-api-url "users/owner_id/playlists/playlist_id/followers")
+(def-spotify-api-call unfollow-a-playlist client/delete (str spotify-api-url "users/owner_id/playlists/playlist_id/followers")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory keys in m are :owner_id and :playlist_id.
     :owner_id has to be the spotify user id of the user owning the playlist.
@@ -234,7 +234,7 @@

     Example: (unfollow-a-playlist {:owner_id \"ulyssestone\" :playlist_id \"3WG4abOpUpocexRakPioAg\" } \"BQBw-JtC..._7GvA\")")

-(spotify-api-call user-following-playlist? client/get (str spotify-api-url "users/owner_id/playlists/playlist_id/followers/contains")
+(def-spotify-api-call user-following-playlist? client/get (str spotify-api-url "users/owner_id/playlists/playlist_id/followers/contains")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory keys in m are :owner_id and :playlist_id.
     :owner_id has to be the spotify user id of the user owning the playlist.
@@ -243,14 +243,14 @@
     Example: (user-following-playlist? {:owner_id \"lecowboy\" :playlist_id \"2PftXV7dgcxFjMWe75GuSG\" } \"BQBw-JtC..._7GvA\")")

 ;Library
-(spotify-api-call save-tracks-for-user client/put (str spotify-api-url "me/tracks")
+(def-spotify-api-call save-tracks-for-user client/put (str spotify-api-url "me/tracks")
 " 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 list of spotify track ids.

     Example: (save-tracks-for-user {:ids \"3BSpuy2yHhoEazfXVU7WGq,0BcaWLANkstu2v9kghrCAj\"} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call get-users-saved-tracks client/get (str spotify-api-url "me/tracks")
+(def-spotify-api-call get-users-saved-tracks client/get (str spotify-api-url "me/tracks")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     There are no compulsory keys in m, optional keys are :market, :limit and :offset.
     :market is an ISO 3166-1 alpha-2 country code.
@@ -259,7 +259,7 @@

     Example: (get-users-saved-tracks {:market \"SE\" :limit 50 :offset 50}} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call remove-users-saved-tracks client/delete (str spotify-api-url "me/tracks")
+(def-spotify-api-call remove-users-saved-tracks client/delete (str spotify-api-url "me/tracks")
 " 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 list of spotify track ids.
@@ -267,7 +267,7 @@
     Example: (remove-users-saved-tracks {:ids \"1RyZgkIghj1eL2U1zlYOoE,6NwbeybX6TDtXlpXvnUOZC\"} \"BQBw-JtC..._7GvA\")")

 ;TODO - better name for this function
-(spotify-api-call check-users-saved-tracks client/get (str spotify-api-url "me/tracks/contains")
+(def-spotify-api-call check-users-saved-tracks client/get (str spotify-api-url "me/tracks/contains")
 " 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 list of spotify track ids.
@@ -275,7 +275,7 @@
     Example: (check-users-saved-tracks {:ids \"28nlyt9KhVZQ0lGQsg8Yht,09ZGF6mwJVzw5jxqbtT53E\"} \"BQBw-JtC..._7GvA\")")

 ;Playlists
-(spotify-api-call get-a-list-of-a-users-playlists client/get (str spotify-api-url "users/user_id/playlists")
+(def-spotify-api-call get-a-list-of-a-users-playlists client/get (str spotify-api-url "users/user_id/playlists")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in  m is :user_id, optional keys are :limit and :offset.
     :user_id is the users spotify id.
@@ -286,7 +286,7 @@

 ;TODO - Can you pass :limit and :offset here? Let's assume you can.
 ;TODO - Change this fields string to be a map?
-(spotify-api-call get-a-playlist client/get (str spotify-api-url "users/user_id/playlists/playlist_id")
+(def-spotify-api-call get-a-playlist client/get (str spotify-api-url "users/user_id/playlists/playlist_id")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory keys in  m are :user_id and :playlist_id, optional keys are :fields, :market, :limit and :offset.
     :user_id is the users spotify id.
@@ -299,7 +299,7 @@

     Example: (get-a-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :fields \"href,name,owner\" :market \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call get-a-playlists-tracks client/get (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
+(def-spotify-api-call get-a-playlists-tracks client/get (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory keys in  m are :user_id and :playlist_id, optional keys are :fields, :limit and :offset and :market.
     :user_id is the users spotify id.
@@ -313,7 +313,7 @@
     Example: (get-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :fields \"href,name,owner\":limit 50 :offset 50 :market \"SE\"} \"BQBw-JtC..._7GvA\")")

 ;TODO - Deal with request body data for values of :name and :public.
-(spotify-api-call create-a-playlist client/post (str spotify-api-url "users/user_id/playlists")
+(def-spotify-api-call create-a-playlist client/post (str spotify-api-url "users/user_id/playlists")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory keys in m are :user_id and :name, optional key is :public.
     :user_id is the users spotify id.
@@ -322,7 +322,7 @@

     Example: (create-a-playlist {:user_id \"elkalel\" :name \"The songs you didn't know you liked.\" :public true} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call add-tracks-to-a-playlist client/post (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
+(def-spotify-api-call add-tracks-to-a-playlist client/post (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m are :user_id and :playlist_id, optional keys are :uris and :position.
     :user_id is the users spotify id.
@@ -336,7 +336,7 @@
 ;TODO - Deal with request body data, very nescessary here.
 ;TODO - Deal with correct formatting of :tracks.
 ;TODO - Additional doc string with optional and required values in :tracks.
-(spotify-api-call remove-tracks-from-a-playlist client/delete (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
+(def-spotify-api-call remove-tracks-from-a-playlist client/delete (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m are :user_id, :playlist_id and :tracks, optional keys is :snapshot_id.
     :user_id is the users spotify id.
@@ -347,7 +347,7 @@

     Example: (remove-tracks-from-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :tracks [{:uri \"spotify:track:4iV5W9uYEdYUVa79Axb7Rh\", :positions [2]} {:uri \"spotify:track:1301WleyT98MSxVHPZCA6M\", :positions [7]}]}  \"BQBw-JtC..._7GvA\")")

-(spotify-api-call reorder-a-playlists-tracks client/put (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
+(def-spotify-api-call reorder-a-playlists-tracks client/put (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m are :user_id, :playlist_id, :range_start and :insert_before, optional keys are :range_length and :snapshot_id.
     :user_id is the users spotify id.
@@ -359,7 +359,7 @@

     Example: (reorder-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :range_start 1 :range_length 2 :insert_before 3} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call replace-a-playlists-tracks client/put (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
+(def-spotify-api-call replace-a-playlists-tracks client/put (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m are :user_id and :playlist_id, optional keys are :uris and :position.
     :user_id is the users spotify id.
@@ -369,7 +369,7 @@
     Example: (replace-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :uris \"spotify:track:4iV5W9uYEdYUVa79Axb7Rh,
 spotify:track:1301WleyT98MSxVHPZCA6M\"} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call change-a-playlists-details client/put (str spotify-api-url "users/user_id/playlists/playlist_id")
+(def-spotify-api-call change-a-playlists-details client/put (str spotify-api-url "users/user_id/playlists/playlist_id")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m are :user_id and :playlist_id, optional keys are :name and :public.
     :user_id is the users spotify id.
@@ -380,7 +380,7 @@
     Example: (change-a-playlists-details {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :name \"Fantastic playlist\" :public true} \"BQBw-JtC..._7GvA\")")

 ;Profiles
-(spotify-api-call get-a-users-profile client/get (str spotify-api-url "users/user_id")
+(def-spotify-api-call get-a-users-profile client/get (str spotify-api-url "users/user_id")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory key in m is :user_id.
     :user_id has to be a spotify user id.
@@ -388,13 +388,13 @@
     Example: (get-a-users-profile {:user_id \"elkalel\"} \"BQBw-JtC..._7GvA\")")

 ;TODO - what happens when map is not present or nil?
-(spotify-api-call get-current-users-profile client/get (str spotify-api-url "me")
+(def-spotify-api-call get-current-users-profile client/get (str spotify-api-url "me")
 " Takes an oauth-token t.

     Example: (get-current-users-profile {} \"BQBw-JtC..._7GvA\")")

 ;Search
-(spotify-api-call search client/get (str spotify-api-url "search")
+(def-spotify-api-call search client/get (str spotify-api-url "search")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
     Compulsory keys in m are :q and :type, optional keys are :market, :limit and :offset.
     :q is the search string.
@@ -406,7 +406,7 @@
     Example: (search {:q \"Gerry Rafferty\" :type \"artist\"  :market \"SE\" :limit 50 :offset 50}} \"BQBw-JtC..._7GvA\")")

 ;Tracks
-(spotify-api-call get-a-track client/get (str spotify-api-url "tracks/id")
+(def-spotify-api-call get-a-track client/get (str spotify-api-url "tracks/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 track's id.
@@ -414,7 +414,7 @@

     Example: (get-a-track {:id \"3BEmmHuv5jm0tbCUVI6ceD\" :market \"SE\"} \"BQBw-JtC..._7GvA\")")

-(spotify-api-call get-several-tracks client/get (str spotify-api-url "tracks")
+(def-spotify-api-call get-several-tracks client/get (str spotify-api-url "tracks")
 " 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 track ids.


Typing the loop-locals - not sure we do need them, insights here still to come. hash-set instead of literal to deal with duplicate keys for types.

--- src/cljs/go/compiler.clj
+++ src/cljs/go/compiler.clj
@@ -144,7 +144,7 @@

 (defn go-type [tag]
   (if-let [ns (and (symbol? tag) (namespace tag))]
-    (munge (if (#{'cljs.core ana/*cljs-ns*} (symbol ns))
+    (munge (if ((hash-set 'cljs.core ana/*cljs-ns*) (symbol ns))
              (go-type-fqn tag)
              (str ns "." (go-type-fqn tag))))
     ('{number "float64" boolean "bool" string "string" array "[]interface{}"} tag "interface{}")))
@@ -547,12 +547,11 @@
   (when (or (not= :statement (:context env)) protocol-impl)
     (let [loop-locals (->> (concat (mapcat :params (filter #(and % @(:flag %)) recur-frames))
                                    (mapcat :params loop-lets))
-                           (map munge)
                            seq)]
       (when loop-locals
         (when (= :return (:context env))
           (emits "return "))
-        (emitln "func(" (comma-sep loop-locals) " interface{}) *AFnPrimitive {")
+        (emitln "func(" (comma-sep (typed-params loop-locals)) ") *AFnPrimitive {")
         (when-not (= :return (:context env))
           (emits "return ")))
       (let [name (or name (gensym))


Styling

Styling

--- src/cljs/gtfve/core.cljs
+++ src/cljs/gtfve/core.cljs
@@ -15,9 +15,9 @@
 (defonce map-types (js->clj Maps.MapTypeId :keywordize-keys true))

 (defonce default-opts {:center {:lat 14.653386
-                            :lng 121.032520}
-                   :mapTypeId (:ROADMAP map-types)
-                   :zoom 15})
+                                :lng 121.032520}
+                       :mapTypeId (:ROADMAP map-types)
+                       :zoom 15})

 (defonce gmap (atom nil))


Moved defaults into a def and renamed hashmap function names to be more meaningful

--- src/cljs/htmly/core.cljs
+++ src/cljs/htmly/core.cljs
@@ -53,7 +53,7 @@
 (defn no-local-storage [function]
   function)

-(def app (local-storage (atom {:show-help true
+(def default-data {:show-help true
                                :columns [[{:function :background
                                            :data ["white"]}
                                           {:function :image
@@ -67,10 +67,9 @@
                                                           [["Alter"] ["10"]]
                                                           [["Große"] ["1,30m"]]
                                                           [["Haarfarbe"] ["Braun"]]
-                                                          [["Augenfarbe"] ["Blau"]]]}
-                                           :over [0 0]}]
-                                         [{:function :ulist
-                                           :no 1
+                                                          [["Augenfarbe"] ["Blau"]]]}}]
+
+                                         [{:function :thumbs-up
                                            :data {
                                                   :icon "thumbs-up"
                                                   :title ["Daumen Hoch"]
@@ -79,8 +78,7 @@
                                                          ["One"]
                                                          ["Two"]
                                                          ["Three"]]}}
-                                          {:function :ulist
-                                           :no 2
+                                          {:function :thumbs-down
                                            :data {
                                                   :icon "thumbs-down"
                                                   :title ["Daumen Runter"]
@@ -89,8 +87,7 @@
                                                          ["One"]
                                                          ["Two"]
                                                          ["Three"]]}}
-                                          {:function :olist
-                                           :no 1
+                                          {:function :music
                                            :data {
                                                   :icon "music"
                                                   :title ["Mein Top Lieder"]
@@ -99,8 +96,7 @@
                                                          ["One"]
                                                          ["Two"]
                                                          ["Three"]]}}
-                                          {:function :olist
-                                           :no 2
+                                          {:function :film
                                            :data {
                                                   :icon "film"
                                                   :title ["Mein Top Filme"]
@@ -110,7 +106,7 @@
                                                          ["Two"]
                                                          ["Three"]]}}]

-                                         [{:function :linklist
+                                         [{:function :links
                                            :data {
                                                   :icon "globe"
                                                   :title ["Meine Top Webseiten"]
@@ -130,8 +126,9 @@
                                                           ["Schlange"]
                                                           ["Hai"]]
                                                   :answer 1
-                                                  :button ["Raten"]}}]]})))
-
+                                                  :button ["Raten"]}}]]})
+
+(def app (no-local-storage (atom default-data)))

 (defn edit-title-and-intro [details]
   (dom/span nil
@@ -388,7 +385,7 @@
     (render-state [this state]
       (if (:help state)
         (dom/div nil
-                 (if (== (details :no) 1)
+                 (if (= (details :function) :thumbs-up)
                    (raw-html ulist-text-1)
                    (raw-html ulist-text-2))
                  (source-code
@@ -423,7 +420,7 @@
     (render-state [this state]
       (if (:help state)
         (dom/div nil
-                 (if (== (details :no) 1)
+                 (if (= (details :function) :music)
                    (raw-html olist-text-1)
                    (raw-html olist-text-2))
                  (source-code
@@ -570,9 +567,11 @@
    :title title
    :paragraph paragraph
    :table table
-   :ulist ulist
-   :olist olist
-   :linklist linklist
+   :thumbs-up ulist
+   :thumbs-down ulist
+   :music olist
+   :film olist
+   :links linklist
    :form form})

 (defn step [details owner]


Move table data into a hashmap

Move table data into a hashmap

--- src/cljs/htmly/core.cljs
+++ src/cljs/htmly/core.cljs
@@ -63,11 +63,11 @@
                                           {:function :paragraph
                                            :data ["Etwas text über dich, der dich grob beschreibt. Es muss nicht all zu lang sein, aber genug um einen Eindruck von dir zu bekommen."]}
                                           {:function :table
-                                           :data [
-                                                     [["Alter"] ["10"]]
-                                                     [["Große"] ["1,30m"]]
-                                                     [["Haarfarbe"] ["Braun"]]
-                                                     [["Augenfarbe"] ["Blau"]]]
+                                           :data {:items [
+                                                          [["Alter"] ["10"]]
+                                                          [["Große"] ["1,30m"]]
+                                                          [["Haarfarbe"] ["Braun"]]
+                                                          [["Augenfarbe"] ["Blau"]]]}
                                            :over [0 0]}]
                                          [{:function :ulist
                                            :no 1
@@ -298,13 +298,13 @@
                   (dom/span nil "  <tbody>\n")
                   (apply
                    dom/span nil
-                   (om/build-all table-row-help (:data details)))
+                   (om/build-all table-row-help (-> details :data :items)))
                   (dom/span nil "  </tbody>\n")
                   (dom/span nil "</table>")))
         (dom/table #js {:className "table table-bordered"}
                    (apply
                     dom/tbody nil
-                    (om/build-all table-row (:data details))))))))
+                    (om/build-all table-row (-> details :data :items))))))))

 (defn list-item [details owner]
   (reify


Added meta-errors for :reproductive-fidelity and :reproductive-consistency.

--- src/clojush/evaluate.clj
+++ src/clojush/evaluate.clj
@@ -39,14 +39,27 @@
                         (cond
                           (fn? cat) (cat ind argmap)
                           (= cat :size) (count (:genome ind))
-;                          (= cat :compressibility) 555 ;;TMH fix later
+                          ;(= cat :compressibility) 555 ;;TMH fix later
                           (= cat :total-error) (:total-error ind)
                           (= cat :unsolved-cases) (count (filter #(> % error-threshold)
                                                                  (:errors ind)))
                           (= cat :rand) (lrand)
                           (= cat :rand-bit) (lrand-nth [0 1])
                           (= cat :age) (:age ind)
-                          (= cat :novelty) :novelty ; Keyword will be replaced later, since needs entire population to compute novelty
+                          (= cat :novelty) :novelty ; Keyword will be replaced later,
+                          ;                         ; needs entire population to compute novelty
+                          ;
+                          (= cat :reproductive-fidelity)
+                          (let [g (:genome ind)]
+                            (sequence-similarity
+                              g
+                              (produce-child-genome-by-autoconstruction g g argmap)))
+                          ;
+                          (= cat :reproductive-consistency)
+                          (let [g (:genome ind)]
+                            (sequence-similarity
+                              (produce-child-genome-by-autoconstruction g g argmap)
+                              (produce-child-genome-by-autoconstruction g g argmap)))
                           :else (throw (Exception. (str "Unrecognized meta category: " cat)))))]
     (doall (map meta-error-fn meta-error-categories))))

@@ -130,3 +143,4 @@
                            :history (if print-history (cons te (:history i)) (:history i)))
             me (calculate-meta-errors new-ind argmap)]
         (assoc new-ind :meta-errors me)))))
+


cleaned up binding-note, since it can depend on key order now

--- src/midje/midje_forms/translating.clj
+++ src/midje/midje_forms/translating.clj
@@ -249,7 +249,7 @@
                  (zip/next line-loc)))))

 (defn- binding-note [ordered-binding-map]
-  (let [entries (map (fn [k] (str k " " (pr-str (k ordered-binding-map)))) (keys ordered-binding-map))]
+  (let [entries (map (fn [[variable value]] (str variable " " (pr-str value))) ordered-binding-map)]
     (str "{" (str-join ", " entries) "}")))

 (defn add-one-binding-note [expect-containing-form ordered-binding-map]


Fixed the reset button; added ! to side-effecty functions


todomvc: fix comment

todomvc: fix comment

--- examples/todomvc/src/app/core.cljs
+++ examples/todomvc/src/app/core.cljs
@@ -27,7 +27,7 @@
         ; create app from spec
         app (mvsa/app app-spec)

-        ; create GUI; history is passed into view model to build correct URLs
+        ; create GUI; history is passed into view for rendering links
         [app-view-model app-view] (mvsa/connect-ui app view-model (new-view history))

         ; create debugger GUI


better nil hygiene handling keys

better nil hygiene handling keys

--- src/er_cassandra/key.clj
+++ src/er_cassandra/key.clj
@@ -61,9 +61,9 @@
 (defn extract-collection-key-components
   [coll record-or-key-value]
   (cond
-    (map? coll) (keys coll)
-    (sequential? coll) coll
-    (set? coll) coll
+    (map? coll) (filter identity (keys coll))
+    (sequential? coll) (filter identity coll)
+    (set? coll) (disj coll nil )
     :else (throw (ex-info
                   "not a supported key collection"
                   {:coll coll
@@ -74,7 +74,8 @@
    (extract-key-value-collection key record-or-key-value {}))

   ([key record-or-key-value opts]
-   (let [kv (extract-key-value* key record-or-key-value opts)]
+   (when-let [kv (not-empty
+                  (extract-key-value* key record-or-key-value opts))]
      (let [pre (into [] (take (dec (count kv)) kv))
            coll (last kv)
            lkvs (extract-collection-key-components coll opts)]


playing with an alternate contract syntax.  i find it much cleaner, albiet without the same IDE indentation support

--- src/fogus/me/trammel.clj
+++ src/fogus/me/trammel.clj
@@ -40,6 +40,51 @@
                                forms))]
     (list* 'fn name body)))

+
+(declare kollect-bodies build-kontract)
+
+(defmacro kontract [& forms]
+  (let [name (if (symbol? (first forms))
+               (first forms)
+               nil)
+        body (kollect-bodies (if name
+                               (rest forms)
+                               forms))]
+    `(quote ~body)))
+
+(defn- kollect-bodies [forms]
+  (let [bodies (->> (partition-by vector? forms)
+                    (partition 2))]
+    (for [body bodies]
+      (build-kontract (vec body)))))
+
+(defn- build-kontract [[[sig] expectations :as c]]
+  (let [[L R] (->> expectations
+                   (partition-by #{:requires :ensures})
+                   (partition 2))]
+    (println L)
+    (println)))
+
+(comment
+  (count (kontract doubler
+                   [x]
+                   #_:requires
+                   #_(pos? x)
+
+                   :ensures
+                   (= (* 2 x) %)
+
+                   [x y]
+                   :requires
+                   (pos? x)
+                   (pos? y)
+
+                   :ensures
+                   (= (* 2 (+ x y)) %))))
+
+
+;; USAGE
+
 (comment
   (def doubler
        (contract doubler
@@ -62,6 +107,7 @@
           (pos? x))
          (ensures
           (= (* 2 x) %))
+
          [x y]
          (requires
           (pos? x)


splice in an extra def as if from options

--- clj_record/core.clj
+++ clj_record/core.clj
@@ -20,7 +20,7 @@
             (sql/with-results rows "VALUES IDENTITY_VAL_LOCAL()" (:1 (first rows))))]
       (find-record model-name id))))

-(defn defs-from-options [options] '((def foo "foo from options")))
+(defn defs-from-options [options] nil)

 (defmacro init-model [model-name & options]
   (let [optional-forms (defs-from-options options)]


Leiningen Native Dependencies: whenever deps are updated, target folder is refreshed.

- Fix Issue #577

--- ccw.core/src/clj/ccw/leiningen/classpath_container.clj
+++ ccw.core/src/clj/ccw/leiningen/classpath_container.clj
@@ -553,6 +553,15 @@
   (let [container (leiningen-classpath-container deps)]
     (set-classpath-container java-project CONTAINER-PATH container)))

+(defn refresh-target-folder
+  "Refreshes the target folder of a project, if it exists.
+   project may be anything coercible to an IProject.
+   This function does not call refresh on a background job, nor does it run
+   inside a workspace runnable."
+  [project-coercible]
+  (if-let [target-folder (.getFolder (e/project project-coercible) "target")]
+    (.refreshLocal target-folder (IResource/DEPTH_INFINITE) nil)))
+
 (defn update-project-dependencies
   "Get the dependencies.
    If deps fetched ok: sets lein container, save the dependencies list on disk.
@@ -565,6 +574,7 @@
       (set-lein-container java-project deps)
       (delete-container-markers java-project)
       (save-project-dependencies java-project deps))
+    (refresh-target-folder java-project)
     (catch Exception e
       ;; TODO enhance this in the future ... (more accurate problem markers)
       (let [[jresource message] (resource-message e java-project)


Updated remote naming

Updated remote naming

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -59,6 +59,8 @@
    :wishes (wishes-from-html)
    :code   (get-path)})

+; REMOTES
+
 (defn create-wishlist-rem []
-  (letrem [wishlist (create-wishlist {:title "Default"})]
-    (show-wishlist! wishlist)))
+  (letrem [neu (create-wishlist {:title "Default"})]
+    (show-wishlist! neu)))