getting reasonably speedy

getting reasonably speedy

--- src/blx/sortable.clj
+++ src/blx/sortable.clj
@@ -31,90 +31,66 @@
     (->> (line-seq rdr)
          (mapv parse-json))))

-(defn remove-special-chars [s]
-  ((fnil str/replace "") s #"[_-]" ""))
-
-(defn remove-spaces [s]
-  ((fnil str/replace "") s #" " ""))
+(defn remove-chars [s]
+  (-> s
+      ((fnil str/replace "") #"[ _-]+" "")
+      str/lower-case))

 (defn prepare-product [product]
   (-> product
-      (update :product_name (comp remove-spaces remove-special-chars))))
-
+      (update :product_name remove-chars)
+      (update :model remove-chars)))

 (defn longest-starting-match [a b]
-  (->> [a b]
-       (map (comp remove-spaces remove-special-chars))
-       (map str/lower-case)
-       (apply map vector)
-       (reduce (fn [match-len [a b]]
-                 (if (= a b)
-                   (inc match-len)
-                   (reduced match-len)))
-               0)))
-
+  (reduce (fn [match-len [a b]]
+            (if (= a b)
+              (inc match-len)
+              (reduced match-len)))
+          0
+          (map vector a b)))

 (defn match-manufacturer [mproducts listing]
   (->> (keys mproducts)
-       (some #(when (.startsWith (:manufacturer listing) %)
+       (map remove-chars)
+       (some #(when (.startsWith (remove-chars (:manufacturer listing)) %)
                 %))))

 (defn match-title [products listing]
-  (let [min-match-len 3
+        ; Longer than just manufacturer name
+  (let [min-match-len (max 3 (count (:manufacturer listing)))
         matches (->> products
                      (map #(vector (longest-starting-match (:title listing)
                                                            (:product_name %))
                                    %))
-                     (sort-by first >)
-                     (filter (fn [[_ prod]]
-                               (if (:model prod)
-                                 (.contains (remove-special-chars (remove-spaces (:title listing)))
-                                            (remove-special-chars (remove-spaces (:model prod))))
-                                 true)))
-                     (filter #(> (first %)
-                                 ; Longer than just manufacturer name
-                                 (max min-match-len (count (:manufacturer listing)))))
-                     (take 3))]
+                     (filter (fn [[score prod]]
+                               (and (> score min-match-len)
+                                    (if-let [model (:model prod)]
+                                      (.contains (:title listing) model)
+                                      true))))
+                     (sort-by first >))]
     ; Do not allow ties
     (when (and matches
                (not= (first (first matches))
                      (first (second matches))))
       (first matches))))

-(defn match' [products listing]
-  (println "Trying to match " listing)
-  (let [mproducts (group-by :manufacturer products)
-        est-manufacturer (match-manufacturer mproducts listing)
-        est-products (match-title products listing)]
-    [est-manufacturer est-products]))
+(defn match [products listing]
+  (let [listing' (update listing :title remove-chars)]
+    (when-let [[_ match] (match-title products listing')]
+      [listing match])))

-
-(def match-threshold 20)
-
-(def match-preds
-  [[(fn [products listing]
-      (some #(.startsWith (:manufacturer listing) %)
-            (map :manufacturer products)))
-    20]])
-
-
-(defn match-product
-  "Returns the product matched by listing, or nil if no match."
-  [products listing]
-  (let [score-seq (map (fn [[pred weight]]
-                         (when (pred listing)
-                           weight))
-                       match-preds)]
-    (reduce (fn [score x]
-              (let [score' (+ score x)]
-                (if (>= score' match-threshold)
-                  (reduced score')
-                  score')))
-            0 score-seq)))
-
+(defn domatch [products listings]
+  (let [matches (->> listings
+                     (pmap #(match products %))  ; pmap was a 4x speedup
+                     (filter some?))]
+    (->> matches
+         (group-by second)
+         (map (fn [[prod matching-listings]]
+                {:product_name (:product_name prod)
+                 :listings (map first matching-listings)})))))

 (defn -main


heroku deploy

heroku deploy

--- src/cai/outgoing.clj
+++ src/cai/outgoing.clj
@@ -25,7 +25,6 @@
     [{:action "typing_on"}
      {:message (templates/text-message clever_output)}]))

-
 (defn reply-to-image [sender-id image-url]
   (let [days (mod (reduce + (map #(int %) (seq image-url))) (* 3 365))
         date (time/minus (time/now) (time/days days))
@@ -41,7 +40,6 @@
        {:message (templates/image-message url)}
        {:message (templates/text-message url)})]))

-
 (defn reply-to-audio-or-video [sender-id url]
   (let [text (speech-api/stt url)
         cs-old (get-in @user-map [(keyword sender-id) :cs])


fix mark cell deleted

fix mark cell deleted

--- src/clj/neb/cell.clj
+++ src/clj/neb/cell.clj
@@ -351,10 +351,8 @@
       (assert (> data-len 0))
       (if (= data-len new-data-length)
         (write-cell trunk hash partition schema data :loc cell-loc :planned-data fields :version new-version)
-        (let [result (write-cell trunk hash partition schema data :planned-data fields :version new-version)]
-          (when result
-            (mark-cell-deleted trunk cell-loc data-len)
-            result)))
+        (do (write-cell trunk hash partition schema data :planned-data fields :version new-version)
+            (mark-cell-deleted trunk cell-loc data-len)))
       (assoc data
         :*version* new-version))))


express server

express server

--- src/cljs/server.cljs
+++ src/cljs/server.cljs
@@ -34,24 +34,20 @@
     c))

 (defn handler [req res]
-  (.writeHead res 200 {"Content-Type" "text/plain"})
   (let [jokes-chan (fetch-some-jokes 500)]
     (go
       (while
         (when-let [joke (<! jokes-chan)]
-          (.write res joke)
-          ;; (<! (timeout 2000))
-          ;; curl http://127.0.0.1:1337/
-          (.write res "\n\n")))
-      (.end res))))
+          (.send res joke))))))

-(defn server [handler port]
-  (-> (.createServer http handler)
-      (.listen port)))
+(defn server [handler port cb]
+  (let [app (express)]
+    (.get app "/" handler)
+    (.listen app port cb)))

 (defn -main [& mess]
   (let [port (or (.-PORT (.-env js/process)) 1337)]
-    (server handler port)
-    (println (str "Server running at http://127.0.0.1:" port "/"))))
+    (server handler port
+            #(println (str "Server running at http://127.0.0.1:" port "/")))))

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


remove @import check since it is not supported

--- src/cljss/sheet.cljs
+++ src/cljss/sheet.cljs
@@ -28,13 +28,9 @@
       (swap! cache conj cls-name)
       (let [rules-count (gobj/get (gobj/get sheet "cssRules") "length")]
         (if dev?
-         (if (not= (.indexOf rule "@import") -1)
-           (.insertBefore tag (dom/createTextNode rule) (gobj/get tag "firstChild"))
-           (dom/appendChild tag (dom/createTextNode rule)))
+         (dom/appendChild tag (dom/createTextNode rule))
          (try
-           (if (not= (.indexOf rule "@import") -1)
-             (.insertRule sheet rule 0)
-             (.insertRule sheet rule rules-count))
+           (.insertRule sheet rule rules-count)
            (catch :default e
              (when dev?
                (js/console.warn "Illegal CSS rule" rule))))))))


don't use println where not needed

don't use println where not needed

--- src-brepl/brepl.cljs
+++ src-brepl/brepl.cljs
@@ -2,4 +2,4 @@
   (:require [simple-brepl.client]))

 (if (.-log js/console)
-  (println "hey from brepl"))
+  (.log js/console "hey from brepl"))


Improve nth-input-ar ugen check error message

--- src/overtone/sc/machinery/ugen/check.clj
+++ src/overtone/sc/machinery/ugen/check.clj
@@ -97,7 +97,7 @@
   (every? ar? (drop 1 inputs)))

 (defcheck nth-input-ar [index]
-  (str "The input at index " index " should be audio rate.")
+  (str "The input at index " index " should be audio rate - found " (nth inputs index) " with rate: "(with-out-str (pr (:rate-name (nth inputs index)))))
   (ar? (nth inputs index)))

 (defcheck num-outs-greater-than [n]


Remove convert-units-f for :mass

Remove convert-units-f for :mass

--- src/test_utils/fracture_diagnostics.cljc
+++ src/test_utils/fracture_diagnostics.cljc
@@ -53,14 +53,11 @@

 (defn convert-units-f [from to]
   (let [factors   {[:ft-lb :J]                1.35582
-                   [:kg :lb]                  2.20462262185
                    ;; slurry rate conversion not needed (use [:bbl :m3])
                    [:m3 :bbl]                 6.28981077}
         converter {[:kg-per-m3 :lb-per-cu-ft] #(/ % (factors [:lb-per-cu-ft :kg-per-m3]))
                    [:ft-lb :J]                #(* % (factors [:ft-lb :J]))
                    [:J :ft-lb]                #(/ % (factors [:ft-lb :J]))
-                   [:kg :lb]                  #(* % (factors [:kg :lb]))
-                   [:lb :kg]                  #(/ % (factors [:kg :lb]))
                    [:bbl :m3]                 #(/ % (factors [:m3 :bbl]))
                    [:m3 :bbl]                 #(* % (factors [:m3 :bbl]))}]
     (converter [from to])))
@@ -89,6 +86,7 @@
 (def energy-as (as-f :ft-lb :J 1.35582))
 (def force-as (as-f :lbf :N 4.44822))
 (def length-as (as-f :m :ft 3.28084))
+(def mass-as (as-f :kg :lb 2.20462262185))
 (def power-as (as-f :hp :W 745.69987158227022))
 (def pressure-as (as-f :psi :kPa 6.894757293168361))
 (def proppant-concentration-as (as-f :lb-per-gal :kg-per-m3 119.826))
@@ -656,8 +654,8 @@
         measurement (generate-measurement-f unit)]
     [measurement (measurement-as-f measurement (first (remove (partial = unit) units)))]))

-(generate-measurement-pair (set (quantity-unit-map :length))
-                           rand-length-unit typical-stage-length length-as)
+(generate-measurement-pair (set (quantity-unit-map :mass))
+                           rand-mass-unit typical-proppant-mass mass-as)

 (defn rand-measurement
   ([]


Fix tests.

Fix tests.

--- test/buddy/auth/backends/token_tests.clj
+++ test/buddy/auth/backends/token_tests.clj
@@ -2,8 +2,7 @@
   (:require [clojure.test :refer :all]
             [buddy.core.codecs :refer :all]
             [buddy.core.hash :as hash]
-            [buddy.sign.jws :as jws]
-            [buddy.sign.jwe :as jwe]
+            [buddy.sign.jwt :as jwt]
             [buddy.auth :refer [throw-unauthorized authenticated?]]
             [buddy.auth.backends :as backends]
             [buddy.auth.backends.token :as token]
@@ -46,7 +45,7 @@

 (defn make-jws-request
   [data secret]
-  (let [header (->> (jws/sign data secret)
+  (let [header (->> (jwt/sign data secret)
                     (format "Token %s"))]
     {:headers {"authorization" header}}))

@@ -137,7 +136,7 @@

 (defn make-jwe-request
   [data secret]
-  (let [header (->> (jwe/encrypt data secret)
+  (let [header (->> (jwt/encrypt data secret)
                     (format "Token %s"))]
     {:headers {"authorization" header}}))


centos testing

centos testing

--- test/celestial/integration/workflows.clj
+++ test/celestial/integration/workflows.clj
@@ -1,8 +1,8 @@
 (ns celestial.integration.workflows
   "Testing workflows"
   (:require
-    [celestial.fixtures.core :refer  (with-defaults is-type? with-admin with-conf)]
-    [celestial.fixtures.data :refer (redis-type redis-prox-spec redis-ec2-spec local-conf)]
+    [celestial.fixtures.core :refer (with-defaults is-type? with-admin with-conf)]
+    [celestial.fixtures.data :refer (redis-type redis-prox-spec redis-ec2-spec local-conf redis-ec2-centos)]
     [celestial.fixtures.populate :refer (populate-system)]
     [celestial.persistency.systems :as s]
     [celestial.workflows :as wf])
@@ -40,14 +40,15 @@
         (wf/destroy (spec)) => nil
         ))

-    (fact "aws reload workflows" :integration :ec2 :workflow
+    (fact "aws provisioning workflows" :integration :ec2 :workflow
       (letfn [(spec [] (assoc (s/get-system 1) :system-id 1))]
         (wf/create (spec)) => nil
         (wf/reload (spec)) => nil
         (wf/destroy (spec)) => nil
-        ))
+        )))

-    (fact "aws provision workflows" :integration :ec2 :workflow
+    (with-state-changes [(before :facts (do (populate-system redis-type redis-ec2-centos)))]
+     (fact "aws centos provisioning" :integration :ec2 :workflow
       (letfn [(spec [] (assoc (s/get-system 1) :system-id 1))]
         (wf/create (spec)) => nil
         (wf/stop (spec)) => nil
@@ -55,7 +56,7 @@
         (wf/start (spec)) => nil
         (wf/puppetize redis-type (spec)) => nil
         (wf/destroy (spec)) => nil
-        ))
-    )))
+        )))
+    ))


timbre refer and adding interfaces list key

--- src/aws/provider.clj
+++ src/aws/provider.clj
@@ -24,11 +24,11 @@
     [slingshot.slingshot :refer  [throw+ try+]]
     [celestial.provider :refer (wait-for wait-for-ssh)]
     [celestial.core :refer (Vm)]
-    [celestial.common :refer (import-logging)]
+    [taoensso.timbre :as timbre]
     [celestial.persistency.systems :as s]
     [celestial.model :refer (translate vconstruct)]))

-(import-logging)
+(timbre/refer-timbre)

 (defn wait-for-status [instance req-stat timeout]
   "Waiting for ec2 machine status timeout is in mili"
@@ -49,7 +49,8 @@
 (defn creation-keys [aws]
   (clojure.set/subset? (into #{} (keys aws))
     #{:volumes :min-count :max-count :instance-type :ebs-optimized
-      :key-name :placement :security-groups :subnet-id :allocation-id :block-device-mappings}))
+      :key-name :placement :security-groups :network-interfaces
+      :subnet-id :allocation-id :block-device-mappings}))

 (defn create-instance
    "creates instance from aws"


moving to amazonica

moving to amazonica

--- src/aws/provider.clj
+++ src/aws/provider.clj
@@ -11,11 +11,10 @@

 (ns aws.provider
   (:require
+    [amazonica.aws.ec2 :as ec2]
     [aws.common :refer (with-ctx instance-desc creds image-id)]
     [aws.networking :refer (update-ip set-hostname pub-dns)]
     [aws.volumes :refer (delete-volumes handle-volumes)]
-    [aws.sdk.ec2 :as ec2]
-    [aws.sdk.ebs :as ebs]
     [aws.sdk.eip :as eip]
     [aws.validations :refer (provider-validation)]
     [celestial.persistency :as p]
@@ -48,13 +47,16 @@
     (do ~@body)
     (throw+ {:type ::aws:missing-id :message "Instance id not found"})))

+(defn creation-keys [aws]
+  (clojure.set/subset? (into #{} (keys aws))
+    #{:volumes :min-count :max-count :instance-type :key-name}))
+
 (defn create-instance
    "creates instance from aws"
    [{:keys [aws machine] :as spec} endpoint]
-   {:pre [(clojure.set/subset? (into #{} (keys aws))
-       #{:volumes :min-count :max-count :instance-type :key-name})]}
+   {:pre [(creation-keys aws)]}
    (let [inst (merge (dissoc aws :volumes) {:image-id (image-id machine)})]
-     (-> (with-ctx ec2/run-instances inst) :instances first :id)))
+     (get-in (with-ctx ec2/run-instances inst) [:instances 0 :instance-id])))

 (defconstrainedrecord Instance [endpoint spec user]
   "An Ec2 instance"
@@ -76,7 +78,7 @@
   (start [this]
     (with-instance-id
       (debug "starting" instance-id)
-      (with-ctx ec2/start-instances instance-id)
+      (with-ctx ec2/start-instances {:instance-ids [instance-id]})
       (wait-for-status this "running" [5 :minute])
       (when-let [ip (get-in spec [:machine :ip])]
         (debug (<<  "Associating existing ip ~{ip} to instance-id"))
@@ -89,7 +91,7 @@
     (with-instance-id
       (debug "deleting" instance-id)
       (delete-volumes endpoint instance-id (spec :system-id))
-      (with-ctx ec2/terminate-instances instance-id)
+      (with-ctx ec2/terminate-instances {:instance-ids instance-id})
       (wait-for-status this "terminated" [5 :minute])
       ; for reload support
       (s/update-system (spec :system-id)
@@ -103,7 +105,7 @@
          (debug "clearing dynamic ip from system")
          (s/update-system (spec :system-id)
            (dissoc-in* (s/get-system (spec :system-id)) [:machine :ip])))
-       (with-ctx ec2/stop-instances instance-id)
+       (with-ctx ec2/stop-instances {:instance-ids instance-id})
        (wait-for-status this "stopped" [5 :minute])))

   (status [this]
@@ -127,12 +129,11 @@
   (apply ->Instance (translate spec)))

 (comment
-  (use 'celestial.fixtures)
-  (def m (vconstruct celestial.fixtures/puppet-ami))
-  (:endpoint m )
-  (.status m)
+  (use 'celestial.fixtures.data 'celestial.fixtures.core )
+  (def m (vconstruct redis-ec2-spec))
+  (with-admin (with-conf local-conf (.status m)))
+  (with-conf local-conf (with-admin (.create m)))
   (.start m)
-
   (clojure.pprint/pprint
     (celestial.model/set-env :dev
      (first (:addresses (eip/describe-eip (assoc (creds) :endpoint "ec2.eu-west-1.amazonaws.com") "i-cdd59781")))))


don't index lexemes whose val(path)=:top

--- src/babel/index.cljc
+++ src/babel/index.cljc
@@ -170,9 +170,9 @@

 (defn map-subset-by-path [lexicon path]
   (map-subset-by-path2
-   (vec (set (filter #(not (nil? %))
+   (vec (set (filter #(not (= :top %))
                      (map (fn [entry]
-                            (get-in entry path))
+                            (get-in entry path :top))
                           (flatten (vals lexicon))))))
    (flatten (vals lexicon))
    path))


~(defn generate-question-and-correct-set-dynamic): disable timing by default

--- src/babel/reader.clj
+++ src/babel/reader.clj
@@ -73,7 +73,14 @@

 (defn generate-question-and-correct-set-dynamic [target-spec source-language source-locale
                                                  target-language target-locale]
-  (let [basic-spec {:synsem {:subcat []
+  (let [source-timing? false
+        source-timing-fn (if source-timing? #(time %)
+                             (fn [x] x))
+        target-timing? false
+        target-timing-fn (if target-timing? #(time %)
+                             (fn [x] x))
+
+        basic-spec {:synsem {:subcat []
                              :sem {:subj {:city false}}
                              :cat :verb}
                     :modified false}
@@ -83,7 +90,8 @@
         target-language (keyword target-language)
         target-model @((get models target-language))

-        target-expression (time (babel.generate/generate target-spec target-model))
+        target-expression
+        (target-timing-fn (babel.generate/generate target-spec target-model))

         pred (dag_unify.core/get-in target-expression
                                     [:synsem :sem :pred])
@@ -98,7 +106,8 @@
           basic-spec))

         source-model @((get models source-language))
-        source-expression (time (babel.generate/generate source-spec source-model))]
+        source-expression
+        (source-timing-fn (babel.generate/generate source-spec source-model))]
     (let [pairing
           {:target ((:morph (babel.italiano/medium)) target-expression)
            :pred (dag_unify.core/strip-refs


blind: correctly read floating numbers

blind: correctly read floating numbers

--- src/blind/reader.clj
+++ src/blind/reader.clj
@@ -283,7 +283,13 @@
 (defn match-number [^String s]
   (cond
     (.contains s "/") (match-ratio s (doto (.matcher ratio-pattern s) .matches))
-    (.contains s ".") (match-float s (doto (.matcher float-pattern s) .matches))
+
+    (or (.contains s ".")
+        (.contains s "M")
+        (.contains s "E")
+        (.contains s "e"))
+    (match-float s (doto (.matcher float-pattern s) .matches))
+
     :else (match-int s (doto (.matcher int-pattern s) .matches))))

 (defn- parse-symbol [^String token]


import more common commands

import more common commands

--- src/bolt/config.cljs
+++ src/bolt/config.cljs
@@ -7,23 +7,38 @@
     :amazon {:alias "a" :url "http://www.amazon.com/s/?field-keywords=%s"}
     :google-maps {:alias "map" :url "https://www.google.com/maps/preview#!q=%s"}
     :archive {:alias "arch" :url "http://web.archive.org/web/*/%s"}
-    :google-group {:alias "ggs" :url "http://groups.google.com/groups/dir?q=%s"}
     :youtube {:alias "v" :url "https://www.youtube.com/results?search_query=%s&utm_source=opensearch"}
-    :google-define {:alias "gdef" :url "http://www.google.com/search?q=define:%s"}
+    :google-define {:alias "gd" :url "http://www.google.com/search?q=define:%s"}
     :wikipedia {:alias "w" :url "http://en.wikipedia.org/wiki/Special:Search?search=%s"}
+    ; url doesnt work on phone
     :gmail {:alias "gmas" :url "https://mail.google.com/mail/u/0/?shva=1#search/%s"}
-    :wolfram {:alias "wram" :url "http://www.wolframalpha.com/input/?i=%s"}
-    :ltgtfy {:alias "gfun" :url "http://lmgtfy.com/?q=%s"}
-    :lastfm {:url "http://www.last.fm/search?q=%s"}
+    :wolfram {:alias "wolf" :url "http://www.wolframalpha.com/input/?i=%s"}
+    :lastfm {:alias "lfm" :url "http://www.last.fm/search?q=%s"}
     :clojuredocs {:alias "cd" :url "http://clojuredocs.org/search?q=%s"}
     :flickr {:alias "fl" :url "http://www.flickr.com/search/?q=%s"}
+    :imdb {:url "http://www.imdb.com/find?q=%s&s=all"}
+    :domain {:url "https://domai.nr/?q=%s"}
+    :freebase {:alias "fb" :url "http://www.freebase.com/search?query=%s"}
+    :twitter {:url "https://twitter.com/search?q=%s"}
+    :urbandictionary {:alias "urban" :url "http://www.urbandictionary.com/define.php?term=%s"}

-    ;; just for voice
+    ;; not used on phone
+    :google-group {:alias "ggs" :url "http://groups.google.com/groups/dir?q=%s"}
+    :ltgtfy {:alias "gfun" :url "http://lmgtfy.com/?q=%s"}
+
+    ;; just for phone
     :github {:alias "gh" :url "https://github.com/search?q=%s&ref=simplesearch"}
-    :yelp {:alias "y" :url "http://www.yelp.com/search?find_desc=%s&src=opensearch"}
+    ;; blank out find_loc for localized search
+    :yelp {:alias "y" :url "http://www.yelp.com/search?find_desc=%s&find_loc="}
     :clojars {:alias "cl" :url "http://clojars.org/search?q=%s"}
+    :devdocs {:alias "dev" :url "http://devdocs.io/#q=%s"} ;voice-trouble

-    ;; for local dev
+    ;; semtag
+    :search {:alias "pss" :url "http://semtag.me#/search?query=%s"}
+    :regex-search {:alias "psr" :url "http://semtag.me#/search?query=%s&search-type=regex"}
+    :type {:alias "pst" :url "http://semtag.me#/type/%s"}
+    :thing {:alias "pse" :url "http://semtag.me#/thing/%s"} ;voice-trouble
+    ;; local dev
     :semtag-search {:alias "ss" :url "http://localhost:8000/semtag-web-dev.html#/search?query=%s"}
     :semtag-regex-search {:alias "sr" :url "http://localhost:8000/semtag-web-dev.html#/search?query=%s&search-type=regex"}
     :semtag-type {:alias "st" :url "http://localhost:8000/semtag-web-dev.html#/type/%s"}


alert if no speech api, only create obj when start is clicked

--- src/bolt/speech.cljs
+++ src/bolt/speech.cljs
@@ -34,6 +34,10 @@
     (-> .-onresult (set! result))))

 (defn startButton [event]
-  (.start recognition))
+  (if (.-webkitSpeechRecognition js/window)
+    (do
+      (init)
+      (.start recognition))
+  (js/alert "Web Speech API is not supported by this browser. Use Chrome version 25 or later.")))

-(init)
+


Improve comments

Improve comments

--- src/clojush/args.clj
+++ src/clojush/args.clj
@@ -184,7 +184,8 @@
           :autoconstructive false
           ;; If true, then :genetic-operator-probabilities will be {:autoconstruction 1.0},
           ;; :epigenetic-markers will be [:close :silent], and :atom-generators will include
-          ;; instructions specified via :autoconstructive-genome-instructions. Also sets
+          ;; instructions specified via :autoconstructive-genome-instructions, and other settings
+          ;; specified in augment-for-autoconstruction. Also sets
           ;; :replace-child-that-exceeds-size-limit-with to :empty. Also, empty-genome individuals
           ;; will not be selected as parents. You will probably also want to provide a high value
           ;; for :max-generations. If :autoconstructive is :revertable, rather than true, then
@@ -528,11 +529,17 @@
 (defn augment-for-autoconstruction
   []
   (when (:autoconstructive @push-argmap)
+    ;;
+    ;; handle :revertable
     (if (= :revertable (:autoconstuctive @push-argmap))
       (swap! push-argmap assoc :genetic-operator-probabilities
              {[:make-next-operator-revertable :autoconstruction] 1.0})
       (swap! push-argmap assoc :genetic-operator-probabilities {:autoconstruction 1.0}))
+    ;;
+    ;; set :epigenetic-markers
     (swap! push-argmap assoc :epigenetic-markers [:close :silent])
+    ;;
+    ;; add autoconstructive-specific instructions (:genome or :gtm)
     (doseq [instr (case (:autoconstructive-genome-instructions @push-argmap)
                     :all (registered-for-stacks
                            (if (:autoconstructive-environments @push-argmap)
@@ -787,6 +794,8 @@
                              )))]
       (when (not (some #{instr} (:atom-generators @push-argmap)))
         (swap! push-argmap assoc :atom-generators (conj (:atom-generators @push-argmap) instr))))
+    ;;
+    ;; include ERCs for floats, integers, and booleans
     (swap! push-argmap assoc
            :atom-generators (conj (:atom-generators @push-argmap)
                                   (fn [] (lrand))))
@@ -796,6 +805,8 @@
     (swap! push-argmap assoc
            :atom-generators (conj (:atom-generators @push-argmap)
                                   (fn [] (lrand-nth [true false]))))
+    ;;
+    ;; include instructions for using tags
     (swap! push-argmap assoc
            :atom-generators (conj (:atom-generators @push-argmap)
                                   (tag-instruction-erc
@@ -806,6 +817,8 @@
     (swap! push-argmap assoc
            :atom-generators (conj (:atom-generators @push-argmap)
                                   (tagged-instruction-erc 10000)))
+    ;;
+    ;; enrich autoconstructive rand instructions
     (dotimes [n (:autoconstructive-integer-rand-enrichment @push-argmap)]
       (swap! push-argmap assoc
              :atom-generators (conj (:atom-generators @push-argmap)
@@ -821,6 +834,8 @@
       (swap! push-argmap assoc
              :atom-generators (remove #(= % 'autoconstructive_boolean_rand)
                                       (:atom-generators @push-argmap))))
+    ;;
+    ;; specify that too-big children will be replaced with empty genomes
     (swap! push-argmap assoc
            :replace-child-that-exceeds-size-limit-with :empty)))


Added printing of parameters from command line or problem file

--- src/clojush/core.clj
+++ src/clojush/core.clj
@@ -16,7 +16,7 @@
 ;; for more details.

 (ns clojush.core
-  (:use [clojush.pushgp.pushgp])
+  (:use [clojush.pushgp pushgp report])
   (:gen-class))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -38,5 +38,9 @@
     (require (symbol (first args)))
     (let [example-params (eval (symbol (str (first args) "/argmap")))
           params (merge example-params (apply sorted-map param-list))]
+      (println "######################################")
+      (println "Parameters set at command line or in problem file argmap; may or may not be default:")
+      (print-params (into (sorted-map) params))
+      (println "######################################")
       (pushgp params)
       (System/exit 0))))


Update mongoDB.clj

Update mongoDB.clj

--- src/data/mongoDB.clj
+++ src/data/mongoDB.clj
@@ -7,7 +7,7 @@

 (def conn
   (mongo/make-connection "sites-clojure"
-                         :host "127.0.0.17"
+                         :host "127.0.0.1"
                          :port 27017))

 ;set the connection globally


Add type hints.

Add type hints.

--- src/dsbdp/data_processing_dsl.clj
+++ src/dsbdp/data_processing_dsl.clj
@@ -107,7 +107,7 @@
         rules (:rules dsl-expression)
         output-sym (if (.endsWith output-type *incremental-indicator-suffix*)
                      'output)
-        fn-body-vec (condp (fn [v s] (.startsWith s v)) output-type
+        fn-body-vec (condp (fn [^String v ^String s] (.startsWith s v)) output-type
                       "java-map" (create-proc-fn-body-java-map-out input-sym rules output-sym)
                       "clj-map" (create-proc-fn-body-clj-map-out input-sym rules output-sym)
                       "csv-str" (create-proc-fn-body-csv-str-out input-sym rules)


Fixed could not binding *enable-logging*

--- src/control/core.clj
+++ src/control/core.clj
@@ -359,7 +359,7 @@
                                  " just needs "
                                  task-arg-count
                                  " arguments")))
-               (binding [*enable-logging* (or log false)
+               (binding [*enable-logging* (or *enable-logging* log false)
                          *debug* debug]
                  (when *enable-logging*
                    (println  (str bash-bold


improved match with multiples

improved match with multiples

git-svn-id: 90c135e2b654d5d39218b235c725b90ec5779e48@402 cd74b5cd-e609-0410-a199-9e5d10d28226

--- src/edu/berkeley/ai/util/misc.clj
+++ src/edu/berkeley/ai/util/misc.clj
@@ -35,28 +35,48 @@

-(defn merge-mappings [s1 s2]
-  (filter identity
-     (for [m1 s1, m2 s2] (merge-agree m1 m2))))
+(defmacro merge-mappings [s1 s2]
+  `(when-let [s1# ~s1]
+     (filter identity
+	     (for [m1# s1#, m2# ~s2] (merge-agree m1# m2#)))))
+
+(defmacro merge-multi-mappings [s1 s2]
+  `(when-let [s1# ~s1]
+     (for [m1# s1#, m2# ~s2]
+       (reduce (fn [m# [k# v#]] (assoc m# k# (cons v# (get m# k#)))) m2# m1#))))

 (declare match-mappings)

 (defn match-set [var-tree match-tree]
+  (prn "enter match-set " var-tree match-tree)
+  (prln
   (cond (empty? var-tree)
           (when (empty? match-tree) [{}])
 	(empty? match-tree)
-	  (when (every? #(= (first %) :optional) var-tree) [{}])
+	  (when (every? #(contains? #{:optional :multiple} (first %)) var-tree) [{}])
         :else
 	  (concat-elts
 	   (for [clause var-tree]
-	     (when-let [dm (match-mappings (if (= (first clause) :optional) (second clause) clause) (first match-tree))]
-	       (merge-mappings dm (match-set (remove #(identical? clause %) var-tree) (rest match-tree))))))))
+	     (if (= (first clause) :multiple)
+	         (merge-multi-mappings
+		  (match-mappings (second clause) (first match-tree))
+		  (match-set      var-tree        (rest match-tree)))
+	       (merge-mappings
+		(match-mappings (if (= :optional (first clause)) (second clause) clause) (first match-tree))
+		(match-set      (disj var-tree clause)                                   (rest match-tree)))))))
+  "leave match-set " var-tree match-tree))
+
+;	     (match-mappings
+;	      [clause (if (= (first clause) :multiple) var-tree (disj var-tree clause))]
+;	      [(first match-tree) (rest match-tree)])))))
+
+

 (defn match-mappings "Return a lazy seq of maps of variable bindings for this matching.
                       Binds variables in (unquote x) and (unquote-seq x) - greedy forms,
                       matches any order for sets, and hangles (:optional ... )"
   [var-tree match-tree]
-;  (prn var-tree match-tree)
+  (prn "match-mappings " var-tree match-tree)
   (distinct
     (cond (not (coll? var-tree))
 	    (when (= var-tree match-tree)
@@ -71,6 +91,11 @@
 	    (do (assert-is (= (count (first var-tree)) 2))
 		(lazy-cat (merge-mappings (match-mappings (second (first var-tree)) (first match-tree))
 					  (match-mappings (rest var-tree) (rest match-tree)))
+			  (match-mappings (rest var-tree) match-tree)))
+  	  (and (coll? (first var-tree)) (= (ffirst var-tree) :multiple))
+	    (do (assert-is (= (count (first var-tree)) 2))
+		(lazy-cat (merge-multi-mappings (match-mappings (second (first var-tree)) (first match-tree))
+					  (match-mappings var-tree (rest match-tree)))
 			  (match-mappings (rest var-tree) match-tree)))
 	  (not (coll? match-tree))
             nil
@@ -107,7 +132,13 @@
    '#{[:FOO [unquote x]]
       [:BAR [unquote y]]
       [:optional [:BAZ [unquote z]]]}
-   [[:FOO 12] [:BAR 14]])
+   [[:FOO 12] [:BAR 14]])
+
+  (match-mappings
+   '#{[:FOO [unquote x]]
+      [:BAR [unquote y]]
+      [:multiple [:BAZ [unquote z]]]}
+   [[:FOO 12] [:BAR 14]])

 (defn match-mapping "Return a map of variable bindings for this matching, or


wip: fix introspection query

wip: fix introspection query

--- src/graphql_clj/introspection.clj
+++ src/graphql_clj/introspection.clj
@@ -57,8 +57,9 @@
           (= :union-definition tag) :UNION
           (= :interface-definition tag) :INTERFACE
           (= :enum-definition tag) :ENUM
+          (= :input-definition tag) :INPUT
           (= :scalar-definition tag) :SCALAR
-          :else (assert nil (format "unknown type kind for type: %s" type)))))))
+          :else (assert nil (format "Unhandled type kind for type: %s" type)))))))

 (defn field-kind [field]
   (assert (:tag field) (format "field tag is nil for type: %s" field))
@@ -159,10 +160,11 @@

 (defn args-resolver [arg]
   (assert (:name arg) (format "argument-name is null for:%s" arg))
+  (assert (:type arg) (format "argument type is nil for argument:%s" arg))
   (let [type-name (or (:type-name arg) (get-in arg [:type :name]))
-        kind (or (:kind arg) (type-kind (:type arg)))]
+        kind (type-kind (:type arg))]
     (assert kind (format "argument kind is nil for: %s" arg))
-    (assert type-name (format "argument type name is nil for: %s" arg))
+    ;; (assert type-name (format "argument type name is nil for: %s" arg))
     {:name (:name arg)
      :description (:description arg)


Remove async require and switch to url instead of path

--- src/examples/ttf.clj
+++ src/examples/ttf.clj
@@ -5,11 +5,11 @@
             [zaffre.font :as zfont]
             [zaffre.tilesets :as ztiles]
             [zaffre.util :as zutil]
-            [clojure.core.async :as async :refer [<! <!! go-loop]])
+            [taoensso.timbre :as log])
   (:import (zaffre.font TTFFont)))

 ;(def font (TTFFont. "Ubuntu Mono" 16 true))
-(def font (TTFFont. "https://github.com/aaron-santos/robinson/raw/master/fonts/Boxy/Boxy.ttf" 16 true))
+(def font (zfont/construct (TTFFont. "https://github.com/aaron-santos/robinson/raw/master/fonts/Boxy/Boxy.ttf" 16 true)))
 ;(def font (TTFFont. "/home/santos/src/robinson/fonts/Boxy/Boxy.ttf" 16 true))
 (defn -main [& _]
   (zgl/create-terminal
@@ -29,8 +29,9 @@
         ;; Every 33ms, draw a full frame
         (zat/do-frame terminal 33
           (let [key-in (or @last-key \?)]
+            ;(log/info "rendering frame")
             ;; Draw strings
-            (zutil/put-string terminal :text 0 0 (str "Hello world " key-in))
+            ;(zutil/put-string terminal :text 0 0 (str "Hello world " key-in))
             (zutil/put-string terminal :text 2 1 "╔═════╗")
             (zutil/put-string terminal :text 2 2 "║     ║")
             (zutil/put-string terminal :text 2 3 "║     ║")


read the user info from the same folder

read the user info from the same folder

--- src/fat_jar/core.clj
+++ src/fat_jar/core.clj
@@ -50,18 +50,18 @@
     (->> "./mapper.properties" io/file p/load-from)
     true))

-(defn at-output-folder [options filename]
+(defn at-folder [options filename]
   (str (:output options) "/" filename))

 (defn process [options]
   (do
-        (let [destination-file (at-output-folder options (config :output.filename))
+        (let [destination-file (at-folder options (config :output.filename))

                mappings (get (->> (config :input.mappings)
                                     slurp
                                     edn/read-string) (:template options))

-               user-data (->> (config :input.data)
+               user-data (->> (at-folder options (config :input.data))
                      slurp
                      StringReader.
                      BufferedReader.


Notes to self about query plan optimality.

--- src/fleetdb/core.clj
+++ src/fleetdb/core.clj
@@ -164,12 +164,17 @@
 (defn- where-plan [db where order]
   (let [[op & wrest] where]
     (cond
+      ; only choice -> optimal
       (not op)
         (root-plan db order)

+      ; only simple choice -> probably optimal
       (= :!= op)
         (root-filter-plan db where order)

+      ; when no index, use root-filter-plan -> optimal
+      ; when reasonable index and no order -> probably optimal
+      ; when reasonable index and order -> may be suboptimal, but reasonable
       (= := op)
         (let [[attr aval] wrest]
           (if (index-on db attr)
@@ -179,6 +184,7 @@
              :ordered false}
             (root-filter-plan db where order)))

+      ; as above
       (= :in op)
         (let [[attr in] wrest]
           (if (index-on db attr)
@@ -201,6 +207,9 @@
                :ordered ordered})
             (root-filter-plan db where order)))

+      ; when no indexes use root-filter-plan -> optimal
+      ; when some reasonable, most selective first index -> probably optimal
+      ; when non-index or not-most selective first -> suboptimal
       (= :and op)
         (let [main-plan     (where-plan db (first wrest) order)
               filter-wheres (next wrest)]
@@ -209,6 +218,7 @@
            :ordered (:ordered main-plan)
            :source  main-plan})

+      ; meh -> fair but not great
       (= :or op)
         (let [sub-plans (map #(where-plan db % order) wrest)]
           {:action  :union


gce instance construction

gce instance construction

--- src/gce/provider.clj
+++ src/gce/provider.clj
@@ -1,12 +1,16 @@
 (ns gce.provider
   (:require
+   [clojure.core.strint :refer (<<)]
+   [clojure.data.json :refer (write-str)]
    [gce.validations :refer (validate-provider)]
-   [celestial.provider :refer (wait-for-ssh mappings wait-for)]
+   [celestial.provider :refer (wait-for-ssh mappings wait-for transform os->template)]
+   [clojure.java.data :refer (to-java from-java)]
    [celestial.core :refer (Vm)]
    [taoensso.timbre :as timbre]
    [celestial.persistency.systems :as s]
    [celestial.model :refer (translate vconstruct)])
   (:import
+    (com.google.api.services.compute.model Instance)
     (com.google.api.client.googleapis.javanet GoogleNetHttpTransport)
     (com.google.api.client.json.jackson2 JacksonFactory)
     (com.google.api.client.googleapis.auth.oauth2 GoogleCredential)
@@ -30,22 +34,22 @@
   (let [items (get (-> compute (.instances) (.list project zone) (.execute)) "items")]
     (map clojure.walk/keywordize-keys items)))

-(defn create-instane [spec] {})
+(defn create-instance [spec]
+  (.fromString (JacksonFactory/getDefaultInstance) (write-str spec) Instance))

-(defmacro with-id [& body]
-  )
+(defmacro with-id [& body])

-(defrecord Instance [spec]
+(defrecord GCEInstance [spec system]
   Vm
   (create [this]
-    (let [{:keys [id] :as instance} (create-instane spec) ]
+    (let [{:keys [id] :as instance} (create-instance spec) ]
      (debug "created" id)
-     (s/partial-system (spec :system-id) {:gce {:id id}})
+     (s/partial-system (system :system-id) {:gce {:id id}})
       this))

   (start [this]
     (with-id
-      (let [{:keys [machine]} (s/get-system (spec :system-id))]
+      (let [{:keys [machine]} (s/get-system (system :system-id))]
         (when-not (= "running" (.status this))
           )
         (wait-for-ssh (machine :ip) "root" [5 :minute]))
@@ -57,12 +61,39 @@

   (status [this]))

+(defn into-gce [{:keys [name machine-type zone image]}]
+  {
+    :name name
+    :machineType (<< "zones/~{zone}/machineTypes/~{machine-type}")
+    :disks [{
+      :initializeParams {:sourceImage image} :autoDelete true
+      :type "PERSISTENT" :boot true
+    }]
+    :networkInterfaces [{
+      :accessConfigs [{:type "ONE_TO_ONE_NAT", :name "External NAT" }]
+      :network "global/networks/default"
+    }]
+ })
+
+(defn into-system [args])
+
+(def machine-ts
+  "Construcuting machine transformations"
+   {:image (fn [os] (:image ((os->template :gce) os)))})
+
 (defmethod translate :gce [{:keys [machine gce system-id] :as spec}]
     "Convert the general model into a gce instance"
-    (mappings (merge machine gce {:system-id system-id}) []))
+    (-> (merge machine gce {:system-id system-id})
+     (mappings {:os :image})
+     (transform (machine-ts machine))
+     (juxt into-gce into-system)
+    ))

-(defn validate [spec]
+(defn validate [spec &]
   (validate-provider spec) spec)

 (defmethod vconstruct :gce [spec]
-  (Instance. (validate (translate spec))))
+  (apply ->GCEInstance (validate (translate spec))))
+
+
+


Goddamnit I committed that shit

Goddamnit I committed that shit

--- src/grimoire/api.clj
+++ src/grimoire/api.clj
@@ -309,12 +309,3 @@
                      (.isDirectory d))
           f     (.listFiles d)]
       f)))
-
-
-;; DEV SHIT DO NOT COMMIT
-(def config      {:datastore {:docs "doc-store/"}})
-(def a-group     (first (list-groups     config           )))
-(def a-artifact  (first (list-artifacts  config a-group   )))
-(def a-version   (first (list-versions   config a-artifact)))
-(def a-namespace (first (list-namespaces config a-version )))
-(def a-def       (first (list-fns        config a-namespace)))


Note implementation limitations

Note implementation limitations

--- src/grimoire/api.clj
+++ src/grimoire/api.clj
@@ -47,7 +47,9 @@
   dispatch)

 (defmulti thing->prior-versions
-  "Returns a sequence of things representing itself at earlier or equal versions."
+  "Returns a sequence of things representing itself at earlier or equal
+  versions. Note that this op only supports Versions, Namespaces and
+  Defs. Artifacts and Groups do not have versions."

   {:arglists '[[config thing]]}
   dispatch)
@@ -63,7 +65,7 @@
   "Returns a sequence of pairs [version example-text] for all examples on prior
   or equal versions of the given thing."

-  {:arglists '[[config thing]]}
+  {:arglists '[[config def-thing]]}
   dispatch)

 (defmulti read-meta


remove boxed math warning

remove boxed math warning

--- src/insn/clojure.clj
+++ src/insn/clojure.clj
@@ -52,7 +52,7 @@
                          [sig (symbol iface)]))
         methods (clojure.core/fn [[sig body]]
                   (let [vararg? (= sig vsig)
-                        nargs (if vararg? (dec (count sig)) (count sig))
+                        nargs (long (if vararg? (dec (count sig)) (count sig)))
                         objs (vec (repeat (inc nargs) `Object))
                         prims (when-let [iface (get ifaces sig)]
                                 (mapv {\L :long, \D :double, \O `Object}


Add a way to write docs

Add a way to write docs

--- src/grimoire/api.clj
+++ src/grimoire/api.clj
@@ -225,3 +225,12 @@
           :when (.exists h)
           :when (.isFile h)]
       [v (slurp h)])))
+
+;; Interacting with the datastore - writing
+;;--------------------------------------------------------------------
+(defn write-docs [config thing data]
+  (let [thing  (ensure-thing thing)
+        _      (assert thing)
+        handle (thing->handle config :docs thing)]
+    (->> handle io/writer (json/generate-stream data) (.flush))
+    nil))


Make clojure.lang.IAtom implementation atomic.

--- src/lentes/core.cljc
+++ src/lentes/core.cljc
@@ -166,20 +166,15 @@

      clojure.lang.IAtom
      (reset [self newval]
-       (swap! src #(put lens newval %))
-       (deref self))
+       (focus lens (swap! src #(put lens newval %))))
      (swap [self f]
-       (swap! src (fn [s] (over lens f s)))
-       (deref self))
+       (focus lens (swap! src (fn [s] (over lens f s)))))
      (swap [self f x]
-       (swap! src (fn [s] (over lens #(f % x) s)))
-       (deref self))
+       (focus lens (swap! src (fn [s] (over lens #(f % x) s)))))
      (swap [self f x y]
-       (swap! src (fn [s] (over lens #(f % x y) s)))
-       (deref self))
+       (focus lens (swap! src (fn [s] (over lens #(f % x y) s)))))
      (swap [self f x y more]
-       (swap! src (fn [s] (over lens #(apply f % x y more) s)))
-       (deref self))
+       (focus lens (swap! src (fn [s] (over lens #(apply f % x y more) s)))))

      clojure.lang.IRef
      (addWatch [self key cb]


copy/paste docs into code WIP

copy/paste docs into code WIP

--- src/heffalump/db.clj
+++ src/heffalump/db.clj
@@ -56,8 +56,6 @@
       (entity-fields v)
       (database db))))

-
-
 (defn create-cache
   []
   (->


Update compilation.clj

Update compilation.clj

--- modules/less/src/modular/less/compilation.clj
+++ modules/less/src/modular/less/compilation.clj
@@ -16,6 +16,6 @@
        (merge {:engine :javascript})
        (s/validate {:engine (s/enum :javascript :rhino :nashorn)
                     :less-config {:project-root s/Str
-                                  :source-paths [s/Str]
+                                  :source-path s/Str
                                   :target-path s/Str}})
        map->LessCompilation))


Adding docs and clarifying argument names.

--- src/measure/core.clj
+++ src/measure/core.clj
@@ -17,10 +17,7 @@
 ;; Measure is a library that enables Clojure programs to track critical aspects of
 ;; their behavior.  Using idiomatic wrappers around Coda Hale's excellent
 ;; [Metrics][http://metrics.codahale.com] library, one can measure statistics from
-;; simple counters to
-;; exponentially-decaying histograms.
-;;
-;;
+;; simple counters to exponentially-decaying histograms.

 (ns measure.core
   {}
@@ -43,8 +40,10 @@

 ;; The core construct of measure is the registry.  To be useful, all
 ;; metrics are registered with a registry, which is typically a singleton.
-;;
-;;
+;;
+;; The registry is a collection of named metrics.  Registries are useful both
+;; to group related sets of measurements, and as the vehicle through which
+;; measurements are reported.

 (defn registry
   "Creates and returns a new metrics registry."
@@ -68,10 +67,14 @@

 ;; Gauges can wrap either a function that returns a value or an atom.
 (defn atom?
+  "Returns true if the given value is an atom."
   [maybe-atom]
   (instance? clojure.lang.Atom maybe-atom))

 (defn atom-or-fn
+  "If the value is an atom, returns a no-arg function that derefs it.
+   If the value is a function, it is returned unmodified.
+   Otherwise, an exception is thrown."
   [val]
   (cond (atom? val) (fn [] @val)
         (fn? val) val
@@ -249,17 +252,23 @@
   Timer
   (value [t] (.getCount t)))

+;; Some metrics (histograms, meters, and timers) provide non-scalar information, and `value` is
+;; insufficient for these types.  Meters expose rates, histograms expose distribution snapshots,
+;; and timers expose both.
+
 (defn rates
-  [^Metered metric]
-  {:count (.getCount metric)
-   :15-minute-rate (.getFifteenMinuteRate metric)
-   :5-minute-rate (.getFiveMinuteRate metric)
-   :1-minute-rate (.getOneMinuteRate metric)
-   :mean-rate (.getMeanRate metric)})
+  "Gets the current rate of events for the given measurement."
+  [^Metered meter-or-timer]
+  {:count (.getCount meter-or-timer)
+   :15-minute-rate (.getFifteenMinuteRate meter-or-timer)
+   :5-minute-rate (.getFiveMinuteRate meter-or-timer)
+   :1-minute-rate (.getOneMinuteRate meter-or-timer)
+   :mean-rate (.getMeanRate meter-or-timer)})

 (defn snapshot
-  [^Sampling metric]
-  (let [s (.getSnapshot metric)]
+  "Gets a snapshot of the current distribution for the given measurement."
+  [^Sampling histogram-or-timer]
+  (let [s (.getSnapshot histogram-or-timer)]
     {:size (.size s)
      :min (.getMin s)
      :max (.getMax s)


Deprecated keys must be optional.

Deprecated keys must be optional.

--- src/onyx/schema.cljc
+++ src/onyx/schema.cljc
@@ -328,7 +328,7 @@

 (def EnvConfig
   {:zookeeper/address s/Str
-   :onyx/id (deprecated [:env-config :model :onyx/id])
+   (s/optional-key :onyx/id) (deprecated [:env-config :model :onyx/id])
    :onyx/tenancy-id TenancyId
    (s/optional-key :zookeeper/server?) s/Bool
    (s/optional-key :zookeeper.server/port) s/Int
@@ -357,7 +357,7 @@

 (def PeerConfig
   {:zookeeper/address s/Str
-   :onyx/id (deprecated [:env-config :model :onyx/id])
+   (s/optional-key :onyx/id) (deprecated [:env-config :model :onyx/id])
    :onyx/tenancy-id TenancyId
    :onyx.peer/job-scheduler JobScheduler
    :onyx.messaging/impl Messaging


Add rotation-check-interval-ms to schema

--- src/onyx/schema.cljc
+++ src/onyx/schema.cljc
@@ -375,6 +375,7 @@
    (s/optional-key :onyx.rocksdb.filter/peer-block-cache-size) PosInt
    (s/optional-key :onyx.rocksdb.filter/num-buckets) PosInt
    (s/optional-key :onyx.rocksdb.filter/num-ids-per-bucket) PosInt
+   (s/optional-key :onyx.rocksdb.filter/rotation-check-interval-ms) PosInt
    (s/optional-key :onyx.zookeeper/backoff-base-sleep-time-ms) s/Int
    (s/optional-key :onyx.zookeeper/backoff-max-sleep-time-ms) s/Int
    (s/optional-key :onyx.zookeeper/backoff-max-retries) s/Int


add simple querying ability by kv pair

add simple querying ability by kv pair

When get-doc and get-docs, it has the ability to search data based on
kv supplied in the parameter

--- src/questdb/core.clj
+++ src/questdb/core.clj
@@ -65,7 +65,19 @@
       (let [fdata (read-index-file dbname dbkey)]
         (if-let [key-data (->> (get datum dbkey)
                                (get fdata))]
-          nil))))
+          (let [new-key-data (conj key-data
+                                   (:uuid datum))]
+            (spit (index-path dbname dbkey)
+                  (merge fdata
+                         {(get datum dbkey) new-key-data})))
+          (spit (index-path dbname dbkey)
+                (merge fdata
+                       {(get datum dbkey) #{(:uuid datum)}}))))))
+
+(defn- write-index-keys!
+  [dbname datum]
+  (doseq [datum-key (keys (dissoc datum :uuid))]
+    (write-index-key! dbname datum-key datum)))

 (defn create!
   "Creates a new database with dbname and make initial directories and
@@ -91,6 +103,8 @@
               [])
         {:status true :message (str dbname " has been created")})))

+(declare get-docs)
+
 (defn get-doc
   "Get one doc from dbname, with two arguments it returns the doc in
   dbname with a specified uuid , with three arguments it returns the
@@ -100,8 +114,8 @@
        (let [res-doc (try (read-string (slurp fname))
                           (catch Exception e))]
          res-doc)))
-  ([dbname uuid col]
-     nil))
+  ([dbname kv option]
+     (first (get-docs dbname kv option))))

 (defn get-docs
   "With one argument it returns all docs in dbname, with two arguments
@@ -112,7 +126,13 @@
        (get-doc dbname uuid)))
   ([dbname uuids]
      (for [uuid uuids]
-       (get-doc dbname uuid))))
+       (get-doc dbname uuid)))
+  ([dbname kv option]
+     (let [uuids (-> (read-index-file dbname (key (first kv)))
+                     (get (val (first kv))))]
+       (if option
+         (get-docs dbname uuids)
+         uuids))))

 (defn put-doc!
   "Put data into dbname, data must be a clojure map. However the
@@ -128,12 +148,14 @@
           old-data (get-doc dbname uuid)
           final (merge old-data data)]
       (do (spit fname final)
+          (write-index-keys! dbname final)
           final))
     (let [uuid (uuid)
           fname (id-path dbname uuid)
           final (assoc data :uuid uuid)]
       (do (spit fname final)
           (add-uuid! dbname uuid)
+          (write-index-keys! dbname final)
           final))))

 (defn put-docs!


enabled monitoring mode

enabled monitoring mode

--- src/server/core.cljs
+++ src/server/core.cljs
@@ -10,6 +10,8 @@
 (defonce express (nodejs/require "express"))
 (defonce app (express))
 (defonce server (.Server (nodejs/require "http") app))
+(defonce redis-client (.createClient (nodejs/require "redis")))
+(defonce util (nodejs/require "util"))

 (client-interface/initialize! server)

@@ -22,6 +24,14 @@
 (.get app "/rooms/:id" #(. %2 (render "room" (clj->js {:roomid (.-id (.-params %1))}))))

 (defn -main []
+  (.monitor redis-client
+    (fn [err res]
+      (println "Entering redis-monitoring mode")))
+
+  (.on redis-client "monitor"
+    (fn [timestamp args]
+      (println "REDIS:" timestamp ": " (.inspect util args))))
+
   (println (str "Listening on port " port))
   (client-interface/start-listening!)
   (.listen server port))


CMR-1718: Added another comment. Removed print statements used for debugging in CI.

--- common-lib/test/cmr/common/test/date_time_range_parser.clj
+++ common-lib/test/cmr/common/test/date_time_range_parser.clj
@@ -16,20 +16,9 @@
     (are [string start end]
          (let [interval (p/parse-datetime-range string)
                range-start (:start-date interval)
-               range-end (:end-date interval)
-               matches (and (= start (to-utc range-start))
-                            (= end (to-utc range-end)))]
-           (when-not matches
-             (println "Failure:"
-                      (pr-str `(and (= ~start (to-utc ~range-start))
-                                     (= ~end (to-utc ~range-end)))))
-             (println "start:" start)
-             (println "end:" end)
-             (println "range-start:" range-start)
-             (println "range-end:" range-end)
-             (println "(to-utc range-start):" (to-utc range-start))
-             (println "(to-utc range-end)):" (to-utc range-end)))
-           matches)
+               range-end (:end-date interval)]
+           (and (= start (to-utc range-start))
+                (= end (to-utc range-end))))

          "1987-01-01T00:00:00.000Z,1990-01-01T00:00:00.000Z"
          (t/date-time 1987 1 1 0 0 0) (t/date-time 1990 1 1 0 0 0)
@@ -49,6 +38,12 @@
          ;; This test fails in CI due to the issue descirbed in CMR-1737
          ; "P1Y2M10DT2H30M/2008-05-11T15:30:00Z"
          ; (t/date-time 2007 3 1 14 0 0) (t/date-time 2008 5 11 15 30 0)
+
+         ;; This tests fail locally assuming the code is run on a machine
+         ;; which is using Eastern Time Zone. But succeeds on a machine using UTC.
+         ;; "1987-03-02T00:00:00.000Z/P1Y2M10DT2H30M"
+         ;; (t/date-time 1987 3 2 0 0 0) (t/date-time 1988 5 12 2 30 0)
+

          "/2001-02-01T10:30:00Z"
          nil (t/date-time 2001 2 1 10 30 0)


add benchmarks for standard lib fns on strings & arrays

--- benchmark/cljs/benchmark_runner.cljs
+++ benchmark/cljs/benchmark_runner.cljs
@@ -29,6 +29,15 @@
 (println ";;; satisfies?")
 (simple-benchmark [coll (list 1 2 3)] (satisfies? ISeq coll) 1000000)
 (simple-benchmark [coll [1 2 3]] (satisfies? ISeq coll) 1000000)
+(println)
+
+(println ";;; array & string ops")
+(simple-benchmark [coll (array 1 2 3)] (seq coll) 1000000)
+(simple-benchmark [coll "foobar"] (seq coll) 1000000)
+(simple-benchmark [coll (array 1 2 3)] (first coll) 1000000)
+(simple-benchmark [coll "foobar"] (first coll) 1000000)
+(simple-benchmark [coll (array 1 2 3)] (nth coll 2) 1000000)
+(simple-benchmark [coll "foobar"] (nth coll 2) 1000000)
 (println)

 (println ";;; list ops")


Close handle later, after new compacted snapshot is written

--- src/onyx/state/log/bookkeeper.clj
+++ src/onyx/state/log/bookkeeper.clj
@@ -94,9 +94,9 @@
             {:job-id job-id :task-id task-id :slot-id slot-id
              :ledger-handle (.getId ^LedgerHandle @ledger-handle) :current-ids current-ids})
       (future
-        (close-handle previous-handle)
         (let [;; Write compacted as a batch
               compacted [{:type :compacted
+                          ;; TODO: add a timeout when derefing here.
                           :filter-snapshot @filter-snapshot
                           :extent-state extent-snapshot}]
               compacted-ledger (new-ledger client peer-opts)
@@ -106,6 +106,7 @@
                           compacted-serialized
                           HandleWriteCallback
                           (fn []
+                            (close-handle previous-handle)
                             (emit-latency-value :window-log-compaction monitoring (- (System/currentTimeMillis) start-time))
                             (>!! outbox-ch
                                  {:fn :compact-bookkeeper-log-ids


Add projectsheader

Add projectsheader

--- app/src/cljs/app/components.cljs
+++ app/src/cljs/app/components.cljs
@@ -56,7 +56,7 @@

 (defn single-project-component
   [project]
-  [:div
+  [:div.projectcomponent.mdl-card.mdl-shadow--2dp
    [:div.projecttitle
     [:a {:href (:url project)} (:title project)]]
    [:div.projectimg
@@ -68,7 +68,10 @@
   [projects]
   [:div#projects
    [section-component
-    (into [:div.project] (map #(single-project-component %) projects))]])
+    [:div.projectsheader.mdl-grid
+     [:div.mdl-cell.mdl-cell--12-col
+      [:h3 "Projects"]]
+     (into [:div.project] (map #(single-project-component %) projects))]]])

 (defn single-employment-component
   [employment]


Remove alias and just use fully qualified name instead

--- src/provisdom/spectomic/core.cljc
+++ src/provisdom/spectomic/core.cljc
@@ -3,8 +3,6 @@
     [clojure.spec :as s]
     [clojure.spec.gen :as sgen]
     [provisdom.spectomic.specs :as spectomic]))
-
-(alias 'tgen 'clojure.test.check.generators)

 ;; this could be a multimethod?
 (def ^:private class->datomic-type
@@ -52,7 +50,7 @@
                                    (not-empty s)
                                    true))) (s/gen spec))
         samples (binding [s/*recursion-limit* 1]
-                  (sgen/sample ((resolve `tgen/resize) 10 g) 100))
+                  (sgen/sample ((resolve 'clojure.test.check.generators/resize) 10 g) 100))
         types (sample-types samples)]
     ;; Makes sure we are getting consistent types from the generator. If types are inconsistent then schema
     ;; generation is unclear.


don't send all errors to campfire

don't send all errors to campfire

--- src/shuppet/core.clj
+++ src/shuppet/core.clj
@@ -118,15 +118,18 @@
      (pmap (fn [app-name]
              (with-ent-bindings environment
                (try+
-                 (shuppet/apply-config environment app-name)
-                 (catch [:type :shuppet.git/git] {:keys [message]}
-                   (warn message))
-                 (catch Exception e
-                   (cf/error  {:environment environment
-                               :title "error while applying configs"
-                               :app-name app-name
-                               :message (.getMessage e) })
-                   (error (str app-name " in " environment " failed: " (util/str-stacktrace e)))))))
+                (shuppet/apply-config environment app-name)
+                (catch [:type :shuppet.git/git] {:keys [message]}
+                  (warn message))
+                (catch java.util.concurrent.ExecutionException e
+                  (cf/error {:environment environment
+                             :title "error while loading config"
+                             :app-name app-name
+                             :message (.getMessage e) })
+                  (error (str app-name " config in " environment " cannot be loaded: " (util/str-stacktrace e))))
+
+                (catch Exception e
+                  (error (str app-name " in " environment " failed: " (util/str-stacktrace e)))))))
            names))))

 (defn configure-apps


Housekeeping

Housekeeping

--- src/taoensso/carmine/protocol.clj
+++ src/taoensso/carmine/protocol.clj
@@ -24,7 +24,7 @@
 (def ^:private ^:const charset     "UTF-8")
 (def ^:private ^:const bytes-class (Class/forName "[B"))

-;;; Wrapper types to box values for which we'd like specific `send-arg` behaviour
+;;; Wrapper types to box values for which we'd like specific coercion behaviour
 (deftype Serialized [value])
 (deftype Raw        [value])


core: when-not

core: when-not

--- core.clj
+++ core.clj
@@ -347,3 +347,9 @@
   {:added "1.0"}
   [test & body]
   (list 'if test (cons 'do body)))
+
+(defmacro when-not
+  "Evaluates test. If logical false, evaluates body in an implicit do."
+  {:added "1.0"}
+  [test & body]
+    (list 'if test nil (cons 'do body)))


easing, timing accuracy, less garbage

easing, timing accuracy, less garbage

--- core.clj
+++ core.clj
@@ -3,20 +3,10 @@
   (:import [UnityEngine Color Vector3 GameObject Color]))

-;TODO
-;[ ] deftween fn for +'ing target and value for relative target
-;[ ] link! protocol for adding callbacks
-;[ ] callback should handle sequences
-;[ ] delay functionality (in link! ?)
-;[ ] tweens should call finish with remainder float, if a callback is a tween add remainder to start time
-;[x] when recycling tween comp or destroying, make sure uid is dissoc'd from REGISTRY
-
-(defn -V+ [^Vector3 a ^Vector3 b] (Vector3/op_Addition a b))
-
+(defn- -V+ [^Vector3 a ^Vector3 b] (Vector3/op_Addition a b))

 (def ^:private UID (atom 0))
 (def REGISTRY (atom {}))
-(def PROP-GETS (atom {}))

 (defn finish [uid c]
   (when-let [f (get @REGISTRY uid)]
@@ -34,6 +24,19 @@
           (cond (< r 0.5) (/ (fin (* 2 r)) 2)
                   :else (- 1 (/ (fout (* 2 (- 1 r))) 2))))})

+(def ^:private easeregistry
+  (into {}
+  (for [in [nil :pow2 :pow3 :pow4 :pow5]
+      out [nil :pow2 :pow3 :pow4 :pow5]
+      :let [infn (get easing in)
+            outfn (get easing out)]]
+      (cond (= [in out] [nil nil]) {[in out] #(identity %)}
+        (= out nil) {[in out] (fn [r] ((:in easing) infn r))}
+        (= in nil) {[in out] #((:out easing) outfn %)}
+        :else {[in out] #((:inout easing) infn outfn %)}
+
+        ))))
+

 (deftype Tween [^System.MonoType component opts callbacks]
   clojure.lang.IObj
@@ -62,41 +65,33 @@
   clojure.lang.IFn
   (invoke [this go]
     (let [pre-c (.GetComponent go component)
-        c (or pre-c (.AddComponent go component))
-        uid (int (swap! UID inc))]
+        c (or pre-c (.AddComponent go component))]
       (set! (.active c) true)
       (set! (.value c) (.target c))
       (if pre-c
-        (do (swap! REGISTRY dissoc (.uid c))
-            (set! (.value c) (.target c)))
-        (set! (.value c)  ((.getfn c) go)))
-      (when @callbacks
-        (swap! REGISTRY conj {uid @callbacks}))
-      (set! (.uid c) uid)
-      (set! (.start c) (float (UnityEngine.Time/time)))
-      (set! (.duration c) (float (:duration opts)))
+        (do (set! (.value c) (.target c)))
+        (do (set! (.value c)  ((.getfn c) go))
+             ))
+      (set! (.uid c) (int (swap! UID inc)))
+      (if @callbacks
+        (swap! REGISTRY conj {(.uid c) @callbacks})
+        (swap! REGISTRY dissoc (.uid c)))

-
+      (set! (.start c) (- (+ (UnityEngine.Time/time) (:delay opts)) (.delay c)))
+      (set! (.duration c) (:duration opts))
+      (set! (.delay c) 0.0)
+
       (if (:+ opts)
         (do ;(set! (.relative c) true)
             (set! (.target c) ((.addfn c) (.value c) (:target opts))))
         (set! (.target c) (:target opts)))
       (when-not (= (.easesig c) [(:in opts) (:out opts)])
-        (set! (.easesig c) [(:in opts)(:out opts) ])
-        (cond
-          (and (:in opts) (:out opts))
-            (set! (.easefn c) #((:inout easing) (get easing (:in opts)) (get easing (:out opts)) %))
-          (:in opts)
-            (set! (.easefn c) #((:in easing) (get easing (:in opts) ) %))
-          (:out opts)
-            (set! (.easefn c) #((:out easing) (get easing (:out opts)) %))
-          :else
-            (set! (.easefn c) (fn [r] r))))
-      )
-      go))
+        (set! (.easesig c) [(:in opts) (:out opts)])
+        (set! (.easefn c) (get easeregistry [(:in opts)(:out opts) ])))
+      go)))

 (defn make [c target & more]
-  (let [args (conj {:target target :duration 1.0 :+ false :callback nil}
+  (let [args (conj {:target target :duration 1.0 :+ false :callback nil :delay 0.0}
         (into {} (mapv
           #(cond
             (= :+ %) {:+ true}
@@ -130,48 +125,49 @@
 (defmacro deftween [sym props & methods ] ;getter valuer & setter
   (let [{:keys [getter valuer setter adder]} (conj default-methods (into {} (map sort-methods methods)))
         compsym (symbol (str sym "_tween"))
-        res-props (concat '[^boolean active ^float delay ^float start ^float duration ^boolean relative ^float ratio ^int uid
+        res-props (concat '[^boolean active ^System.Double delay ^System.Double start ^System.Double duration ^boolean relative ^float ratio ^int uid
                            getfn addfn easefn easesig] props)
         [[this] get-more] getter
         [[this-v] value-more] valuer
         getterfn (cons 'fn getter)
         set-more (or setter (list 'set! get-more value-more))]
-  `(~'do
-    (~'swap! ~'tween.core/PROP-GETS ~'conj {(~'str (~'quote ~compsym)) (~'fn [~this] ~get-more)})
-    (~'arcadia.core/defcomponent ~compsym ~res-props
-     (~'Awake [~this]
-      ('~use '~'hard.core)
-        (~'set! (~'.getfn ~this) ~getterfn)
-        (~'set! (~'.addfn ~this) ~adder)
-        (~'set! (~'.duration ~this) (float 5.0))
-        (~'set! (~'.start ~this) (~'UnityEngine.Time/time))
-        (~'set! (~'.value ~this) ~get-more)
-        (~'set! (~'.target ~this) ~get-more))
-     (~'Update [~this-v]
-        (~'if (~'.active ~this-v)
-
-          (~'if  (~'> (~'- (~'UnityEngine.Time/time) (~'.start ~this-v)) (~'.duration ~this-v))
-              (~'do
-                (~'set! (~'.ratio ~this-v) ~'(float 1.0))
+`(do
+
+  (arcadia.core/defcomponent ~compsym ~res-props
+   (~'Awake [~this]
+      (set! (.getfn ~this) ~getterfn)
+      (set! (.addfn ~this) ~adder)
+      (set! (.duration ~this) 5.0)
+      (set! (.start ~this) (UnityEngine.Time/time))
+      (set! (.value ~this) ~get-more)
+      (set! (.target ~this) ~get-more))
+   (~'Update [~this-v]
+
+      (if (.active ~this-v)
+            (if  (> (- (UnityEngine.Time/time) (.start ~this-v))
+                    (.duration ~this-v))
+
+              (do (set! (.ratio ~this-v) (float 1.0))
                 ~set-more
-                (~'set! (~'.active ~this-v) ~'false)
-                (~'tween.core/finish (~'.uid ~this-v) (~'.gameObject ~this-v))
-                (~'set! (~'.delay ~this-v) (~'float (~'- (~'.delay ~this-v) (~'- (~'- (~'UnityEngine.Time/time) (~'.start ~this-v)) (~'.duration ~this-v))))))
+                (set! (.active ~this-v) false)
+                (set! (.delay ~this-v)
+                  (- (- (UnityEngine.Time/time) (.start ~this-v))
+                     (.duration ~this-v)))
+                (tween.core/finish (.uid ~this-v) (.gameObject ~this-v)))

-          (~'do
-                (~'set! (~'.ratio ~this-v)
-                  (~'float ((~'.easefn ~this)
-                   (~'/ (~'- (~'UnityEngine.Time/time) (~'.start ~this-v)) (~'.duration ~this-v))
-                   )
-                  ))
-                ~set-more)
-          )))
-    ~'(OnDestroy [this]
-        (swap! tween.core/REGISTRY dissoc (.uid this))))
-    (~'defn ~sym [~'& ~'more] (~'apply ~'tween.core/make (~'cons ~compsym ~'more)))
-
-  )))
-
+              (do
+                (set! (.ratio ~this-v)
+                  (float ((.easefn ~this)
+                   (/ (- (UnityEngine.Time/time) (.start ~this-v))
+                      (.duration ~this-v)) )))
+                 ~set-more)) ))
+  (~'OnDestroy [~'this]
+      (swap! tween.core/REGISTRY dissoc (.uid ~'this))))
+
+  (defn ~sym ~'[& more] (apply tween.core/make (cons ~compsym ~'more)))
+
+)))
+

@@ -216,3 +212,4 @@

+


Fix missing assertion in test

Fix missing assertion in test

--- test/refactor_nrepl/util_test.clj
+++ test/refactor_nrepl/util_test.clj
@@ -15,12 +15,14 @@
 (def set-location [8 35])
 (def map-location [8 28])
 (def weird-location [2 5])
+(def println-location [6 8])

 (deftest get-enclosing-sexp-test
-  (is (= "[some :bindings
-        more :bindings]"
-         (apply get-enclosing-sexp file-content binding-location)))
-  (is (= "(println #{some}
+  (is (= (apply get-enclosing-sexp file-content binding-location)
+         "[some :bindings
+        more :bindings]"))
+  (is (= (apply get-enclosing-sexp file-content println-location)
+         "(println #{some}
              ;; helpful comment
              (prn {\"foo\" {:qux [#{more}]}}))"))
   (is (= (apply get-enclosing-sexp file-content set-location) "#{more}"))


Fixed test

Fixed test

--- test/staircase/test/histories.clj
+++ test/staircase/test/histories.clj
@@ -56,7 +56,7 @@
     (let [histories (component/start (new-history-resource :db {:connection db-spec}))
           new-id (create histories {:title "My new history" :description "A testing history"})
           got (get-one histories new-id)
-          hists (get-all histories)]
+          hists (into [] (get-all histories))]
       (testing "Return value of create"
         (is (instance? java.util.UUID new-id))
         (is (instance? java.util.Date (:created_at got))))
@@ -76,7 +76,7 @@
         (is (exists? histories new-id)))
       (let [updated (update histories new-id {:title "changed the title" :created_at "sneaky attempt to change the past"})
             retrieved (get-one histories new-id)
-            hists (get-all histories)]
+            hists (into [] (get-all histories))]
         (testing "Changed the title"
           (is (= "changed the title" (:title updated)))
           (is (= (:created_at got) (:created_at updated)))


fix missing def

fix missing def

--- figwheel-repl/src/figwheel/repl.cljc
+++ figwheel-repl/src/figwheel/repl.cljc
@@ -621,6 +621,8 @@
 ;; ------------------------------------------------------------------
 ;; long polling is a bit complex - but this currently appears to work as well
 ;; as websockets, it is heavier overall and much harder to determine when it is closed
+
+(declare send-for-response)

 (defn ping [conn] (send-for-response [conn] {:op :ping}))


Added docstring to the check task. Should show up in cake help now.


using rolling appender and using timbre 4.0.1 merge-config!


all JavaScriptFiles must provide a namespace

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -276,7 +276,8 @@
   ([foreign ^URL url provides requires]
      (javascript-file foreign url nil provides requires nil nil))
   ([foreign ^URL url source-url provides requires lines source-map]
-     (JavaScriptFile. foreign url source-url (map name provides) (map name requires) lines source-map)))
+    (assert (first provides) (str source-url " does not provide a namespace"))
+    (JavaScriptFile. foreign url source-url (map name provides) (map name requires) lines source-map)))

 (defn map->javascript-file [m]
   (javascript-file


(maint) Remove duplicate `puppetlabs.trapperkeeper.services` requirement

We already require this namespace as `tk-service` above.

--- test/unit/puppetlabs/services/jruby/jruby_puppet_testutils.clj
+++ test/unit/puppetlabs/services/jruby/jruby_puppet_testutils.clj
@@ -17,8 +17,7 @@
             [puppetlabs.services.jruby-pool-manager.jruby-pool-manager-service :as jruby-pool-manager]
             [puppetlabs.trapperkeeper.services.scheduler.scheduler-service :as scheduler-service]
             [puppetlabs.trapperkeeper.services.status.status-service :as status-service]
-            [puppetlabs.trapperkeeper.services.webrouting.webrouting-service :as webrouting-service]
-            [puppetlabs.trapperkeeper.services :as tk-services])
+            [puppetlabs.trapperkeeper.services.webrouting.webrouting-service :as webrouting-service])
   (:import (clojure.lang IFn)
            (com.puppetlabs.jruby_utils.jruby ScriptingContainer)
            (puppetlabs.services.jruby_pool_manager.jruby_schemas JRubyInstance)
@@ -370,7 +369,7 @@
    (add-mock-jruby-pool-manager-service services config create-mock-jruby-puppet))
   ([services config mock-jruby-puppet-fn]
    (->> services
-        (remove #(= :PoolManagerService (tk-services/service-def-id %)))
+        (remove #(= :PoolManagerService (tk-service/service-def-id %)))
         vec
         (cons (mock-jruby-pool-manager-service
                config


allow (parse) to take a vector of tokens (i.e. do the tokenization outside of here, for example in a language-dependent function)

--- src/babel/parse.cljc
+++ src/babel/parse.cljc
@@ -32,6 +32,7 @@
    size is equal to _size_."
   ;; for example:
   ;; (span-map 5) =>
+  ;;
   ;; {1 ([0 1]         [1 2] ...) ;; all of these are of size 1
   ;;  2 ([[0 1] [1 2]] [[1 2] [2 3]] ... ) ;; each pair has a combined size of 2
   ;;  3 ([[0 2] [2 3]] [[1 2] [2 3]] ... ) ;; each pair has a combined size of 3
@@ -110,29 +111,41 @@
                            (get span-map n)))))))

 (defn parse
-  "return a list of all possible parse trees for a string or a list of lists of maps
-   (a result of looking up in a dictionary a list of tokens from the input string)"
-  [input model]
-  (log/info (str "parsing input: '" input "'"))
-  (let [tokens (string/split input tokenizer)
-        token-count (count tokens)
-        token-count-range (range 0 token-count)
-        input-map (zipmap (map (fn [i] [i (+ i 1)])
-                               token-count-range)
-                          (map (fn [i] [(nth tokens i)])
-                               token-count-range))]
-    (log/debug (str "input map:" input-map))
-    (let [all-parses
-          (parses input-map token-count model
-                  (span-map token-count))
-          result
-          {:token-count token-count
-           :complete-parses
-           (filter map? (get all-parses
-                             [0 token-count]))
-           :all-parses all-parses}]
-      (if (empty? (:complete-parses result))
-        (log/warn (str "could not parse: " input))
-        (log/info (str "successfully parsed input: '" input "'")))
-      (:complete-parses result))))
+  "return a list of all possible parse trees for a string or a sequence of tokens.
+   In the latter case, the tokens will be produced by splitting a string in
+   some language-dependent. If the input is a string, then use a
+   language-independent tokenizer to turn the string into a sequence of tokens."
+  ([input model]
+   (log/info (str "parsing input: '" input "'"))
+   (cond (string? input)
+         (parse (string/split input tokenizer) model)
+
+         (or (seq? input) (vector? input))
+         ;; assume input is a list of tokens.
+         (let [tokens input
+               token-count (count tokens)
+               token-count-range (range 0 token-count)
+               input-map (zipmap (map (fn [i] [i (+ i 1)])
+                                      token-count-range)
+                                 (map (fn [i] [(nth tokens i)])
+                                      token-count-range))]
+           (log/debug (str "input map:" input-map))
+           (let [all-parses
+                 (parses input-map token-count model
+                         (span-map token-count))
+                 result
+                 {:token-count token-count
+                  :complete-parses
+                  (filter map? (get all-parses
+                                    [0 token-count]))
+                  :all-parses all-parses}]
+             (if (empty? (:complete-parses result))
+               (log/warn (str "could not parse: " input))
+               (log/info (str "successfully parsed input: " input "")))
+             (:complete-parses result)))

+         true
+         (throw (Exception. "Don't know how to parse input of type: " (type input))))))
+
+
+


some more clojure

some more clojure

--- week6-clojure/src/week6_clojure/core.clj
+++ week6-clojure/src/week6_clojure/core.clj
@@ -1,9 +1,4 @@
 (ns week6-clojure.core)
-
-(defn foo
-  "I don't do a whole lot."
-  [x]
-  (println x "Hello, World!"))

 (defn big
   "From Week 6 Day 1 exercises: returns true if a string st is longer than n characters"
@@ -17,3 +12,9 @@
   (def types {clojure.lang.PersistentList :list, clojure.lang.PersistentList$EmptyList :list, clojure.lang.PersistentArrayMap :map, clojure.lang.PersistentVector :vector})
   (types (class col))
 )
+
+(defmacro unless_or_else
+  "From Week 6 Day 2 exercises: unless with an else branch"
+  [condition body else_body]
+  (list 'if (list 'not condition) body else_body)
+)


Revert "few perf improvements, it's still 100x slower than how it should be, I can't figure it out why"

This reverts commit 0aaf1b7c284f30afbb75e7404f6139b1625c4a38 since it only worsened the code and was no significant speed improvement

Conflicts:

	src/blind/reader.clj

--- src/blind/reader.clj
+++ src/blind/reader.clj
@@ -97,26 +97,26 @@

 (defn- whitespace?
   "Checks whether a given character is whitespace"
-  [ch]
+  [^Character ch]
   (if ch
-    (or (Character/isWhitespace ^char ch) (identical? \, ch))))
+    (or (Character/isWhitespace ch) (= \, ch))))

 (defn- numeric?
   "Checks whether a given character is numeric"
-  [ch]
+  [^Character ch]
   (if ch
-    (Character/isDigit ^char ch)))
+    (Character/isDigit ch)))

 (defn- comment-prefix?
   "Checks whether the character begins a comment."
   [ch]
-  (identical? \; ^char ch))
+  (= \; ^char ch))

 (defn- number-literal?
   "Checks whether the reader is at the start of a number literal"
-  [reader initch]
+  [reader ^Character initch]
   (or (numeric? initch)
-      (and (or (identical? \+ ^char initch) (identical? \- ^char initch))
+      (and (or (= \+ initch) (= \- initch))
            (numeric? (peek-char reader)))))

 (declare read macros dispatch-macros)
@@ -130,20 +130,21 @@
   [rdr & msg]
   (throw (ex-info (apply str msg)
                   (merge {:type :reader-exception}
-                         (if (instance? IndexingPushbackReader (class rdr))
+                         (if (satisfies? IndexingReader rdr)
                            {:line (get-line-number rdr)
                             :column (get-column-number rdr)})))))

 (defn macro-terminating? [ch]
-  (and (not (identical? \# ^char ch))
-       (not (identical? \' ^char ch))
+  (and (not= \# ch)
+       (not= \' ch)
        ;;(not= ch \:) ;; why?
        (macros ch)))

 (defn ^String read-token
   [rdr initch]
-  (if-not initch
+  (if (not initch)
     (reader-error rdr "EOF while reading")
+
     (loop [sb (doto (StringBuilder.) (.append initch))
            ch (peek-char rdr)]
       (if (or (nil? ch)
@@ -291,23 +292,23 @@

 (defn ^PersistentVector read-delimited-list
   [delim rdr recursive?]
-  (let [first-line (if (instance? IndexingPushbackReader (class rdr))
+  (let [first-line (if (satisfies? IndexingReader rdr)
                      (get-line-number rdr))]
-    (loop [a (transient [])]
-      (let [ch (read-past whitespace? rdr)]
-        (when-not ch
-          (reader-error rdr "EOF while reading"
-                        (if first-line
-                          (str ", starting at line" first-line))))
-        (if (identical? ^char delim ^char  ch)
-          (persistent! a)
-          (if-let [macrofn (macros ch)]
-            (let [mret (macrofn rdr ch)]
-              (recur (if-not (= mret rdr) (conj! a mret) a)))
-            (do
-              (unread rdr ch)
-              (let [o (read rdr true nil recursive?)]
-                (recur (if-not (= o rdr) (conj! a o) a))))))))))
+   (loop [a (transient [])]
+     (let [ch (read-past whitespace? rdr)]
+       (when-not ch
+         (reader-error rdr "EOF while reading"
+                       (if first-line
+                         (str ", starting at line" first-line))))
+       (if (= delim ch)
+         (persistent! a)
+         (if-let [macrofn (macros ch)]
+           (let [mret (macrofn rdr ch)]
+             (recur (if-not (= mret rdr) (conj! a mret) a)))
+           (do
+             (unread rdr ch)
+             (let [o (read rdr true nil recursive?)]
+               (recur (if-not (= o rdr) (conj! a o) a))))))))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; data structure readers
@@ -331,7 +332,7 @@

 (defn read-list
   [rdr _]
-  (let [[line column] (if (instance? IndexingPushbackReader (class rdr))
+  (let [[line column] (if (satisfies? IndexingReader rdr)
                         [(get-line-number rdr) (dec (get-column-number rdr))])
         the-list (read-delimited-list \) rdr true)]
     (if (empty? the-list)
@@ -476,7 +477,7 @@

 (defn read-meta
   [rdr _]
-  (let [[line column] (if (instance? IndexingPushbackReader (class rdr))
+  (let [[line column] (if (satisfies? IndexingReader rdr)
                         [(get-line-number rdr) (dec (get-column-number rdr))])
         m (desugar-meta (read rdr true nil true))]
     (when-not (map? m)
@@ -646,7 +647,7 @@
         (recur (next s) (-> key-vals
                             (conj! (key e))
                             (conj! (val e)))))
-      (seq (persistent! key-vals)))))
+      (persistent! key-vals))))

 (defn- register-gensym [sym]
   (if-not gensym-env
@@ -801,7 +802,7 @@
         (throw e)
         (throw (ex-info (.getCause e)
                         (merge {:type :reader-exception}
-                               (if (instance? IndexingPushbackReader (class reader))
+                               (if (satisfies? IndexingReader reader)
                                  {:line (get-line-number reader)
                                   :column (get-column-number reader)}))
                         e))))))


Add names to anonymous functions

Add names to anonymous functions

... for easier debugging

--- src/micro_logic/core.clj
+++ src/micro_logic/core.clj
@@ -127,29 +127,29 @@
 (def empty-state (state {} 0))

 (defn === [u v]
-  (fn [{:keys [s c]}]
+  (fn unify-goal [{:keys [s c]}]
     (if-let [s' (unify u v s)]
       (unit (state s' c))
       mzero)))

 (defn call-fresh [f]
-  (fn [{:keys [s c]}]
+  (fn fresh-goal [{:keys [s c]}]
     ((f (lvar c)) (state s (inc c)))))

 (defn ldisj [g1 g2]
-  (fn [state]
+  (fn disj-goal [state]
     (mplus (g1 state) (g2 state))))

 (defn lconj [g1 g2]
-  (fn [state]
+  (fn conj-goal [state]
     (bind (g1 state) g2)))

 ;;; aux macros

 (defmacro delay-goal [g]
-  `(fn [state#]
-     #(~g state#)))
+  `(fn delayed-goal-outer [state#]
+     (fn delayed-goal-inner [] (~g state#))))

 (defmacro lconj+
   ([g] `(delay-goal ~g))


Index-to-tree-objects working correctly

Index-to-tree-objects working correctly

--- src/clj_git/core.clj
+++ src/clj_git/core.clj
@@ -319,30 +319,41 @@
                                  (last (clojure.string/split
                                         (:fname x) #"\/"))))
                         ordered)
-        tree-objs (map (fn [x]
-                         (if (= (:type x) :file)
-                           (-> x
-                               (assoc :type "blob")
-                               (assoc :flags "100644"))
-                           (-> x
-                               (assoc :type "tree")
-                               (assoc :flags "40000"))))
-                       with-names)
-        f-children (fn [objs x]
-                     (filter #(= (:parent %) (:fname x)) objs))
+        blob-objs (->> with-names
+                       (filter #(= (:type %) :file))
+                       (map #(-> %
+                                 (assoc :type "blob")
+                                 (assoc :flags "100644"))))
+        dir-objs (->> with-names
+                       (filter #(= (:type %) :dir))
+                       (map #(-> %
+                                 (assoc :type "tree")
+                                 (assoc :flags "40000"))))
+        f-children (fn [ds x]
+                     (map #(select-keys % [:name
+                                           :type
+                                           :hash
+                                           :flags])
+                          (filter #(= (:parent %) (:fname x))
+                                  (concat blob-objs ds))))
         with-hashes (reduce (fn [objs x]
                           (conj objs
-                           (if (= (:type x) "tree")
                              (assoc x :hash
                                     (hash-tree (f-children objs x)))
-                             x))) [] tree-objs)
-        top-hash (hash-tree (f-children with-hashes nil))]
-    (list top-hash with-hashes)))
+                             )) [] dir-objs)
+        tree-objs (map (fn [x]
+                         {:object-type :tree
+                          :contents (f-children with-hashes x)})
+                       with-hashes)
+        top-children (f-children with-hashes nil)
+        top-tree-obj {:object-type :tree
+                      :contents top-children}]
+    (list (hash-tree top-children) (conj tree-objs top-tree-obj))))

 (defn index-to-tree-objects []
   (let [index-files (read-index)
         files-map (files-tree index-files)
-        objs (files-map-to-objs files-map)]
-    objs))
-
-
+        [top-hash objs] (files-map-to-objs files-map)]
+    [top-hash objs]))
+
+


Tweaked order and docs of age-related items in args.clj.

--- src/clojush/args.clj
+++ src/clojush/args.clj
@@ -224,10 +224,6 @@
           ;; The number of extra instances of autoconstructive_boolean_rand to include in
           ;; :atom-generators for autoconstruction. If negative then autoconstructive_boolean_rand
           ;; will not be in :atom-generators at all.
-
-          :age-combining-function :average
-          ;; For genetic operators that involve multiple parents, the function used to combine
-          ;; the incremented ages of the parents to produce the age of the child.

           ;;----------------------------------------
           ;; Epignenetics
@@ -317,7 +313,12 @@
           ;; lower will be considered.
           ;;
           ;; NOTE: It doesn't make any sense to use this unless you have multiple ages in the
-          ;; population, as you migh have, for example, from using the genesis operator.
+          ;; population, as you migh have, for example, from using the genesis operator or
+          ;; autoconstruction.
+
+          :age-combining-function :average
+          ;; For genetic operators that involve multiple parents, the function used to combine
+          ;; the incremented ages of the parents to produce the age of the child.

           ;;----------------------------------------
           ;; Arguments related to the Push interpreter
@@ -565,3 +566,4 @@

+


Fix wrong binding form

Fix wrong binding form

--- src-cljs/frontend/utils.cljs
+++ src-cljs/frontend/utils.cljs
@@ -329,6 +329,6 @@
       (goog.style/setSize item max-width max-height))))

 (defn outer-svg
-  [short-src & alt args]
+  [short-src alt args]
   (html [:img (merge {:src (cdn-path (gstring/format "/img/outer/%s.svg" short-src))
                       :alt alt} args)]))


More work and formating changes

More work and formating changes

--- clojure-programming/src/clojure_programming/chapter01.clj
+++ clojure-programming/src/clojure_programming/chapter01.clj
@@ -2,7 +2,8 @@
   (:require [midje.sweet :refer :all]))

-[[:section {:title "The Clojure REPL" :tag "page 3"}]]
+[[:section {:title "The Clojure REPL  -- page: 3"}]]
+

 "
 'defn' defines a new function named 'average' in the namespace.
@@ -15,11 +16,11 @@
 (fact (average [60 80 100 400]) => 160)

-[[:section {:title "The Reader" :tag "page 12" }]]
-
-
-"
-The reader (read-string) returns a language AST of the string read
+[[:section {:title "The Reader -- page: 12"}]]
+
+
+"
+ reader (read-string) returns a language AST of the string read
 "
 (facts "the reader 'read-str' converts strings into Clojure data structures"
   (fact (read-string "42") => 42)
@@ -31,10 +32,11 @@
 "
 (facts "'pr-str' is the complement of 'read-str'"
   (fact (pr-str [1 2 3]) => "[1 2 3]")
-  (fact (read-string "[1 2 3]") => [1 2 3]))
-
-
-[[:subsection {:title "scalars" :tag "page 13" }]]
+  (fact (read-string "[1 2 3]") => [1 2 3])
+  (fact (pr-str (read-string "[1 2 3]")) => "[1 2 3]"))
+
+
+[[:subsection {:title "scalars --  page: 13"}]]

 (fact "Strings are Java strings delimited by \"\""
   "hello there" => "hello there"
@@ -46,12 +48,12 @@
 (fact "'nil' is nil or Java Null"
   (type nil) => nil)

-(fact "Characters literals ar dented by a backslash"
+(fact "Characters literals are indicated by a backslash"
   (class \c) => java.lang.Character)

 (facts "Unicode and octal representations use prefixes"
   (fact "\\u00ff"
-    \u00ff => \ÿ)
+    \u00ff => \ÿ)
   (fact "\\o41"
     \o41 => \!))

@@ -82,14 +84,23 @@
 (fact pizza
   => {:name "Ramunto's", :clojure-programming.chapter01/location "42.3734, -72.3365", :location "Claremont, NH"})

-(fact (:clojure-programming.chapter01/location pizza)
+(fact "namespace denoted by '/'"
+  (:clojure-programming.chapter01/location pizza)
   => "42.3734, -72.3365")

+(facts "namespaces and keywords"
+  (fact  (name :clojure-programming.chapter01/location)
+    => "location")
+  (fact (namespace :clojure-programming.chapter01/location)
+    => "clojure-programming.chapter01")
+  (fact (namespace :locations)
+    => nil))
+
 "

 symbols:

-'Symbols' are identifiers that evaluate to values that they name in the current name space.
+'Symbols' are identifiers that evaluate to values that they name in the current name space.

 'average' was a symbol defined earlier:
 "
@@ -98,13 +109,16 @@

 "
-
+page 17
 regualar expressions:
 Clojure treats strings prefixed with '#' as regualar expect literals.

 "
 (fact "class of regualar expression literal: "
   (class #"(p|h)ail") => java.util.regex.Pattern )
+
+(fact (re-seq #"(...) (...)" "foo bar")
+  => '(["foo bar" "foo" "bar"]))

 (fact "Clojure regexs do not need escaping backslashes "
   (re-seq #"(\d+)-(\d+)" "1-3")  => '(["1-3" "1" "3"]))
@@ -118,7 +132,7 @@
 Single line begin with a ';' character
 all text after the ';' are ignored until the end of the line

-Form level using the '#_' reader macro, This causes the reader to
+Form level using the '#_' reader macro, This causes the reader to
 ignore the 'sexp' following the macro:
 "
 (fact
@@ -126,23 +140,27 @@

-[[:subsection {:title "Whitespaces and Commas" :tag "page 19" }]]
-"
+[[:subsection {:title "Whitespaces and Commas" }]]
+"
+page: 18
 Commas are whitespace in Clojure.

 So:"
 (fact "these are equivalent"
-  (defn silly-adder [x,y]
+  (defn silly-adder
+    [x,y]
     (+, x, y))
   =>
-  (defn silly-adder [x y]
+  (defn silly-adder
+    [x y]
     (+ x y)))

 "And: "
-(fact (= [1 2 3] [1, 2, 3]) => true)
-
-
-[[:subsection {:title "Collection Literals" :tag "page 19.5" }]]
+(fact (= [1 2 3] [1, 2, 3])
+  => true)
+
+
+[[:subsection {:title "Collection Literals -- page: 19" }]]

 (facts
   (fact "the list '(...):"
@@ -156,10 +174,10 @@

-[[:subsection {:title "Miscellaneous Reader Sugar" :tag "page 20.a" }]]
-
-"
-Evaluation can be suppressed with the (') quote macro, this is equivalent
+[[:subsection {:title "Miscellaneous Reader Sugar-- page: 20" }]]
+
+"
+Evaluation can be suppressed with the (') quote macro, this is equivalent
 to the (quote from)
 "
 (fact (quote (a b c)) => '(a b c))
@@ -174,48 +192,63 @@
 "
 (def var1 10)
 (fact #'var1 => #'clojure-programming.chapter01/var1)
-"
-derenfernce a var (@)
-"
-;;(fact @var1 => 10)
-
-
-[[:section {:title "Namespaces" :tag "page 20.b" }]]
+
+;(fact "derenfernce a var (@)"
+;  @var1 => 10)
+
+
+[[:section {:title "Namespaces-- page: 20" }]]

 "
 Namespaces are Clojures unit of code modularity.

-A 'namespace' is fundamentally a dynamic mapping between symbols and
+A 'namespace' is fundamentally a dynamic mapping between symbols and
 either vars and Java classes.

 Vars (a reference type) are mutable storage that can hold any value.

 They are defined using the 'def' special form.
+"
+(fact (def x 1)
+  => #'clojure-programming.chapter01/x)
+
+(fact "We can access th var's value using that symbol"
+  x => 1)
+
+(facts "We can redifine vars"
+  (def x "hello")  => #'clojure-programming.chapter01/x
+  x => "hello")
+
+"Symbols may be namespace qualified"
+
+;"*ns*  ;=> #<Namespace clojure-programming.chapter01>"
+
+
+;"(fact (ns foo) => nil)"
+
+;"*ns* ;=> #<Namespace foo>"
+
+;(fact clojure-programming.chapter01/x
+; => "hello")
+
+;(ns clojure-programming.chapter01)
+
+"

 Never define 'vars' in a funtion body, only at the top level.
 "

-(def x 1)
-(fact x => 1)
-
-(def  x "hello")
-(fact x => "hello")
-
-"symbols may be qualified by a namespace.
-*ns* is bound to the current namespace
-
-the 'java.lang' namepace is imported by default into each Clojure namepace:
-"
-(facts
+(facts "Any symbol that names a class evaluates to that class"
   (fact String => java.lang.String)
   (fact Integer => java.lang.Integer)
   (fact java.util.List => java.util.List)
   (fact java.net.Socket => java.net.Socket))

-"namespaces also alias the vars included in Clojures standard library 'clojure.core' so it may be used without qualifications"
-
-
-[[:section {:title "Symbol Evaluation" :tag "page 23" }]]
+"namespaces also alias the vars included in Clojures standard library 'clojure.core' so it may be used without qualifications
+"
+
+
+[[:section {:title "Symbol Evaluation  -- page: 23"}]]

 "
 vars evaluate to there contents,
@@ -223,19 +256,19 @@
 "

-[[:section {:title "Special Forms" :tag "page 24.a" }]]
+[[:section {:title "Special Forms -- page: 24"}]]

 "
 Symbols in function call position can only eval to two different things:
 * The value of a named var or a local -or-
 * A Clojure special form.

-Clojure special forms form the basis of Clojure computation, all other
-things are build on top of special forms.
+Clojure special forms form the basis of Clojure computation, all other
+things are build on top of special forms.
 Special forms have there own evaluation syntax
 "

-[[:subsection {:title "Suppressing Evaluation: quote" :tag "page 24.b" }]]
+[[:subsection {:title "Suppressing Evaluation: quote  -- page: 24"}]]

 (fact (quote x) => 'x)
 (fact (symbol? (quote x)) => truthy)
@@ -247,15 +280,23 @@
   '(+ x x) => '(+ x x)
   (list? '(+ x x)) => true)

-(fact ''x => '(quote x))
-
-
-[[:subsection {:title "Code Blocks: do" :tag "page 25" }]]
+(fact (list '+ 'x 'x) => '(+ x x))
+
+(fact "peek at what the reader produces by quoting a form."
+  ''x => '(quote x))
+
+;TODO: fix this
+;(facts "use this for other reader sugars"
+;  (fact '@x => (clojure.core/deref x)))
+
+
+[[:subsection {:title "Code Blocks: do  -- page: 25"}]]

 (fact "do evaluates all of it's expessions in order and yields the last"
   (do (println "hi")
       (+ 3 4)
       (apply * [4 5 6]))
+  ; hi
   => 120)

 "The steps before the last are usually executed for there side effects.
@@ -266,7 +307,7 @@
       b (int (rand-int 6))]
   (println (format "You rolled a %s and a %s" a b))
   (+ a b))
-"
+"
 contains an implicit 'do'
 such as:"

@@ -277,9 +318,9 @@
     (+ a b)))

-[[:subsection {:title "Defining Vars: def" :tag "page 26" }]]
-"
-def defines or redifines a var with an optional value in the
+[[:subsection {:title "Defining Vars: def  --  page 26"}]]
+"
+def defines or redifines a var with an optional value in the
 current namespace
 "
 (facts "def'ing vars"
@@ -293,7 +334,7 @@
 "

-[[:subsection {:title "Local Bindings: let" :tag "page 27" }]]
+[[:subsection {:title "Local Bindings: let --  page 27"}]]
 "
 let binds locally scoped references, let defines locals
 "
@@ -303,7 +344,8 @@
         y2 (* y y)]
     (Math/sqrt (+ x2 y2))))

-(fact (hypot 3 4) => 5.0)
+(fact (hypot 3.0 4.0)
+  => 5.0)
 "
 let is implicitly used int 'fn' and 'defn' to bind parmeters in the
 local scope.
@@ -316,7 +358,7 @@
 Let bindings provide destructuring at.
 "

-[[:subsection {:title "Destructuring - let" :tag "page 28" }]]
+[[:subsection {:title "Destructuring - let --  page 28"}]]
 "
 Most Clojure funtions are based around sequential and map data structures.
 This allows functions and data structures to be trivially composed.
@@ -341,8 +383,11 @@
 Accessing deeper structures are more complicated
 "
 (facts "this is complicated"
-  (fact (+ (first v) (v 2)) => 141.2)
-  (fact (+ (first v) (first (last v))) => 47))
+  (fact (+ (first v) (v 2))
+    => 141.2)
+  (fact "if we need to acces values in nested collections:"
+    (+ (first v) (first (last v)))
+    => 47))
 "
 Clojure destructuring provides a more concise syntax
 Destructuring syntax of 'let' also works for (fn defn loop ...).
@@ -350,10 +395,12 @@
 Destructuring comes in two forms Sequntial and Map.
 "
 "Sequential destructuring works with many types of collections:
-  list vector seq, java.util.List (ArrayList LinkedList),
+  list vector seq, java.util.List (ArrayList LinkedList),
   java arrays, Strings.
 "
-(fact "basic example"
+(def v [42 "foo" 99.2 [5 12]])
+
+(fact "basic sequential destructuring example"
   (let [[x y z] v]
     (+ x z))
   => 141.2)
@@ -374,7 +421,7 @@

 "
 Extra-positional sequential values
-& gathers up the rest of values that lay beyond the values in
+& gathers up the rest of values that lay beyond the values in
 the destructuring form.
 "
 (fact "extra-positional"
@@ -390,7 +437,7 @@
   => '[42 "foo" 99.2 [5 12] 141.2])

 "
-Map destructuring
+Map destructuring  -- page: 32
 similar to sequential destructuring.
 It works with hash-maps array-maps records, anything that implements
 java.util.Map, anything that is supported by 'get' vectors Strings Arrays
@@ -405,7 +452,6 @@
 (fact (let [{a :a b :b} m]
         (+ a b))
   => 11)
-

 (facts "Keynames don't have to match"
   (fact
@@ -702,7 +748,7 @@
   (fact (if (not true) \t)
     =>  nil))

-"If a condition is false and no else expression is provided
+"If a condition is false and no else expression is provided
  the result will be 'nil'.

 Other refinements of the if conditional:
@@ -793,7 +839,7 @@
     => []))

 "Static method invocation"
-(facts "Java: Math.pow(2, 10)"
+(facts "Java: Math.pow(2, 10)"
   (fact "sugared interop form"
     (Math/pow 2 10)
     => 1024.0)


Added `assert-info`

Added `assert-info`


Some mild cleanup

Some mild cleanup

--- src/foreclojure/utils.clj
+++ src/foreclojure/utils.clj
@@ -134,16 +134,17 @@
       [:script {:type "text/javascript"} "SyntaxHighlighter.all()"]
       [:body
        [:div#top
-        [:a {:href "/"} [:img#logo {:src "/images/logo.png"}]]]
+        (link-to "/" [:img#logo {:src "/images/logo.png"}])]
        [:div#content
         [:br]
         [:div#menu
-         [:a.menu {:href "/"} "Main Page"]
-         [:a.menu {:href "/problems"} "Problem List"]
-         [:a.menu {:href "/users"} "Top Users"]
-         [:a.menu {:href "/directions"} "Getting Started"]
-         [:a.menu {:href "http://try-clojure.org"} "REPL"]
-         [:a.menu {:href "http://clojuredocs.org"} "Docs"]
+         (for [[link text] [["/" "Main Page"]
+                            ["/problems" "Problem List"]
+                            ["/users" "Top Users"]
+                            ["/directions" "Getting Started"]
+                            ["http://try-clojure.org" "REPL"]
+                            ["http://clojuredocs.org" "Docs"]]]
+           [:a.menu {:href link} text])
          [:span#user-info
           (if user
             [:div