Ensure task lifecycle operations are complete before closing messaging links.

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -350,12 +350,17 @@
             (Thread/sleep 500)
             (recur @replica)))

-        (release-messages! messenger pipeline-data)
-        (thread (forward-completion-calls! pipeline-data completion-ch))
-        (listen-for-sealer job-id task-id pipeline-data seal-resp-ch outbox-ch)
-        (thread (run-task-lifecycle pipeline-data seal-resp-ch kill-ch ex-f))
-
-        (assoc component :pipeline-data pipeline-data :seal-ch seal-resp-ch))
+        (let [release-messages-ch (release-messages! messenger pipeline-data)
+              forward-completion-ch (thread (forward-completion-calls! pipeline-data completion-ch))
+              task-lifecycle-ch (thread (run-task-lifecycle pipeline-data seal-resp-ch kill-ch ex-f))
+              listen-for-sealer-ch (listen-for-sealer job-id task-id pipeline-data seal-resp-ch outbox-ch)]
+          (assoc component
+                 :pipeline-data pipeline-data
+                 :seal-ch seal-resp-ch
+                 :release-messages-ch release-messages-ch
+                 :forward-completion-ch forward-completion-ch
+                 :task-lifecycle-ch task-lifecycle-ch
+                 :listen-for-sealer-ch listen-for-sealer-ch)))
       (catch Exception e
         (handle-exception e restart-ch outbox-ch job-id)
         component)))
@@ -366,6 +371,12 @@
       (l-ext/close-lifecycle-resources* event)

       (close! (:seal-ch component))
+
+      ;; Ensure task operations are finished before closing peer connections
+      (<!! (:task-lifecycle-ch component))
+      (<!! (:listen-for-sealer-ch component))
+      (<!! (:forward-completion-ch component))
+      (<!! (:release-messages-ch component))

       (let [state @(:onyx.core/state event)]
         (doseq [[_ link] (get-in state [:links :send-peer-site])]
@@ -374,7 +385,14 @@
           (extensions/close-peer-connection (:onyx.core/messenger event) event link))
         (doseq [[_ link] (get-in state [:links :completion-peer-site])]
           (extensions/close-peer-connection (:onyx.core/messenger event) event link))))
-    component))
+
+    (assoc component
+           :pipeline-data nil
+           :seal-ch nil
+           :release-messages-ch nil
+           :forward-completion-ch nil
+           :task-lifecycle-ch nil
+           :listen-for-sealer-ch nil)))

 (defn task-lifecycle [args {:keys [id log messenger-buffer messenger job task replica
                                    restart-ch kill-ch outbox-ch seal-ch completion-ch opts]}]


util/simpledb.clj: added delete-where

util/simpledb.clj: added delete-where

--- src/org/altlaw/util/simpledb.clj
+++ src/org/altlaw/util/simpledb.clj
@@ -75,3 +75,7 @@
      (reduce (fn [m [k v]] (assoc m k (parse-attr-list v)))
              {} (.getItems (.selectItems (get-domain domain-name)
                                          query-string next-token)))))
+
+(defn delete-where [domain-name query-string]
+  (doseq [item (list-items domain-name query-string)]
+    (delete-item domain-name (.getIdentifier item))))


[Fix #136] REPL not starting when clojars is down

--- src/refactor_nrepl/artifacts.clj
+++ src/refactor_nrepl/artifacts.clj
@@ -19,11 +19,15 @@
 (defn get-artifacts-from-clojars!
   "Returns a vector of [[some/lib \"0.1\"]...]."
   []
-  (->> "https://clojars.org/repo/all-jars.clj"
-       java.net.URL.
-       io/reader
-       line-seq
-       (map edn/read-string)))
+  (try
+    (->> "https://clojars.org/repo/all-jars.clj"
+         java.net.URL.
+         io/reader
+         line-seq
+         (map edn/read-string))
+    (catch Exception _
+      ;; In the event clojars is down just return an empty vector. See #136.
+      [])))

 (defn add-artifacts-from-clojars! []
   (->> (get-artifacts-from-clojars!)


fix a bug that file in the sub package of the target project could not be deleted

--- src/leiningen/leinsync/packages.clj
+++ src/leiningen/leinsync/packages.clj
@@ -61,11 +61,13 @@

 (defn delete-package-files-of-target-project [target-project folder-name package-path]
   (try
-    (doseq [file-to-delete (-> (pr/->target-project-path target-project)
-                               (str "/" folder-name "/" package-path)
-                               ^File (io/file)
-                               .listFiles)]
-      (io/delete-file file-to-delete true))
+    (doseq [^File file-to-delete (-> (pr/->target-project-path target-project)
+                                     (str "/" folder-name "/" package-path)
+                                     ^File (io/file)
+                                     .listFiles)]
+      (if (.isDirectory file-to-delete)
+        (FileUtils/deleteDirectory file-to-delete)
+        (io/delete-file file-to-delete true)))
     (catch Exception e
       (m/info "**** [Error] when deleting a file of the folder:" folder-name (.getMessage e))
       (if @u/DEBUG-MODE (m/info e)))))


optimize analyze-dot

optimize analyze-dot

--- src/main/clojure/cljs/analyzer.cljc
+++ src/main/clojure/cljs/analyzer.cljc
@@ -2002,25 +2002,36 @@
                  (list* '. dot-form) " with classification "
                  (classify-dot-form dot-form))))))

+(defn analyze-dot [env target field member+ form]
+  (let [v [target field member+]
+        {:keys [dot-action target method field args]} (build-dot-form v)
+        enve       (assoc env :context :expr)
+        targetexpr (analyze enve target)
+        form-meta  (meta form)
+        tag        (:tag form-meta)]
+    (case dot-action
+      ::access (let [children [targetexpr]]
+                 {:op :dot
+                  :env env
+                  :form form
+                  :target targetexpr
+                  :field field
+                  :children children
+                  :tag tag})
+      ::call   (let [argexprs (map #(analyze enve %) args)
+                     children (into [targetexpr] argexprs)]
+                 {:op :dot
+                  :env env
+                  :form form
+                  :target targetexpr
+                  :method method
+                  :args argexprs
+                  :children children
+                  :tag tag}))))
+
 (defmethod parse '.
   [_ env [_ target & [field & member+] :as form] _ _]
-  (disallowing-recur
-   (let [{:keys [dot-action target method field args]} (build-dot-form [target field member+])
-         enve        (assoc env :context :expr)
-         targetexpr  (analyze enve target)]
-     (case dot-action
-           ::access {:env env :op :dot :form form
-                     :target targetexpr
-                     :field field
-                     :children [targetexpr]
-                     :tag (-> form meta :tag)}
-           ::call   (let [argexprs (map #(analyze enve %) args)]
-                      {:env env :op :dot :form form
-                       :target targetexpr
-                       :method method
-                       :args argexprs
-                       :children (into [targetexpr] argexprs)
-                       :tag (-> form meta :tag)})))))
+  (disallowing-recur (analyze-dot env target field member+ form)))

 (defmethod parse 'js*
   [op env [_ jsform & args :as form] _ _]


optimize analyze-fn-method

optimize analyze-fn-method

--- src/main/clojure/cljs/analyzer.cljc
+++ src/main/clojure/cljs/analyzer.cljc
@@ -1158,35 +1158,60 @@
         (when export-as {:export export-as})
         (when init-expr {:children [init-expr]})))))

+(defn analyze-fn-method-param [env]
+  (fn [[locals params] name]
+    (let [line   (get-line name env)
+          column (get-col name env)
+          nmeta  (meta name)
+          tag    (:tag nmeta)
+          shadow (when-not (nil? locals)
+                   (locals name))
+          env    (merge (select-keys env [:context])
+                   {:line line :column column})
+          param  {:op :var
+                  :name name
+                  :line line
+                  :column column
+                  :tag tag
+                  :shadow shadow
+                  ;; Give the fn params the same shape
+                  ;; as a :var, so it gets routed
+                  ;; correctly in the compiler
+                  :env env
+                  :info {:name name :shadow shadow}
+                  :binding-form? true}]
+     [(assoc locals name param) (conj params param)])))
+
+(defn analyze-fn-method-body [env form recur-frames]
+  (binding [*recur-frames* recur-frames]
+    (analyze env form)))
+
 (defn- analyze-fn-method [env locals form type]
-  (let [param-names (first form)
-        variadic (boolean (some '#{&} param-names))
-        param-names (vec (remove '#{&} param-names))
-        body (next form)
-        [locals params] (reduce (fn [[locals params] name]
-                                  (let [param {:name name
-                                               :line (get-line name env)
-                                               :column (get-col name env)
-                                               :tag (-> name meta :tag)
-                                               :shadow (when locals (locals name))
-                                               ;; Give the fn params the same shape
-                                               ;; as a :var, so it gets routed
-                                               ;; correctly in the compiler
-                                               :op :var
-                                               :env (merge (select-keys env [:context])
-                                                           {:line (get-line name env)
-                                                            :column (get-col name env)})
-                                               :info {:name name
-                                                      :shadow (when locals (locals name))}
-                                               :binding-form? true}]
-                                    [(assoc locals name param) (conj params param)]))
-                                [locals []] param-names)
-        fixed-arity (count (if variadic (butlast params) params))
-        recur-frame {:params params :flag (atom nil)}
-        expr (binding [*recur-frames* (cons recur-frame *recur-frames*)]
-               (analyze (assoc env :context :return :locals locals) `(do ~@body)))]
-    {:env env :variadic variadic :params params :max-fixed-arity fixed-arity
-     :type type :form form :recurs @(:flag recur-frame) :expr expr}))
+  (let [param-names     (first form)
+        variadic        (boolean (some '#{&} param-names))
+        param-names     (vec (remove '#{&} param-names))
+        body            (next form)
+        step            (analyze-fn-method-param env)
+        step-init       [locals []]
+        [locals params] (reduce step step-init param-names)
+        params'         (if (true? variadic)
+                          (butlast params)
+                          params)
+        fixed-arity     (count params')
+        recur-frame     {:params params :flag (atom nil)}
+        recur-frames    (cons recur-frame *recur-frames*)
+        body-env        (assoc env :context :return :locals locals)
+        body-form       `(do ~@body)
+        expr            (analyze-fn-method-body body-env body-form recur-frames)
+        recurs          @(:flag recur-frame)]
+    {:env env
+     :variadic variadic
+     :params params
+     :max-fixed-arity fixed-arity
+     :type type
+     :form form
+     :expr expr
+     :recurs recurs}))

 (declare analyze-wrap-meta)


added add/remove of participants for selection

--- src/tango/cljs/runtime/core.cljs
+++ src/tango/cljs/runtime/core.cljs
@@ -407,17 +407,30 @@
         (dom/h2 {:className "sub-header"} (str "Select Participants for Class "
                                                (:class/name selected-class)))
         (dom/div nil
-          (dom/button nil "Back")
-          (dom/button nil "Done"))
-        (map #(dom/button #js {:className (str "col-sm-6 btn" (if (selected? %)
+          (dom/button #js {:className (str "btn btn-default")
+                           :onClick   #()}
+                      (dom/span #js {:className "glyphicon glyphicon-arrow-left"}))
+
+          (dom/button #js {:className (str "btn btn-default")
+                           :onClick   #(om/transact! this `[(app/select-page {:selected-page :create-class})
+                                                            :app/selected-page])}
+                      (dom/span #js {:className "glyphicon glyphicon-ok"})))
+
+        (map #(dom/button #js {:className (str "col-sm-3 btn" (if (selected? %)
                                                                 " btn-primary"
                                                                 " btn-default"))
-                               :onClick (fn [e]
-                                          (om/transact!
-                                            reconciler
-                                            `[(class/update
-                                                {:class/starting ~(conj starting %)})
-                                              :app/selected-class]))}
+                               :onClick   (fn [e]
+                                            (let [updated-starting
+                                                  (if (selected? %)
+                                                    (filter (fn [p]
+                                                              (not= (:participant/id p) (:participant/id %)))
+                                                            starting)
+                                                    (conj starting %))]
+                                              (om/transact!
+                                                reconciler
+                                                `[(class/update
+                                                    {:class/starting ~updated-starting})
+                                                  :app/selected-class])))}
                           (str (:participant/number %) " - " (:participant/name %)))
              participants)))))


use var for elb sg

use var for elb sg

--- shared/test.clj
+++ shared/test.clj
@@ -5,12 +5,14 @@
   [(sg-rule "tcp" 80 8090 ["198.0.2.0/24" "198.51.100.0/24"])
    (sg-rule "udp" 80 8090 ["198.0.2.0/24" "198.51.100.0/32"])])

+(def elb-sg (str app-name "-lb"))
+
 {:sg [{:GroupName app-name
        :GroupDescription (str "Security group for application " app-name)
        :VpcId vpc-id
        :Ingress sg-ingress
        :Egress sg-egress}
-      {:GroupName (str app-name "-lb")
+      {:GroupName elb-sg
        :GroupDescription (str "Security group for load balancer " app-name)
        :VpcId vpc-id
        :Ingress override-sg-ingress
@@ -19,7 +21,7 @@
  :elb {:LoadBalancerName app-name
        :Listeners [(elb-listener 8080 8080 "http")
                    (elb-listener 80 8080 "http")]
-       :SecurityGroups [(str app-name "-sg")]
+       :SecurityGroups [elb-sg]
        :Subnets elb-subnets
        :Scheme "internal"
        :HealthCheck (elb-healthcheck "HTTP:8080/1.x/ping" 2 2 6 5)}


Include event in close-log call for consistency

--- src/onyx/state/state_extensions.clj
+++ src/onyx/state/state_extensions.clj
@@ -5,7 +5,7 @@
     log-type))

 (defmulti close-log
-  (fn [log]
+  (fn [log event]
     (type log)))

 ;; For onyx to implement


All in place but the accidentals and the final flourish.

--- src/overtunes/songs/variatio-12.clj
+++ src/overtunes/songs/variatio-12.clj
@@ -21,9 +21,9 @@
     (range a (inc b))
     (reverse (run b a))))

-(def durations (flatten [(repeat 2 1/4) 1/2 (repeat 6 1/4) (repeat 8 1/4) 3/2 (repeat 10 1/4) 1/2 (repeat 2 1/4) 9/4 3/4 (repeat 8 1/4)]))
-(def pitches (flatten [0 (run -1 3) (run 2 0) 4 (run 1 8) (run 7 -1) 0 (run 0 -3) 4 4 (run 2 -3) -1]))
-(def bass (map #(- % 7) (flatten (map #(repeat 3 %) (concat (run 0 -3) (run -5 -3) [0])))))
+(def durations (flatten [(repeat 2 1/4) 1/2 (repeat 6 1/4) (repeat 8 1/4) 3/2 (repeat 10 1/4) 1/2 (repeat 2 1/4) 9/4 3/4 (repeat 12 1/4) 1/2 1 1/2 (repeat 12 1/4) 1]))
+(def pitches (flatten [0 (run -1 3) (run 2 0) 4 (run 1 8) (run 7 -1) 0 (run 0 -3) 4 4 (run 2 -3) -1 1 (run 4 6) 1 1 1 2 -1 -2 0 1 -1 -2 (run 5 0)]))
+(def bass (map #(- % 7) (flatten [(map #(repeat 3 %) (concat (run 0 -3) (run -5 -3) [-7])) 0])))

 (defn melody# [timing notes]
   (let [note# #(at (timing %1) (piano (g-major %2)))]


remove extraneous logging

remove extraneous logging

--- src-cljs/tranjlator/sockets.cljs
+++ src-cljs/tranjlator/sockets.cljs
@@ -37,7 +37,6 @@
       (let [timeout (a/timeout 15000)]
         (alt!
           timeout ([_]
-                     (println "pinging")
                      (.send ws (pr-str {:topic :ping}))
                      (recur))
           sender-ch ([msg]


Amended the flow of POST request

Amended the flow of POST request

--- src/rdf_path_examples/resources.clj
+++ src/rdf_path_examples/resources.clj
@@ -3,29 +3,39 @@
             [rdf-path-examples.jsonld :as jsonld]
             [rdf-path-examples.integrity-constraints :refer [validate-path]]
             [rdf-path-examples.examples :refer [generate-examples]]
+            [rdf-path-examples.views :as views]
             [schema.coerce :as coerce]
             [clojure.tools.logging :as log]
-            [liberator.core :refer [defresource]]))
+            [clojure.walk :refer [keywordize-keys]]
+            [liberator.core :refer [defresource]]
+            [liberator.representation :refer [render-map-generic]]))
+
+(def ^:private default-response
+  {:representation {:media-type "application/ld+json"}})

 (def parse-query-params
   (coerce/coercer Config coerce/string-coercion-matcher))

+(defmethod render-map-generic "application/ld+json"
+  ; Alias the JSON rendering function for JSON-LD
+  [data context]
+  ((get-method render-map-generic "application/json") data context))
+
 (defresource rdf-path-examples
   :allowed-methods [:post]
   :available-media-types ["application/ld+json"]
+  :handle-malformed views/error
   :handle-ok (fn [{{configuration :params} :request
                    :keys [rdf-path]}]
-               {:message (generate-examples configuration rdf-path)
-                :representation {:media-type "application/ld+json"}})
+               (generate-examples configuration rdf-path))
   :known-content-type? (fn [{{{content-type "content-type"} :headers} :request}]
                          (= content-type "application/ld+json"))
   :malformed? (fn [{{:keys [body query-params]} :request}]
                 (let [configuration (parse-query-params query-params)
                       path (jsonld/json-ld->rdf-model body)]
                   (if-let [error (or (:error configuration) (validate-path path))]
-                    [true {:message (str error)
-                           :representation {:media-type (if (string? error)
-                                                          "application/ld+json"
-                                                          "text/plain")}}]
-                    [false {:request {:params (merge {:limit 5} configuration)}
-                            :rdf-path path}]))))
+                    [true (assoc default-response :error-msg error)]
+                    [false {:request {:params (merge {:limit 5} (keywordize-keys configuration))}
+                            :rdf-path path}])))
+  :new? (constantly false)
+  :respond-with-entity? (constantly true))


improve readme closing behavior

improve readme closing behavior

--- src/replme/cljs/readme_section.cljs
+++ src/replme/cljs/readme_section.cljs
@@ -1,5 +1,5 @@
 (ns replme.cljs.readme-section
-  (:use [jayq.core :only [$ on find fade-in html fade-out ajax done add-class]])
+  (:use [jayq.core :only [$ on find fade-in html slide-up ajax done remove-class add-class]])
   (:require [goog.crypt.base64 :as b64]
             [markdown.core :refer [md->html]]
             [clojure.string :as str]
@@ -27,7 +27,9 @@
         $repl (find ($ :#repl-container) :.jquery-console-inner)
         repo-name (:repo state)]

-    (on $readme-close :click #(fade-out $readme-container 500))
+    (on $readme-close :click (fn [e]
+                               (slide-up $readme-container 500
+                                         #(remove-class $repl "readme-open"))))

     (when-not (= repo-name "")
       (go


Fix conditionals

Fix conditionals

--- src/clj/jest/compiler/NativeJestCompiler.clj
+++ src/clj/jest/compiler/NativeJestCompiler.clj
@@ -403,9 +403,26 @@
     `(let [~@bindings] ~@expressions)))

+(defn- wrap-in-do
+  [expressions]
+  (cond
+    (= 0 (count expressions)) (throw (new NotImplementedException))
+    (= 1 (count expressions)) (first expressions)
+    :else `(do ~@expressions)))
+
 (defn -visitConditional
   [this ^JestParser$ConditionalContext ctx]
-  (throw (new NotImplementedException)))
+
+  (let [conditions (map #( .. this (visitExpression %)) (merge-items (. ctx ifCondition) (. ctx elifExpression)))
+        results (map #( .. this (visitBlock %)) (merge-items (. ctx iftrue) (. ctx elifBlock)))
+        else (if (. ctx elseBlock) (.. this (visitBlock (. ctx elseBlock))) nil)
+        single-if (= (. conditions size) 1)]
+
+    (cond
+      (and single-if else) `(if ~(. conditions (get 0)) ~(wrap-in-do (. results (get 0))) ~(wrap-in-do else))
+      single-if `(if ~(. conditions (get 0)) ~(wrap-in-do (. results (get 0))))
+      (not else) `(cond ~@(apply concat (zip conditions (map wrap-in-do results))))
+      :else `(cond ~@(apply concat (zip conditions (map wrap-in-do results))) :else ~(wrap-in-do else)))))

 (defn -visitClojureVector


just dissoc

just dissoc

--- src/cljx/jamesmacaulay/async_tools/core.cljx
+++ src/cljx/jamesmacaulay/async_tools/core.cljx
@@ -35,7 +35,7 @@
          (let [state (swap! state-atom assoc :boxed-value (channels/box value))]
            (doseq [handler (:handlers state)]
              ((impl/commit handler) value))
-           (swap! state-atom assoc :handlers nil))))
+           (swap! state-atom dissoc :handlers))))
     state-atom))

 (defrecord AsyncFuture [state-atom]


[#531] Add support for photo and video question types

--- backend/src/akvo/lumen/import/flow.clj
+++ backend/src/akvo/lumen/import/flow.clj
@@ -180,6 +180,14 @@
   (str/join "|" (map (fn [item]
                        (get item "name"))
                      response)))
+
+(defmethod render-response "PHOTO"
+  [_ response]
+  (get response "filename"))
+
+(defmethod render-response "VIDEO"
+  [_ response]
+  (get response "filename"))

 (defmethod render-response :default
   [type response]


add TODO

add TODO

--- test/cljam/t_bam.clj
+++ test/cljam/t_bam.clj
@@ -46,4 +46,5 @@
           (bai/create-index sorted-f (str sorted-f ".bai"))) => anything
         (with-open [r (bam/reader (str temp-dir "/test.incomplete.sorted.bam"))]
           (io/read-alignments r {:chr "ref" :start 0 :end 1000})) => (filter #(= "ref" (:rname %)) (:alignments test-sam-incomplete-alignments-sorted-by-pos))
+        ;; TODO: need more strictly check to .bai files
         ))


formatting

formatting

--- test/cu/web_test.clj
+++ test/cu/web_test.clj
@@ -43,9 +43,10 @@
         (in
           (app (body (request :post "/push")
                      {:payload
-                      (json/write-str {:repository
-                                       {:name "foo"
-                                        :url (create-git-repo git-repo-path "run-pipeline" "foo")}})}))))
+                      (json/write-str
+                        {:repository
+                         {:name "foo"
+                          :url (create-git-repo git-repo-path "run-pipeline" "foo")}})}))))

 ; writes output of requested command to a log file
 (expect-let [evidence-that-command-ran (str (UUID/randomUUID))


feat(frontend): add "build-tests" command

--- frontend/tools.clj
+++ frontend/tools.clj
@@ -46,7 +46,7 @@

 (defmethod task "dist"
   [[_ name]]
-  (api/build (api/inputs "src" "test")
+  (api/build (api/inputs "src")
              (merge default-build-options
                     (get-output-options name true ::path)
                     {:optimizations :advanced
@@ -55,10 +55,22 @@

 (defmethod task "build"
   [[_ name]]
-  (api/build (api/inputs "src" "test")
+  (api/build (api/inputs "src")
              (merge default-build-options
                     (get-output-options name false ::path)
                     {:optimizations :simple})))
+
+(defmethod task "build-tests"
+  [& args]
+  (api/build (api/inputs "src" "test")
+             (assoc default-build-options
+                    :main 'uxbox.tests.main
+                    :verbose true
+                    :target :nodejs
+                    :source-map true
+                    :output-to "target/tests/main.js"
+                    :output-dir "target/tests/main"
+                    :optimizations :none)))

 (defmethod task "figwheel"
   [args]


Move type hints to macros.

Move type hints to macros.

--- src/dsbdp/local_data_processing_pipeline.clj
+++ src/dsbdp/local_data_processing_pipeline.clj
@@ -60,9 +60,10 @@
     expr))

 (defmacro enqueue
-  [queue data enqueued-counter dropped-counter]
+  [obj data enqueued-counter dropped-counter]
   (println "Enqueueing data via:")
-  (let [expr (condp (fn [^String v ^String s] (.contains s v)) queue-setup
+  (let [queue (with-meta obj {:tag 'java.util.concurrent.BlockingQueue})
+        expr (condp (fn [^String v ^String s] (.contains s v)) queue-setup
                "add-counted-yield" `(if (< (.size ~queue) queue-size)
                                       (do
                                         (.add ~queue ~data)
@@ -138,9 +139,10 @@
     expr))

 (defmacro take-from-queue
-  [queue]
-  (println "Retrieving data from queue via:")
-  (let [expr (condp (fn [^String v ^String s] (.endsWith s v)) queue-setup
+  [obj]
+  (println "Retrieving data via:")
+  (let [queue (with-meta obj {:tag 'java.util.concurrent.BlockingQueue})
+        expr (condp (fn [^String v ^String s] (.endsWith s v)) queue-setup
                "remove-yield" `(if (not (.isEmpty ~queue))
                                  (.remove ~queue)
                                  (Thread/yield))
@@ -153,9 +155,9 @@

 (defn create-local-processing-element
-  ([^BlockingQueue in-queue initial-proc-fn]
+  ([in-queue initial-proc-fn]
     (create-local-processing-element in-queue initial-proc-fn nil))
-  ([^BlockingQueue in-queue initial-proc-fn id]
+  ([in-queue initial-proc-fn id]
     (let [running (atom true)
           out-queue (create-queue)
           out-counter (Counter.)
@@ -232,7 +234,7 @@
                                 "PipelineOut"
                                 (fn []
                                   (try
-                                    (let [^LocalTransferContainer c (take-from-queue ^BlockingQueue @out-queue)]
+                                    (let [^LocalTransferContainer c (take-from-queue @out-queue)]
                                       (if (not (nil? c))
                                         (out-fn (.getIn c) (.getOut c))))
                                     (catch InterruptedException e


formatting

formatting

--- example-pipeline/src/lambdaui/example/simple_pipeline.clj
+++ example-pipeline/src/lambdaui/example/simple_pipeline.clj
@@ -1,28 +1,27 @@
 (ns lambdaui.example.simple-pipeline
-    (:use [compojure.core])
-    (:require [lambdacd.steps.shell :as shell]
-      [lambdacd.steps.manualtrigger :refer [wait-for-manual-trigger]]
-      [lambdacd.steps.control-flow :refer [either with-workspace in-parallel run]]
-      [lambdacd.core :as lambdacd]
-      [ring.server.standalone :as ring-server]
-              [lambdacd.ui.api]
-      [lambdacd-git.core :as git]
-      [lambdacd.runners :as runners]
-      [clojure.java.io :as io]
-      [lambdaui.api :as ui]))
+  (:use [compojure.core])
+  (:require [lambdacd.steps.shell :as shell]
+            [lambdacd.steps.manualtrigger :refer [wait-for-manual-trigger]]
+            [lambdacd.steps.control-flow :refer [either with-workspace in-parallel run]]
+            [lambdacd.core :as lambdacd]
+            [ring.server.standalone :as ring-server]
+            [lambdacd.ui.api]
+            [lambdacd-git.core :as git]
+            [lambdacd.runners :as runners]
+            [clojure.java.io :as io]
+            [lambdaui.api :as ui]))

 (def repo "git@github.com:flosell/testrepo")

-(defn wait-for-git [args ctx]`
-      (git/wait-for-git ctx repo
-                        :ref "refs/heads/master"
-                        :ms-between-polls (* 60 1000)))
+(defn wait-for-git [args ctx] `(git/wait-for-git ctx repo
+                                                 :ref "refs/heads/master"
+                                                 :ms-between-polls (* 60 1000)))

 (defn clone [args ctx]
-      (git/clone ctx repo (:revision args) (:cwd args)))
+  (git/clone ctx repo (:revision args) (:cwd args)))

 (defn ls [args ctx]
-      (shell/bash ctx (:cwd args) "ls"))
+  (shell/bash ctx (:cwd args) "ls"))

 (def pipeline-structure
   `((either
@@ -42,14 +41,20 @@
       default)
     ))

+(defonce pipe (atom nil))
+
 (defn -main [& args]
-      (let [home-dir (io/file "/tmp/foo")
-            config   {:home-dir home-dir}
-            port  (try-parse (System/getenv "PORT") 8082)
-            pipeline (lambdacd/assemble-pipeline pipeline-structure config)]
-           (git/init-ssh!)
-           (runners/start-one-run-after-another pipeline)
-           (ring-server/serve (routes
-                                (ui/ui-for-pipeline pipeline))
-                              {:open-browser? false
-                               :port          port})))
+  (let [home-dir (io/file "/tmp/foo")
+        config {:home-dir home-dir}
+        port (try-parse (System/getenv "PORT") 8082)
+        pipeline (lambdacd/assemble-pipeline pipeline-structure config)]
+
+    (reset! pipe pipeline)
+
+
+    (git/init-ssh!)
+    (runners/start-one-run-after-another pipeline)
+    (ring-server/serve (routes
+                         (ui/ui-for-pipeline pipeline))
+                       {:open-browser? false
+                        :port          port})))


Extra logging with graphite. (#1968)

Extra logging with graphite. (#1968)

Co-authored-by: Scott Crosby <23e8f75489aff47cf2cd5a529e9a769a24e9501c@twosigma.com>

--- scheduler/src/cook/reporter.clj
+++ scheduler/src/cook/reporter.clj
@@ -34,6 +34,7 @@

 (defn graphite-reporter
   [{:keys [prefix host port pickled?]}]
+  (log/info "Starting graphite reporter")
   (let [addr (InetSocketAddress. host port)
         graphite (if pickled?
                    (PickledGraphite. addr)


pure docstring updates

pure docstring updates

--- src/cats/core.cljc
+++ src/cats/core.cljc
@@ -69,18 +69,21 @@
     (reduce (partial p/mappend ctx) svs)))

 (defn pure
-  "Given any value v, return it wrapped in
-  default/effect free context.
-
-  This is multiarity function that with arity pure/1
-  it uses the dynamic scope to resolve the current
+  "Given any value `v`, return it wrapped in
+  the default/effect-free context.
+
+  This is a multi-arity function that with arity `pure/1`
+  uses the dynamic scope to resolve the current
   context. With `pure/2`, you can force a specific context
   value.

   Example:

       (with-context either/either-monad
-        (pure 1)
+        (pure 1))
+      ;; => #<Right [1]>
+
+      (pure either/either-monad 1)
       ;; => #<Right [1]>
   "
   ([v] (pure (ctx/get-current) v))


curry, lift-m, curry-lift-m docstring updates

--- src/cats/core.cljc
+++ src/cats/core.cljc
@@ -257,10 +257,10 @@

 #?(:clj
    (defmacro curry
-     "Given either a fixed arity function or an arity and a function
-     yields another which is curried.
-
-     With inferred arity (function must have one fixed arity)
+     "Given either a fixed arity function or an arity and a function,
+     return another which is curried.
+
+     With inferred arity (function must have one fixed arity):

          (defn add2 [x y] (+ x y))
          (def cadd2 (curry add2))
@@ -271,7 +271,7 @@
          (cadd2 1 3)
          ;; => 4

-     With fixed arity:
+     With given arity:

          (def c+ (curry 3 +))

@@ -299,8 +299,7 @@

 #?(:clj
    (defmacro lift-m
-     "Lifts a function with the given fixed number of arguments to a
-     monadic context.
+     "Lift a function with a given fixed arity to a monadic context.

          (def monad+ (lift-m 2 +))

@@ -335,7 +334,7 @@

 #?(:clj
    (defmacro curry-lift-m
-     "Is a composition of curry and lift-m macros."
+     "Composition of `curry` and `lift-m`"
      [n f]
      `(curry ~n (lift-m ~n ~f))))


Ensure that aggregations without aggregated values do not fail

--- src/cfpb/qu/data/aggregation.clj
+++ src/cfpb/qu/data/aggregation.clj
@@ -79,7 +79,7 @@

   If you want map and reduce already stringified, to send through
   Monger, run `generate-map-reduce`."
-  [{:keys [dataset from to group aggregations filter slicedef]}]
+  [{:keys [dataset from to group aggregations filter slicedef] :or {aggregations {}}}]
   {:pre [(every? #(not (nil? %)) [dataset from to group aggregations])
          (sequential? group)]}
   (let [field-zip-fn (if slicedef


Adjustments for storing data to disk

Adjustments for storing data to disk

--- src/clj/cglossa/models/seeds.clj
+++ src/clj/cglossa/models/seeds.clj
@@ -34,12 +34,11 @@
                       (map #(import-metadata-values % db))))))
 (defn seed []
   (let [url models/db-uri
-        _ (d/delete-database url)
-        _ (d/create-database url)
         conn (d/connect url)]
     (d/transact conn (concat
                        (generate-parts d/tempid (schema/dbparts))
                        (generate-schema d/tempid (schema/dbschema))))
     (d/transact conn (seed-corpora))
     (d/transact conn (seed-metadata-categories))
-    (d/transact conn (seed-metadata-values (d/db conn)))))
+    @(d/transact-async conn (seed-metadata-values (d/db conn)))
+    (println "Finished seeding the database")))


eagerly evaluate ALL

eagerly evaluate ALL

--- src/clj/com/rpl/specter/impl.clj
+++ src/clj/com/rpl/specter/impl.clj
@@ -145,7 +145,7 @@
     (let [empty-structure (empty structure)
           pfn (partial next-fn vals)]
       (if (list? empty-structure)
-        (map pfn structure)
+        (doall (map pfn structure))
         (->> structure (r/map pfn) (into empty-structure))
         ))))


Do all the ui changes on save after the server has been updated

before we had some changes in the ui (go back to read only) before the
server update and some (change the word) after the server was
successfully updated. This led to weird ui artifacts.

--- src/cljs/hyphen_keeper/core.cljs
+++ src/cljs/hyphen_keeper/core.cljs
@@ -153,12 +153,13 @@
                         (fn [hyphenation] (reset! new-suggestion hyphenation))))
             save #(do (when (hyphenation-valid? @new-hyphenation word)
                         (let [pattern (assoc pattern :hyphenation @new-hyphenation)
-                              on-success (fn [] (swap! app-state assoc-in [:hyphenations word] pattern))
+                              on-success (fn []
+                                           (swap! app-state assoc-in [:hyphenations word] pattern)
+                                           (reset! editing false))
                               on-error (fn [details]
                                          (.warn js/console
                                           (str "Failed to update hyphenation pattern: " details)))]
-                          (add-hyphenation-pattern! pattern on-success on-error)))
-                      (reset! editing false))
+                          (add-hyphenation-pattern! pattern on-success on-error))))
             remove #(remove-hyphenation-pattern! pattern)]
         (if-not @editing
           [hyphenation-pattern-readonly-ui word hyphenation start remove]


Changed code to set format correctly.

Changed code to set format correctly.

--- src/cmr/transmit/transformer.clj
+++ src/cmr/transmit/transformer.clj
@@ -3,21 +3,23 @@
   (:require [clj-http.client :as client]
             [cmr.common.services.errors :as errors]
             [cmr.transmit.config :as config]
-            [cheshire.core :as cheshire]
+            [cheshire.core :as json]
             [cmr.system-trace.http :as ch]
             [cmr.system-trace.core :refer [deftracefn]]
-            [cmr.transmit.connection :as conn]))
+            [cmr.transmit.connection :as conn]
+            [cmr.common.mime-types :as mt]))

 (deftracefn get-formatted-concept-revisions
   "Ask the transformer app for the concepts given by the concept-id, revision-id tuples in the
   given format."
   [context concept-tuples format]
   (let [conn (config/context->app-connection context :transformer)
-        tuples-json-str (cheshire/generate-string concept-tuples)
+        mime-type (format mt/format->mime-type)
+        tuples-json-str (json/encode concept-tuples)
         request-url (str (conn/root-url conn) "/concepts")
         response (client/post request-url {:body tuples-json-str
                                            :content-type :json
-                                           :accept format
+                                           :accept mime-type
                                            :throw-exceptions false
                                            :headers (ch/context->http-headers context)
                                            :connection-manager (conn/conn-mgr conn)})
@@ -28,7 +30,7 @@
         (errors/throw-service-error :not-found err-msg))

       200
-      (cheshire/decode (:body response) true)
+      (json/decode (:body response) true)

       ;; default
       (errors/internal-error! (str "Get concept revisions failed. Transformer app response status code: "


CMR-4664: Fixed failing tests.

CMR-4664: Fixed failing tests.

--- search-app/src/cmr/search/services/parameters/conversion.clj
+++ search-app/src/cmr/search/services/parameters/conversion.clj
@@ -133,7 +133,7 @@

 (defmethod common-params/always-case-sensitive-fields :collection
   [_]
-  #{:variable-concept-id})
+  #{:concept-id :variable-concept-id})

 (defmethod common-params/always-case-sensitive-fields :granule
   [_]


Function to send error response now accepts HTTP code (+ map of supported HTTP codes)

--- src/emender_jenkins/rest_api.clj
+++ src/emender_jenkins/rest_api.clj
@@ -26,6 +26,14 @@
 (def create-job-command "create_job")
 (def update-job-command "update_job")

+; HTTP codes used by several REST API responses
+(def http-codes {
+    :ok                    200
+    :bad-request           400
+    :not-found             404
+    :internal-server-error 500
+    :not-implemented       501})
+
 (defn read-request-body
     [request]
     (file-utils/slurp- (:body request)))
@@ -61,14 +69,14 @@
             (http-response/content-type "application/json"))))

 (defn send-error-response
-    [response request]
+    [response request http-code]
     (if (config/pretty-print? request)
         (-> (http-response/response (with-out-str (json/pprint response)))
             (http-response/content-type "application/json")
-            (http-response/status 400))
+            (http-response/status (get http-codes http-code)))
         (-> (http-response/response (json/write-str response))
             (http-response/content-type "application/json")
-            (http-response/status 400))))
+            (http-response/status (get http-codes http-code)))))

 (defn send-plain-response
     [response]


Document core.dsl.

Document core.dsl.

--- src/fhofherr/simple/core/dsl.clj
+++ src/fhofherr/simple/core/dsl.clj
@@ -1,7 +1,7 @@
 (ns fhofherr.simple.core.dsl
-  "Functions and macros required to define a Simple CI project in a `simple.clj`
-  project definition file. All public functions in this namespace are available
-  from within the `simple.clj` project definition file."
+  "Functions and macros required to configure Simple CI in a `simple.clj` file.
+  All public functions in this namespace are available from within the
+  `simple.clj` file."
   (:require [clojure.java.shell :refer [sh]]
             [fhofherr.simple.core [config :as config]
              [job-descriptor :as jobs]


Added two more simple solutions

Added two more simple solutions

--- src/main/cljc/clojure_club/spiral_challenge/brockturner.cljc
+++ src/main/cljc/clojure_club/spiral_challenge/brockturner.cljc
@@ -26,3 +26,27 @@
           s)))

 ;; (pretty-print-spiral (seq->spiral (range 20)))
+
+
+;; simple "compression" algorithm
+
+(defn compress [coll]
+  (reduce (fn [r i]
+            (let [[v c] (peek r)]
+              (if (= v i)
+                (conj (pop r) [v (inc c)])
+                (conj r [i 1]))))
+          [] coll))
+
+(defn str-compress [string]
+  (reduce (fn [r [v c]] (str r v (char c)))
+          "" (compress string)))
+
+
+;; "Find the meadow"
+
+(defn find-meadow [field]
+  (for [[y r] (map-indexed vector field)
+        [x c] (map-indexed vector r)
+        :when (= c \space)]
+    [x y]))


randomize grammar: makes a big difference in making more random expressions

--- src/babel/forest.cljc
+++ src/babel/forest.cljc
@@ -61,7 +61,7 @@
                   (log/debug (str "generate-all with spec: " (strip-refs spec)))
                   (log/debug (str "generate-all with pred: " (show-spec (remove-false (get-in spec [:synsem :sem :pred])))))
                   (log/debug (str "generate-all(details): " (show-spec spec)))
-                  (let [lb (lightning-bolt grammar
+                  (let [lb (lightning-bolt (lazy-shuffle grammar)
                                            lexicon
                                            spec 0 index nil morph)]
                     (-> lb


prevent log messages like "and -5 more"

prevent log messages like "and -5 more"

--- src/babel/forest.cljc
+++ src/babel/forest.cljc
@@ -269,8 +269,10 @@
 ;                         ". Head is:" (strip-refs (get-in bolt (concat (butlast path) [:head])))
                          ". Head notes:" (strip-refs (get-in bolt (concat (butlast path) [:head :notes])))
                          ". Complements tried were:"
-                         (str " " (string/join "," (map morph (take 5 complement-candidate-lexemes))) ".. and "
-                              (- (count complement-candidate-lexemes) 5) " more."))]
+                         (str " " (string/join "," (map morph (take 5 complement-candidate-lexemes)))
+                              (if (< 0 (- (count complement-candidate-lexemes) 5))
+                                (str ".. and "
+                                     (- (count complement-candidate-lexemes) 5) " more."))))]
                 (log/error message)
 ;                (throw (exception message)))
 )


move scope of function to within its log/debug for efficiency (don't use it -> don't call it)

--- src/babel/forest.cljc
+++ src/babel/forest.cljc
@@ -239,9 +239,10 @@
                                                         (copy complement)))
                                    is-fail? (fail? result)]
                                (if is-fail?
-                                 (let [fail-path (fail-path-between (strip-refs (get-in bolt path))
-                                                                    (strip-refs complement))]
-                                   (log/debug (str "fail-path-between(bolt=val1/comp=val2):" fail-path)))
+                                 (log/debug (str "fail-path-between(bolt=val1/comp=val2):"
+                                                 (fail-path-between (strip-refs (get-in bolt path))
+                                                                    (strip-refs complement))))
+
                                  (log/debug (str "success:" (:rule result) " returning: " (morph result))))

                                (if is-fail? :fail result)))


Make prepare-query* a protocol

Make prepare-query* a protocol

--- src/grafter/rdf4j/repository.clj
+++ src/grafter/rdf4j/repository.clj
@@ -426,6 +426,31 @@
   (evaluate [this]
     (.execute this)))

+(defprotocol IPrepareQuery
+  (prepare-query* [this sparql-string restriction]
+    "Low level function to prepare (parse, but not process) a sesame RDF
+  query.  Takes a repository a query string and an optional sesame
+  Dataset to act as a query restriction.
+
+  Prepared queries still need to be evaluated with evaluate."))
+
+(extend-protocol IPrepareQuery
+  Repository
+  (prepare-query* [repo sparql-string restriction]
+    (println "WARNING: prepare-query* was called on a repository not a connection.  This usage is deprecated and will be removed.")
+    (let [conn (->connection repo)]
+      (prepare-query* conn sparql-string restriction)))
+
+  RepositoryConnection
+  (prepare-query* [repo sparql-string restriction]
+    (let [conn (->connection repo)]
+      (let [pq (.prepareQuery conn
+                              QueryLanguage/SPARQL
+                              sparql-string)]
+
+        (when restriction (.setDataset pq restriction))
+        pq))))
+
 (defn prepare-query
   "Low level function to prepare (parse, but not process) a sesame RDF
   query.  Takes a repository a query string and an optional sesame
@@ -434,13 +459,7 @@
   Prepared queries still need to be evaluated with evaluate."
   ([repo sparql-string] (prepare-query repo sparql-string nil))
   ([repo sparql-string restriction]
-     (let [conn (->connection repo)]
-       (let [pq (.prepareQuery conn
-                               QueryLanguage/SPARQL
-                               sparql-string)]
-
-         (when restriction (.setDataset pq restriction))
-         pq))))
+   (prepare-query* repo sparql-string restriction)))

 (defn prepare-update
   "Prepare (parse but don't process) a SPARQL update request.


port discovery fixed

port discovery fixed

--- src/etaoin/api.clj
+++ src/etaoin/api.clj
@@ -1288,9 +1288,8 @@

   Returns a port as an integer."
   [type host]
-  (loop [port (-> type
-                  (get default-ports)
-                  (or (random-port)))]
+  (loop [port (or (default-ports type)
+                  (random-port))]
     (if (connectable? host port)
       (recur (random-port))
       port)))


bumps version to 1.49.2-SNAPSHOT

bumps version to 1.49.2-SNAPSHOT

--- scheduler/project.clj
+++ scheduler/project.clj
@@ -13,7 +13,7 @@
 ;; See the License for the specific language governing permissions and
 ;; limitations under the License.
 ;;
-(defproject cook "1.49.1"
+(defproject cook "1.49.2-SNAPSHOT"
   :description "This launches jobs on a Mesos cluster with fair sharing and preemption"
   :license {:name "Apache License, Version 2.0"}
   :dependencies [[org.clojure/clojure "1.8.0"]


Update

Update

--- src/boot_fmt/impl.clj
+++ src/boot_fmt/impl.clj
@@ -59,12 +59,9 @@
 (defn process-many
   [opts files]
   (when-not (seq files) (throw (RuntimeException. "No files found")))
-  (let [changes (mapv (fn [file] (bu/dbug "Processing %s\n" file) (process file opts))
-                      files)]
-    #_(if-not (->> changes
-                   (filter :changed?)
-                   seq)
-        (println "No changes."))))
+  (doseq [file files]
+    (bu/dbug "Processing %s\n" file)
+    (process file opts)))

 (defn clj-file?
   [f]


key is always host

key is always host

--- test/celestial/fixtures/data.clj
+++ test/celestial/fixtures/data.clj
@@ -14,11 +14,13 @@

 (def redis-type (slurp-edn "fixtures/redis-type.edn"))

-(def redis-ec2-spec (slurp-edn "fixtures/redis-ec2-system.edn"))
+(def redis-ec2-spec
+  (assoc-in (slurp-edn "fixtures/redis-ec2-system.edn") [:aws :key-name] host))
+
+(def redis-ec2-centos
+  (assoc-in (slurp-edn "fixtures/redis-ec2-centos.edn") [:aws :key-name] host))

 (def redis-physical (slurp-edn "fixtures/redis-physical.edn"))
-
-(def redis-ec2-centos (slurp-edn "fixtures/redis-ec2-centos.edn"))

 (def redis-vc-spec (slurp-edn "fixtures/redis-vc-system.edn"))

@@ -39,4 +41,4 @@
     (when (me.raynes.fs/exists? path) (slurp-edn path))))

 (def ^{:doc "an ami with puppet baked in"}
-  puppet-ami (merge-with merge redis-ec2-spec {:aws {:image-id "ami-f5e2ff81" :key-name host}}))
+  puppet-ami (assoc-in redis-ec2-spec [:aws :image-id] "ami-f5e2ff81"))


Fix civs.model.society-test

Fix civs.model.society-test

--- test/civs/model/society_test.clj
+++ test/civs/model/society_test.clj
@@ -13,18 +13,18 @@

 (deftest a-small-band-should-have-a-low-probability-of-splitting
   (let [ g (create-game nil)
-         t (:tribe (create-tribe g "unnamed" {:x 15 :y 18} (Population. 1 1 1 1 1) initial-culture :band))
+         {t :tribe g :game} (create-tribe g "unnamed" {:x 15 :y 18} (Population. 1 1 1 1 1) initial-culture :band)
          p (possibility-of-splitting g t)]
     (is (< p 0.05))))

 (deftest a-very-large-band-should-have-a-high-probability-of-splitting
   (let [ g (create-game nil)
-         t (:tribe (create-tribe g "unnamed" {:x 15 :y 18} (Population. 40 40 40 40 40) initial-culture :band))
+         {t :tribe g :game} (create-tribe g "unnamed" {:x 15 :y 18} (Population. 40 40 40 40 40) initial-culture :band)
          p (possibility-of-splitting g t)]
     (is (> p 0.50))))

 (deftest a-small-tribe-should-have-a-low-probability-of-splitting
   (let [ g (create-game nil)
-         t (:tribe (create-tribe g "unnamed" {:x 15 :y 18} (Population. 15 15 15 15 15) initial-culture :tribe))
+         {t :tribe g :game} (create-tribe g "unnamed" {:x 15 :y 18} (Population. 15 15 15 15 15) initial-culture :tribe)
          p (possibility-of-splitting g t)]
     (is (< p 0.05))))


Fix assertion.

Fix assertion.

--- test/lambdajam/jobs/test_1_4.clj
+++ test/lambdajam/jobs/test_1_4.clj
@@ -34,8 +34,8 @@
                  :catalog catalog
                  :lifecycles lifecycles
                  :task-scheduler :onyx.task-scheduler/balanced}]
-        (onyx.api/submit-job peer-config job)))
-    (is (= true false) "Job passed! It should fail!")
+        (onyx.api/submit-job peer-config job)
+        (throw (Error. "The test failed, submit-job completed without an error!"))))
     (catch InterruptedException e
       (Thread/interrupted))
     (catch Exception e


Update output_test to use :embedded hornetq instance instead of :vm

I couldn't get this test to pass since it refused to connect to the :vm instance.

--- test/onyx/plugin/output_test.clj
+++ test/onyx/plugin/output_test.clj
@@ -7,24 +7,31 @@

 (def id (java.util.UUID/randomUUID))

+(def config (read-string (slurp (clojure.java.io/resource "test-config.edn"))))
+
 (def scheduler :onyx.job-scheduler/round-robin)

 (def env-config
-  {:hornetq/mode :vm
+  {:hornetq/mode :standalone
    :hornetq/server? true
-   :hornetq.server/type :vm
-   :zookeeper/address "127.0.0.1:2185"
+   :hornetq.server/type :embedded
+   :hornetq.embedded/config ["hornetq/non-clustered-1.xml"]
+   :hornetq.standalone/host (:host (:non-clustered (:hornetq config)))
+   :hornetq.standalone/port (:port (:non-clustered (:hornetq config)))
+   :zookeeper/address (:address (:zookeeper config))
    :zookeeper/server? true
-   :zookeeper.server/port 2185
+   :zookeeper.server/port (:spawn-port (:zookeeper config))
    :onyx/id id
    :onyx.peer/job-scheduler scheduler})

 (def peer-config
-  {:hornetq/mode :vm
-   :zookeeper/address "127.0.0.1:2185"
+  {:hornetq/mode :standalone
+   :hornetq.standalone/host (:host (:non-clustered (:hornetq config)))
+   :hornetq.standalone/port (:port (:non-clustered (:hornetq config)))
+   :zookeeper/address (:address (:zookeeper config))
    :onyx/id id
-   :onyx.peer/inbox-capacity 100
-   :onyx.peer/outbox-capacity 100
+   :onyx.peer/inbox-capacity (:inbox-capacity (:peer config))
+   :onyx.peer/outbox-capacity (:outbox-capacity (:peer config))
    :onyx.peer/job-scheduler scheduler})

 (def env (onyx.api/start-env env-config))
@@ -52,11 +59,8 @@

 (def tx-queue (d/tx-report-queue datomic-conn))

-(def hornetq-host "localhost")
-
-(def hornetq-port 5465)
-
-(def hq-config {"host" hornetq-host "port" hornetq-port})
+(def hq-config {"host" (:host (:non-clustered (:hornetq config)))
+                "port" (:port (:non-clustered (:hornetq config)))})

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


Update commands to return has w/ story+output.

--- src/isla/story.clj
+++ src/isla/story.clj
@@ -60,10 +60,10 @@
   (look [this arguments-str]
     (let [arguments (extract-arguments arguments-str)]
       (if (empty? arguments)
-        (:summary (get player :room))
+        (creturn this (:summary (get player :room)))
         (if (= "at" (first arguments))
           (if-let [item (item this (second arguments))]
-            (:summary item)))))))
+            (creturn this (:summary item))))))))

 (defn init-story [story-str]
   (let [raw-env (interpreter/interpret


Use format instead of str for formating

Use format instead of str for formating

and constructing catalog entries

--- src/catalog/latex.clj
+++ src/catalog/latex.clj
@@ -83,147 +83,146 @@
        (string/replace #">>" "{>}>"))))

 (defn preamble [{:keys [title font creator] :or {font "Verdana"}}]
-  ["\\isopage[12]"
-   "\\fixpdflayout"
-   "\\checkandfixthelayout"
-   "\\usepackage{graphicx}"
-   "\\usepackage{titletoc}"
-   "\\usepackage[ngerman]{babel}"
-   "\\def\\languageshorthands#1{}"
-   "\\usepackage{fontspec,xunicode,xltxtra}"
-   "\\defaultfontfeatures{Mapping=tex-text}"
-   (str "\\setmainfont{" font "}")
-   "\\usepackage{hyperref}"
-   (str "\\hypersetup{pdftitle={" (escape title) "}, pdfauthor={" (escape creator) "}}")
-   "\\setsecnumdepth{subsubsection}"
-   "\\setlength{\\parindent}{0pt}"])
+  (let [[title creator] (map escape [title creator])]
+    (format
+     "\\isopage[12]
+\\fixpdflayout
+\\checkandfixthelayout
+\\usepackage{graphicx}
+\\usepackage{titletoc}
+\\usepackage[ngerman]{babel}
+\\def\\languageshorthands#1{}
+\\usepackage{fontspec,xunicode,xltxtra}
+\\defaultfontfeatures{Mapping=tex-text}
+\\setmainfont{%s}
+\\usepackage{hyperref}
+\\hypersetup{pdftitle={%s}, pdfauthor={%s}}
+\\setsecnumdepth{subsubsection}
+\\setlength{\\parindent}{0pt}" font title creator)))

 (defn frontmatter [{:keys [title issue-number year]}]
-  ["\\frontmatter"
-   "\\begin{Spacing}{1.75}"
-   (str  "{\\huge " (escape title) "}\\\\[0.5cm]")
-   "\\end{Spacing}"
-   "{\\large Ausgabenummer und Jahr}\\\\[1.5cm]"
-   "\\vfill"
-   "Logo\\\\ "
-   "SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte\\\\[0.5cm]"
-   "\\cleartorecto"])
+  (format
+   "\\frontmatter
+\\begin{Spacing}{1.75}
+{\\huge %s}\\\\[0.5cm]
+\\end{Spacing}
+{\\large Ausgabenummer und Jahr}\\\\[1.5cm]
+\\vfill
+Logo\\\\
+SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte\\\\[0.5cm]
+\\cleartorecto" (escape title)))

 (defn mainmatter [env]
-  ["\\mainmatter"
-   ;; "\\pagestyle{plain}"
-   "\\tableofcontents"])
-
-(defmulti catalog-entry (fn [{format :format}] format))
+  "\\mainmatter
+%% \\pagestyle{plain}
+\\tableofcontents")
+
+(defmulti catalog-entry (fn [{fmt :format}] fmt))

 (defmethod catalog-entry :hörfilm
   [{:keys [title personel-name description source_publisher source_date genre library_signature]}]
-  ["\\begin{description}"
-   (string/join " "
-                [(format "\\item[%s]" (escape title))
-                 (format "Regie: %s" (escape personel-name))
-                 (escape source_date)
-                 (translations genre) "\\\\"
-                 (escape description)
-                 (escape library_signature)])
-   "\\end{description}"])
+  (format "\\begin{description}
+\\item[%s] Regie: %s %s %s \\\\ %s %s
+\\end{description}"
+          (escape title) (escape personel-name)
+          (escape source_date) (translations genre)
+          (escape description) (escape library_signature)))

 (defmethod catalog-entry :hörbuch
   [{:keys [title creator description source_publisher source_date genre duration narrator
            producer producer_place produced_commercially
            library_signature]}]
-  ["\\begin{description}"
-   (string/join " "
-                [(format "\\item[%s]" (escape title))
-                 (escape creator)
-                 (escape source_publisher)
-                 (escape source_date)
-                 (translations genre) "\\\\"
-                 (escape description) "\\\\"
-                 (escape duration)
-                 (format "gelesen von: %s" (escape narrator))
-                 (escape producer) (escape producer_place)
-                 (escape produced_commercially)
-                 (escape library_signature)])
-   "\\end{description}"])
+  (format "\\begin{description}
+\\item[%s] %s %s %s %s \\\\ %s \\\\ %s Gelesen von: %s %s %s %s %s
+\\end{description}"
+          (escape title)
+          (escape creator)
+          (escape source_publisher)
+          (escape source_date)
+          (translations genre)
+          (escape description)
+          (escape duration)
+          (escape narrator)
+          (escape producer)
+          (escape producer_place)
+          (escape produced_commercially)
+          (escape library_signature)))

 (defmethod catalog-entry :default
-  [{:keys [title creator description source_publisher source_date genre duration]}]
-  ["\\begin{description}"
-   (string/join " "
-                [(format "\\item[%s]" (escape title))
-                 (escape creator)
-                 (escape source_publisher)
-                 (escape source_date)
-                 (translations genre) "\\\\"
-                 (escape description)
-                 "Spieldauer"
-                 (escape duration)])
-   "\\end{description}"])
+  [{:keys [title creator description source_publisher source_date genre]}]
+  (format "\\begin{description}
+\\item[%s] %s %s %s %s \\\\ %s
+\\end{description}"
+          (escape title)
+          (escape creator)
+          (escape source_publisher)
+          (escape source_date)
+          (translations genre)
+          (escape description)))

 (defn catalog-entries [items]
   (for [item items] (catalog-entry item)))

 (defn subgenre-entry [subgenre items]
   (when (subgenre items)
-    [(str "\\subsubsection{" (translations subgenre "FIXME")"}")
+    [(format "\\subsubsection{%s}" (translations subgenre "FIXME"))
      (catalog-entries (subgenre items))]))

 (defn subgenre-entries [items]
   (for [subgenre subgenres] (subgenre-entry subgenre items)))

-(defn genre-entry [format genre items]
+(defn genre-entry [fmt genre items]
   (when (genre items)
-    [(str "\\subsection{" (translations genre "FIXME") "}")
+    [(format "\\subsection{%s}" (translations genre "FIXME"))
      (cond
        (#{:kinder-und-jugendbücher} genre) (subgenre-entries (genre items))
-       (#{:hörbuch} format) (subgenre-entries (genre items))
+       (#{:hörbuch} fmt) (subgenre-entries (genre items))
        :else (catalog-entries (genre items)))]))

-(defn genre-entries [format items]
-  (for [genre genres] (genre-entry format genre items)))
-
-(defn format-entry [format items]
-  (when (format items)
-    [(str "\\section{" (translations format "FIXME") "}")
+(defn genre-entries [fmt items]
+  (for [genre genres] (genre-entry fmt genre items)))
+
+(defn format-entry [fmt items]
+  (when (fmt items)
+    [(format "\\section{%s}" (translations fmt "FIXME"))
      ;; start a section toc
      "\\startcontents"
      ;; the toc should range from levels 2 to 3 inclusive (i.e. 2 and 3)
      "\\printcontents{}{2}{\\setcounter{tocdepth}{3}}"
-     (case format
-       (:hörfilm :ludo) (catalog-entries (format items))
-       (genre-entries format (format items)))]))
+     (case fmt
+       (:hörfilm :ludo) (catalog-entries (fmt items))
+       (genre-entries fmt (fmt items)))]))

 (defn format-entries [items]
-  (for [format formats] (format-entry format items)))
+  (for [fmt formats] (format-entry fmt items)))

 (defn catalog [{items :items}]
   ["\\chapter{Katalog}"
    (format-entries items)])

 (defn impressum [env]
-   ["\\chapter{Impressum}"
-   ""
-   "Neu im Sortiment"
-   ""
-   "Für Kundinnen und Kunden der SBS sowie für Interessenten"
-   ""
-   "Erscheint sechsmal jährlich und weist alle seit der letzten Ausgabe neu in die SBS aufgenommenen Bücher nach"
-   ""
-   "Neu im Sortiment kann im Jahresabonnement per Post zu CHF XX oder per E-Mail gratis bezogen werden."
-   ""
-   "Herausgeber:\\\\ "
-   "SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte\\\\ "
-   "Grubenstrasse 12\\\\ "
-   "CH-8045 Zürich\\\\ "
-   "Fon +41 43 333 32 32\\\\ "
-   "Fax +41 43 333 32 33\\\\ "
-   "www.sbs.ch"
-   ""
-   "Abonnement, Ausleihe und Verkauf: nutzerservice@sbs.ch\\\\ "
-   "Verkauf Institutionen: medienverlag@sbs.ch"
-   ""
-   "Copyright Vermerk"])
+   "\\chapter{Impressum}
+
+Neu im Sortiment
+
+Für Kundinnen und Kunden der SBS sowie für Interessenten
+
+Erscheint sechsmal jährlich und weist alle seit der letzten Ausgabe neu in die SBS aufgenommenen Bücher nach
+
+Neu im Sortiment kann im Jahresabonnement per Post zu CHF XX oder per E-Mail gratis bezogen werden.
+
+Herausgeber:\\\\
+SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte\\\\
+Grubenstrasse 12\\\\
+CH-8045 Zürich\\\\
+Fon +41 43 333 32 32\\\\
+Fax +41 43 333 32 33\\\\
+www.sbs.ch
+
+Abonnement, Ausleihe und Verkauf: nutzerservice@sbs.ch\\\\
+Verkauf Institutionen: medienverlag@sbs.ch
+
+Copyright Vermerk")

 (defn document [{:keys [class options]
                  :or {class "memoir"
@@ -231,7 +230,7 @@
                  :as env}]
   (string/join "\n"
    (flatten
-    [(str "\\documentclass[" (string/join "," options) "]{" class "}")
+    [(format "\\documentclass[%s]{%s}" (string/join "," options) class)
      (preamble env)
      "\\begin{document}"
      (frontmatter env)


Started cvt-expr.

Started cvt-expr.

--- src/cbfg/zgo/core.clj
+++ src/cbfg/zgo/core.clj
@@ -60,6 +60,36 @@
      (re-find #"\?$" plast) "bool" ; When ends with '?'.
      :default (string/capitalize plast))))

+(defn cvt-ago [scope name [self-actx actx body]]
+  ["go {" body "}"])
+
+(defn cvt-ago-loop [scope name [self-actx actx bindings body]]
+  [bindings ";\n"
+   "go for {" body "}"])
+
+(def cvt-special-fns
+  {"ago" cvt-ago
+   "ago-loop" cvt-ago-loop
+   })
+
+(defn cvt-normal-fn [scope name args]
+  [name "(" args ")"])
+
+(defn cvt-expr [scope expr]
+  (cond
+   (vector? expr) ["[" (interpose "," (map #(cvt-expr scope %) expr)) "]"]
+   (map? expr) ["{" (interpose "," (map (fn [[k v]]
+                                          [(cvt-expr scope k) ":"
+                                           (cvt-expr scope v)])
+                                        expr)) "}"]
+   (coll? expr) (let [[fn-name & args] expr
+                      fn-handler (get cvt-special-fns (str fn-name)
+                                      cvt-normal-fn)]
+                  (fn-handler scope fn-name args))
+   (symbol? expr) (cvt-sym expr)
+   (keyword? expr) (str expr)
+   :default ["DEFAULT-EXPR" expr]))
+
 (defn cvt-fn-params [params]
   ["(" (interpose "," (map (fn [sym] [(cvt-sym sym) (cvt-type sym)])
                            params))
@@ -68,7 +98,7 @@
 (defn cvt-fn-body [params forms]
   (map-indexed (fn [idx form]
                  [(when (= idx (dec (count forms))) "return")
-                  form ";"])
+                  (cvt-expr params form) ";"])
                forms))

 (defn cvt-fn [params body]


Core methods for agenda advancement cost effects.

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -20,7 +20,7 @@
   (let [username (get-in @state [side :user :username])]
     (say state side {:user "__system__" :text (str username " " text ".")})))

-(declare prompt! forfeit trigger-event handle-end-run trash)
+(declare prompt! forfeit trigger-event handle-end-run trash update-advancement-cost)

 (defn pay [state side card & args]
   (let [costs (merge-costs (remove #(or (nil? %) (= % [:forfeit])) args))
@@ -600,7 +600,7 @@

 (defn score [state side args]
   (let [card (or (:card args) args)]
-    (when (>= (:advance-counter card) (:advancementcost card))
+    (when (>= (:advance-counter card) (or (:current-cost card) (:advancementcost card)))
       (let [moved-card (move state :corp card :scored)
             c (card-init state :corp moved-card)]
         (system-msg state :corp (str "scores " (:title c) " and gains " (:agendapoints c)
@@ -806,7 +806,7 @@
   (swap! state assoc-in [side :register] nil)
   (swap! state assoc-in [side :click] (get-in @state [side :click-per-turn]))
   (trigger-event state side (if (= side :corp) :corp-turn-begins :runner-turn-begins))
-  (when (= side :corp) (draw state :corp)))
+  (when (= side :corp) (do (draw state :corp) (update-all-advancement-costs state side))))

 (defn end-turn [state side args]
   (let [max-hand-size (get-in @state [side :max-hand-size])]
@@ -953,6 +953,8 @@
                    (system-msg state side (str "installs " card-name " in " server))))
                (let [moved-card (move state side c slot)]
                  (trigger-event state side :corp-install moved-card)
+                 (when (= (:type c) "Agenda")
+                   (update-advancement-cost state side moved-card))
                  (when rezzed (rez state side moved-card {:no-cost true})))))))))

 (defn play [state side {:keys [card server]}]
@@ -969,9 +971,33 @@
     (resolve-ability state side derez-effect (get-card state card) nil))
   (trigger-event state side :derez card))

+(defn advancement-cost-bonus [state side n]
+  (swap! state update-in [:bonus :advancement-cost] (fnil #(+ % n) 0)))
+
+(defn advancement-cost [state side {:keys [advancementcost] :as card}]
+  (if (nil? advancementcost)
+    nil
+    (-> (if-let [costfun (:advancement-cost-bonus (card-def card))]
+          (+ advancementcost (costfun state side card nil))
+          advancementcost)
+        (+ (or (get-in @state [:bonus :advancement-cost]) 0))
+        (max 0))))
+
+(defn update-all-advancement-costs [state side]
+  (doseq [ag (->> (mapcat :content (flatten (seq (get-in @state [:corp :servers]))))
+                  (filter #(= (:type %) "Agenda")))]
+    (update-advancement-cost state side ag)))
+
+(defn update-advancement-cost [state side agenda]
+  (system-msg state side (str "update agenda " (:title agenda)))
+  (swap! state update-in [:bonus] dissoc :advancement-cost)
+  (trigger-event state side :pre-advancement-cost agenda)
+  (update! state side (assoc agenda :current-cost (advancement-cost state side agenda))))
+
 (defn advance [state side {:keys [card]}]
   (when (pay state side card :click 1 :credit 1)
     (system-msg state side "advances a card")
+    (update-advancement-cost state side card)
     (add-prop state side card :advance-counter 1)))

 (defn forfeit [state side card]


edn data type

edn data type

--- src/clj/neb/types.clj
+++ src/clj/neb/types.clj
@@ -125,6 +125,11 @@
              :encoder nippy/freeze
              :decoder nippy/thaw
              :dep :bytes
+             :example [{:a 1 :b 2}]}
+   :edn     {:id      21 :dynamic? true
+             :encoder (fn [obj] (.getBytes (pr-str obj) string-encoding))
+             :decoder (fn [^bytes byte-arr] (read-string (String. byte-arr string-encoding)))
+             :dep :bytes
              :example [{:a 1 :b 2}]}})

 (def int-writer (get-in @data-types [:int :writer]))


whitespace fixes

whitespace fixes

--- src/clj_http/core.clj
+++ src/clj_http/core.clj
@@ -36,16 +36,16 @@
    will be a vector containing the values in the order they appeared
    in the headers."
   ([#^HeaderIterator headers]
-      (parse-headers headers #(.toLowerCase %)))
+     (parse-headers headers #(.toLowerCase %)))
   ([#^HeaderIterator headers name-transform]
-      (->> (iterator-seq headers)
-           (map (fn [#^Header h] [(name-transform (.getName h)) (.getValue h)]))
-           (group-by first)
-           (map (fn [[name headers]]
-                  (let [values (map second headers)]
-                    [name (let [[value & tail] values]
-                            (if tail values value))])))
-           (into {}))))
+     (->> (iterator-seq headers)
+          (map (fn [#^Header h] [(name-transform (.getName h)) (.getValue h)]))
+          (group-by first)
+          (map (fn [[name headers]]
+                 (let [values (map second headers)]
+                   [name (let [[value & tail] values]
+                           (if tail values value))])))
+          (into {}))))

 (defn set-client-param [#^HttpClient client key val]
   (when-not (nil? val)
@@ -276,7 +276,10 @@
               resp (merge {:status (.getStatusCode (.getStatusLine http-resp))
                            :headers (parse-headers (.headerIterator http-resp))
                            :body (coerce-body-entity req http-entity conn-mgr)}
-                          (if raw-headers {:raw-headers (parse-headers (.headerIterator http-resp) identity)}))]
+                          (when raw-headers
+                            {:raw-headers
+                             (parse-headers (.headerIterator http-resp)
+                                            identity)}))]
           (if save-request?
             (-> resp
                 (assoc :request req)


Fixed logic for getting port used by this application

--- src/clouseau/core.clj
+++ src/clouseau/core.clj
@@ -47,6 +47,8 @@

 (require '[clouseau.server         :as server])

+(def default-port
+    "3000")

 (def cli-options
     ;; an option with a required argument
@@ -67,7 +69,9 @@
 (defn get-port
     "Returns specified port or default port if none is specified on the command line."
     [specified-port]
-    (or specified-port "3000"))
+    (if (or (not specified-port) (empty? specified-port))
+        default-port
+        specified-port))

 (defn -main
     "Entry point to the Clouseau server."


finish part 3

finish part 3

--- resources/workshop/do-things.clj
+++ resources/workshop/do-things.clj
@@ -33,7 +33,7 @@

 "Tout le code Clojure est écrit dans une structure uniforme. Clojure comprend:

-* Représentations littérales de structures de données comme les numéros, cordes, cartes, et vecteurs
+* Représentations littérales de structures de données comme les numéros, cordes, maps, et vecteurs
 * Opérations
 Nous utilisons la forme de terme pour se référer au code structurellement valide. Ces représentations littérales sont des formes toutes valides:

@@ -324,7 +324,7 @@
   )

-"Le get-in fonction vous permet de rechercher des valeurs dans les cartes imbriquées:"
+"Le get-in fonction vous permet de rechercher des valeurs dans les maps imbriquées:"
 (comment
   (get-in {:a 0 :b {:c "ho hum"}} [:b :c])
   ; => "ho hum"
@@ -346,7 +346,7 @@

 [[:section {:tags "keywords" :title "Mots Clés"}]]

-"Les mots-clés en Clojure sont mieux compris par la façon dont ils sont utilisés. Ils sont principalement utilisés comme clés dans les cartes, comme vous pouvez le voir ci-dessus. Exemples de mots clés:"
+"Les mots-clés en Clojure sont mieux compris par la façon dont ils sont utilisés. Ils sont principalement utilisés comme clés dans les maps, comme vous pouvez le voir ci-dessus. Exemples de mots clés:"

 (comment
@@ -376,14 +376,14 @@

 "Je pense que ce est super cool et réel Clojurists le fais tout le temps. Vous devriez le faire aussi!

-Outre l'utilisation de la carte littéraux, vous pouvez utiliser le hash-map fonction pour créer une carte:"
+Outre l'utilisation de la map littéraux, vous pouvez utiliser le hash-map fonction pour créer une map:"

 (comment
   (hash-map :a 1 :b 2)
 ; => {:a 1 :b 2}
 )

-"Clojure vous permet également de créer des cartes triées, mais je ne couvrira pas cela."
+"Clojure vous permet également de créer des maps triées, mais je ne couvrira pas cela."

 [[:section {:tags "vectors" :title "Vecteurs"}]]

@@ -506,7 +506,7 @@
   ; => nil

   )
-"Tout comme vous pouvez créer des cartes et des cartes de hachage triés, vous pouvez créer des ensembles de hachage et des jeux triés:"
+"Tout comme vous pouvez créer des maps et des maps de hachage triés, vous pouvez créer des ensembles de hachage et des jeux triés:"

 (comment
   (Hash-set 1 1 3 1 2)
@@ -575,7 +575,7 @@
   (first ['failed-protagonist-names 'failed-antagonist-names])
   ; => failed-protagonist-names
   )
-"Vous pouvez également citer collections comme des listes, des cartes et des vecteurs. Tous les symboles de la collection seront non évalués:"
+"Vous pouvez également citer collections comme des listes, des maps et des vecteurs. Tous les symboles de la collection seront non évalués:"

 (comment

@@ -611,3 +611,568 @@
 "

+[[:chapter {:tag "fonctions" :title "Fonctions"}]]
+
+"Une des raisons les gens vont écrous sur Lisps, ce est qu'ils vous permettent de construire des programmes qui se comportent de façon complexe, mais le premier bloc de construction - la fonction - est si simple. Cette section vous initier à la beauté et l'élégance de fonctions Lisp en expliquant:
+
+*Appel de fonctions
+*Comment fonctions diffèrent de macros et les formulaires spéciaux
+*Définir des fonctions
+*Les fonctions anonymes
+*Fonctions retour"
+
+[[:section {:tags "appel_de_fonctions" :title "Appel de fonctions"}]]
+
+"A présent, vous avez vu de nombreux exemples d'appels de fonction:"
+
+(comment
+
+  (+ 1 2 3 4)
+  (* 1 2 3 4)
+  (Première [1 2 3 4])
+  )
+
+
+"Je suis déjà allé sur la façon dont toutes les expressions Clojure ont la même syntaxe: parenthèse ouvrante, l'opérateur, opérandes, de fermer la parenthèse. \"Appel de fonction\" est juste un autre terme pour une expression où l'opérateur est une expression de fonction. Une expression de fonction est juste une expression qui renvoie une fonction.
+
+Il pourrait ne pas être évident, mais cela vous permet d'écrire du code assez intéressant. Voici une expression de fonction qui renvoie le + fonction (de plus):"
+
+(comment
+
+  ;; Return value of "or" is first truthy value, and + is truthy
+  (or + -)
+  )
+
+"Vous pouvez utiliser cette expression que l'opérateur dans une autre expression:"
+
+(comment
+
+  ((or + -) 1 2 3)
+  ; => 6
+  )
+
+"Voici appels de fonction un couple de plus valides qui reviennent 6:"
+
+(comment
+
+  ;; Return value of "and" is first falsey value or last truthy value.
+  ;; + is the last truthy value
+  ((and (= 1 1) +) 1 2 3)
+
+  ;; Return value of "first" is the first element in a sequence
+  ((first [+ 0]) 1 2 3)
+
+
+  )
+
+"Cependant, ce ne sont pas les appels de fonction valides:"
+(comment
+  ;; Numbers aren't functions
+  (1 2 3 4)
+
+  ;; Neither are strings
+  ("test" 1 2 3)
+  )
+
+"Si vous exécutez ces derniers dans votre REPL vous obtiendrez quelque chose comme"
+
+(comment
+  ClassCastException java.lang.String cannot be cast to clojure.lang.IFn
+  user/eval728 (NO_SOURCE_FILE:1)
+  )
+"Vous êtes susceptible de voir cette erreur autant de fois que vous continuez avec Clojure. \"X ne peut pas être converti en clojure.lang.IFn\" signifie simplement que vous essayez quelque chose comme une fonction quand elle ne est pas.
+
+la flexibilité de fonction ne se arrête pas avec l'expression de fonction! Syntaxiquement, les fonctions peuvent prendre des expressions comme arguments - y compris d'autres fonctions.
+
+Prenez la map fonction (à ne pas confondre avec la structure de données de map). map crée une nouvelle liste en appliquant une fonction à chaque membre d'une collection:"
+
+(comment
+
+  ;; The "inc" function increments a number by 1
+  (inc 1.1)
+  ; => 2.1
+
+  (map inc [0 1 2 3])
+  ; => (1 2 3 4)
+  )
+
+
+"(Notez que map ne retourne pas un vecteur, même si nous avons fourni un vecteur comme argument. Vous apprendrez pourquoi plus tard. Pour l'instant, espérons que ce est OK et attendu.)
+
+En effet, la capacité de Clojure pour recevoir fonctions comme arguments vous permet de construire des abstractions plus puissants. Ceux qui connaissent mal ce genre de programmation pensent des fonctions que vous permettant de généraliser les opérations plus instances de données. Par exemple, la + fonction abstraction outre, plus de chiffres précis.
+
+. En revanche, Clojure (et tous Lisps) vous permet de créer des fonctions qui généralisent sur les processus map vous permet de généraliser le processus de transformation d'une collection en appliquant une fonction - une fonction - plus de toute collection.
+
+La dernière chose que vous devez savoir sur les appels de fonction est que Clojure évalue tous les arguments de la fonction récursive avant de les transmettre à la fonction. Voici comment Clojure va évaluer un appel de fonction dont les arguments sont aussi des appels de fonctions:"
+
+
+(comment
+
+  ;; Here's the function call. It kicks off the evaluation process
+  (+ (inc 199) (/ 100 (- 7 2)))
+
+  ;; All sub-forms are evaluated before applying the "+" function
+  (+ 200 (/ 100 (- 7 2))) ; evaluated "(inc 199)"
+  (+ 200 (/ 100 5)) ; evaluated (- 7 2)
+  (+ 200 20) ; evaluated (/ 100 5)
+  220 ; final evaluation
+  )
+
+[[:section {:tags "appel_de_fonctions_macro_forme_special" :title "Appels de fonction, les appels de macro, et les formes spéciales"}]]
+
+
+"Dans la dernière section, vous avez appris que les appels de fonction sont des expressions qui ont une expression de fonction en tant qu'opérateur. Il existe deux autres types d'expressions: appels de macro et **formes spéciales**. Vous avez déjà vu un couple formes spéciales:"
+
+(comment
+
+  (def failed-movie-titles ["Gone With the Moving Air" "Swellfellas"])
+  (if (= severity :mild)
+    (def error-message (str error-message "MILDLY INCONVENIENCED!"))
+    (def error-message (str error-message "DOOOOOOOMED!")))
+  )
+
+"Vous apprendrez tout ce qu'il ya à savoir sur les appels de macro et les formes spéciales dans le chapitre \"Clojure Alchemy: lecture, l'évaluation et les macros». Pour l'instant, cependant, la principale caractéristique qui rend formes spéciales \"spécial\", ce est qu'ils ne évaluent pas toujours tous leurs opérandes, contrairement appels de fonction.
+Prenez if , par exemple. Sa structure générale est:"
+
+(comment
+  (if boolean-form
+    then-form
+    optional-else-form)
+  )
+
+
+"Maintenant, imaginez que vous aviez un if déclaration de ce genre:"
+
+
+(comment
+  (if good-mood
+    (tweet walking-on-sunshine-lyrics)
+    (tweet mopey-country-song-lyrics))
+  )
+
+"Si Clojure évalué deux tweet appels de fonction, puis tes followers finiraient très confus.
+
+Une autre caractéristique qui différencie les formes spéciales, ce est que vous ne pouvez pas les utiliser comme arguments de fonctions.
+
+En général, les formes particulières à mettre en œuvre la fonctionnalité Clojure de base qui ne peut pas être mis en œuvre avec des fonctions. Il ya seulement une poignée de formes spéciales Clojure, et il est assez étonnant que cette langue riche est mis en œuvre avec un tel petit ensemble de blocs de construction.
+
+Macros sont semblables à des formes particulières en ce qu'elles évaluent leurs opérandes différemment des appels de fonction et ils ont aussi ne peuvent pas être passés comme arguments à des fonctions. Mais ce détour a pris assez longtemps; il est temps d'apprendre à définir des fonctions!"
+
+
+[[:section {:tags "definition_de_fonctions" :title "Définition de fonctions"}]]
+
+"Les définitions de fonctions sont constituées de cinq parties principales:
+
+*defn
+*Un nom
+*(Facultatif) un docstring
+*Les Paramètres
+*Le corps de la fonction
+"
+
+"Voici un exemple d'une définition de fonction et appelant la fonction:"
+
+(comment
+
+  (defn too-enthusiastic
+    "Return a cheer that might be a bit too enthusiastic"
+    [name]
+    (str "OH. MY. GOD! " name " YOU ARE MOST DEFINITELY LIKE THE BEST "
+      "MAN SLASH WOMAN EVER I LOVE YOU AND WE SHOULD RUN AWAY TO SOMEWHERE"))
+
+  (too-enthusiastic "Zelda")
+  ; => "OH. MY. GOD! Zelda YOU ARE MOST DEFINITELY LIKE THE BEST MAN SLASH WOMAN EVER I LOVE YOU AND WE SHOULD RUN AWAY TO SOMEWHERE"
+
+  )
+
+"Débutons plus profondément dans le docstring, paramètres, et le corps de la fonction."
+[[:subsection {:tags "definition_de_fonctions" :title "Définition de fonctions"}]]
+
+
+"Le docstring est vraiment cool. Vous pouvez afficher l'docstring pour une fonction dans le REPL avec (doc fn-name) , par exemple (doc map) . Le docstring est également utilisé si vous utilisez un outil pour générer la documentation de votre code. Dans l'exemple ci-dessus, \"Return a cheer that might be a bit too enthusiasti\" est le docstring."
+
+[[:subsection {:tags "Les_parametres" :title "Les Paramètres"}]]
+
+"Clojure fonctions peuvent être définies avec zéro ou plusieurs paramètres:"
+
+(comment
+  (defn no-params
+    []
+    "I take no parameters!")
+
+  (defn one-param
+    [x]
+    (str "I take one param: " x " It'd better be a string!"))
+
+  (defn two-params
+    [x y]
+    (str "Two parameters! That's nothing! Pah! I will smoosh them "
+      "together to spite you! " x y))
+  )
+
+"Les fonctions peuvent également être surchargés par arité. Cela signifie que un corps de fonction différent de fonctionner selon le nombre d'arguments passés à une fonction.
+
+Voici la forme générale d'une définition de fonction de plusieurs arité. Notez que chaque définition de arité est entre parenthèses et a une liste d'arguments:"
+
+(comment
+
+  (defn multi-arity
+    ;; 3-arity arguments and body
+    ([first-arg second-arg third-arg]
+      (do-things first-arg second-arg third-arg))
+    ;; 2-arity arguments and body
+    ([first-arg second-arg]
+      (do-things first-arg second-arg))
+    ;; 1-arity arguments and body
+    ([first-arg]
+      (do-things first-arg)))
+  )
+
+"Surcharge par arité est un moyen de fournir des valeurs par défaut pour les arguments. Dans ce cas, \"karate\" est l'argument par défaut pour le chop-type param:"
+
+(comment
+
+  (defn x-chop
+    "Describe the kind of chop you're inflicting on someone"
+    ([name chop-type]
+      (str "I " chop-type " chop " name "! Take that!"))
+    ([name]
+      (x-chop name "karate")))
+  )
+
+
+"Si vous appelez x-chop avec deux arguments, la fonction fonctionne comme il le ferait si elle ne était pas une fonction multi-arité:"
+
+(comment
+  (x-chop "Kanye West" "slap")
+  ; => "I slap chop Kanye West! Take that!"
+  )
+
+"Si vous appelez x-chop avec un seul argument, cependant, puis x-chop sera effectivement se appeler avec le second argument \"karate\" fourni:"
+
+(comment
+
+  (x-chop "Kanye East")
+  ; => "I karate chop Kanye East! Take that!"
+
+  )
+
+
+"Il peut sembler inhabituel de définir une fonction en termes de lui-même de ce genre. Si oui, super! Vous apprenez une nouvelle façon de faire les choses!
+
+Vous pouvez également faire de chaque arité faire quelque chose de complètement indépendant:"
+
+(comment
+
+  (defn weird-arity
+    ([]
+      "Destiny dressed you this morning my friend, and now Fear is
+      trying to pull off your pants. If you give up, if you give in,
+      you're gonna end up naked with Fear just standing there laughing
+      at your dangling unmentionables! - the Tick")
+    ([number]
+      (inc number)))
+
+  )
+
+"Mais le plus probable, vous ne voulez pas le faire.Clojure vous permet également de définir des fonctions arité variable en incluant un \"reste-param\", comme dans \"mettre le reste de ces arguments dans une liste avec le nom suivant\":"
+
+(comment
+  (defn codger-communication
+    [whippersnapper]
+    (str "Get off my lawn, " whippersnapper "!!!"))
+
+  (defn codger
+    [& whippersnappers] ;; the ampersand indicates the "rest-param"
+    (map codger-communication whippersnappers))
+
+  (codger "Billy" "Anne-Marie" "The Incredible Bulk")
+  ; =>
+  ; ("Get off my lawn, Billy!!!"
+  ;  "Get off my lawn, Anne-Marie!!!"
+  ;  "Get off my lawn, The Incredible Bulk!!!")
+
+  )
+
+
+"Comme vous pouvez le voir, lorsque vous fournissez des arguments aux fonctions arité variable, les arguments sont traités comme une liste.
+
+Vous pouvez mélanger repos-params avec params normales, mais le reste-param doit venir en dernier:"
+
+(comment
+  (defn favorite-things
+    [name & things]
+    (str "Hi, " name ", here are my favorite things: "
+      (clojure.string/join ", " things)))
+
+  (favorite-things "Doreen" "gum" "shoes" "kara-te")
+  ; => "Hi, Doreen, here are my favorite things: gum, shoes, kara-te"
+  )
+
+"Enfin, Clojure a une façon plus sophistiquée de la définition des paramètres appelé \"déstructuration\", qui mérite son propre paragraphe:"
+[[:subsection {:tags "Destructuration" :title "Déstructuration"}]]
+
+"L'idée de base derrière déstructuration est qu'il vous permet de lier de façon concise *symboles* à des *valeurs* au sein d'une *collection*. Regardons un exemple de base:"
+
+
+(comment
+
+
+  ;; Return the first element of a collection
+  (defn my-first
+    [[first-thing]] ; Notice that first-thing is within a vector
+    first-thing)
+
+  (my-first ["oven" "bike" "waraxe"])
+  ; => "oven"
+
+  )
+
+"Voici comment vous voulez faire la même chose sans déstructuration:"
+
+(comment
+
+  (defn my-other-first
+    [collection]
+    (first collection))
+  (my-other-first ["nickel" "hair"])
+  ; => "nickel"
+  )
+
+
+
+"Comme vous pouvez le voir, les my-first associés le symbole first-thing avec le premier élément du vecteur qui a été adoptée en argument. Vous dites my-first à le faire en plaçant le symbole first-thing dans un vecteur.
+
+Ce vecteur est comme une énorme pancarte tenue jusqu'à Clojure qui dit, \"Hey! Cette fonction va recevoir une liste ou un vecteur ou un ensemble comme un argument. Faire ma vie plus facile en démontant la structure de l'argument pour moi et l'association significative noms avec différentes parties de l'argument! \"
+
+Lorsque déstructuration un vecteur ou d'une liste, vous pouvez nommer autant d'éléments que vous voulez et aussi utiliser params repos:
+"
+
+(comment
+
+  (defn chooser
+    [[first-choice second-choice & unimportant-choices]]
+    (println (str "Your first choice is: " first-choice))
+    (println (str "Your second choice is: " second-choice))
+    (println (str "We're ignoring the rest of your choices. "
+               "Here they are in case you need to cry over them: "
+               (clojure.string/join ", " unimportant-choices))))
+  (chooser ["Marmalade", "Handsome Jack", "Pigpen", "Aquaman"])
+  ; =>
+  ; Your first choice is: Marmalade
+  ; Your second choice is: Handsome Jack
+  ; We're ignoring the rest of your choices. Here they are in case \
+  ; you need to cry over them: Pigpen, Aquaman
+
+  )
+
+"Vous pouvez aussi déstructurer maps. De la même manière que vous dites Clojure à déstructurer un vecteur ou une liste en fournissant un vecteur comme un paramètre, vous destucture maps en fournissant une carte comme un paramètre:"
+
+(comment
+
+  (defn announce-treasure-location
+    [{lat :lat lng :lng}]
+    (println (str "Treasure lat: " lat))
+    (println (str "Treasure lng: " lng)))
+  (announce-treasure-location {:lat 28.22 :lng 81.33})
+  ; =>
+  ; Treasure lat: 28.22
+  ; Treasure lng: 81.33
+  )
+
+"Regardons de plus à cette ligne:"
+
+(comment
+  [{lat :lat lng :lng}]
+
+  )
+
+"Ce est comme dire à Clojure, \"Yo Clojure me faire une flava et associer le symbole! lat avec la valeur correspondant à la clé :lat . Faites la même chose avec lng et :lng , ok ?. \"
+
+Nous voulons souvent de prendre simplement des mots-clés et de \"briser les sortir\" d'une carte, donc il ya une syntaxe plus courte pour que:"
+
+(comment
+
+  ;; Works the same as above.
+  (defn announce-treasure-location
+    [{:keys [lat lng]}]
+    (println (str "Treasure lat: " lat))
+    (println (str "Treasure lng: " lng)))
+
+  )
+
+"Vous pouvez conserver l'accès à l'argument de la carte originale en utilisant le :as mot-clé. Dans l'exemple ci-dessous, la carte originale est accessible avec treasure-location :"
+
+
+(comment
+  ;; Works the same as above.
+  (defn receive-treasure-location
+    [{:keys [lat lng] :as treasure-location}]
+    (println (str "Treasure lat: " lat))
+    (println (str "Treasure lng: " lng))
+
+    ;; One would assume that this would put in new coordinates for your ship
+    (steer-ship! treasure-location))
+
+  "En général, vous pouvez penser que la déstructuration instruire Clojure comment associer des symboles à valeurs dans une liste, carte, jeu, ou un vecteur.
+
+Maintenant, pour la partie de la fonction qui fait quelque chose: le corps de la fonction!"
+
+
+
+  )
+
+[[:subsection {:tags "corps_de_fonction" :title "Corps de fonction"}]]
+
+"Votre corps de la fonction peut contenir des formes. Clojure retourne automatiquement la dernière forme évalué:"
+
+(comment
+  (defn illustrative-function
+  []
+  (+ 1 304)
+  30
+  "joe")
+(illustrative-function)
+; => "joe"
+
+(defn number-comment
+  [x]
+  (if (> x 6)
+    "Oh my gosh! What a big number!"
+    "That number's OK, I guess"))
+
+(number-comment 5)
+; => "That number's OK, I guess"
+
+(number-comment 7)
+; => "Oh my gosh! What a big number!"
+
+)
+
+
+[[:subsection {:tags "toutes_les_fonctions_sont_crees_egaux" :title "Toutes les fonctions sont créés égaux"}]]
+
+"Une dernière remarque: dans Clojure, il n'y a pas privilégiés fonctions. + est seulement une fonction, - est juste une fonction, inc et map sont seulement fonctions. Ils ne sont pas mieux que vos fonctions! Donc, ne les laissez pas vous donner toute la lèvre.
+
+Plus important encore, ce fait permet de démontrer la simplicité sous-jacente de Clojure. D'une certaine manière, Clojure est très bête. Lorsque vous effectuez un appel de fonction, Clojure dit simplement, \" map ? Bien sûr,! Je vais juste se appliquent quel que soit ce et de progresser. \" Il ne se soucie pas ce que la fonction est ou d'où il vient, il traite toutes les fonctions de la même. À la base, Clojure ne donne pas deux hamburger retourne propos addition, multiplication, ou la cartographie. Il se soucie peu près l'application de fonctions.
+
+Comme vous programmez avec Clojure plus, vous verrez que cette simplicité est grande. Vous ne avez pas à vous inquiéter à propos de la syntaxe des règles ou spéciaux pour travailler avec des fonctions. Ils fonctionnent tous de la même chose!"
+
+[[:section {:tags "fonctions_anonymes" :title "Fonctions anonymes"}]]
+
+"Dans Clojure, vos fonctions ne ont pas à avoir des noms. En fait, vous vous retrouvez à l'aide des fonctions anonymes tout le temps. Comment mystérieuse!
+
+Il ya deux façons de créer des fonctions anonymes. La première consiste à utiliser le fn forme:
+"
+
+(comment
+
+  ;; This looks a lot like defn, doesn't it?
+  (fn [param-list]
+    function body)
+
+  ;; Example
+  (map (fn [name] (str "Hi, " name))
+    ["Darth Vader" "Mr. Magoo"])
+  ; => ("Hi, Darth Vader" "Hi, Mr. Magoo")
+
+  ;; Another example
+  ((fn [x] (* x 3)) 8)
+  ; => 24
+  )
+
+
+"Vous pouvez traiter fn presque identique à la façon dont vous traitez defn . Les listes de paramètres et les corps des fonctions fonctionnent exactement de la même chose. Vous pouvez utiliser l'argument déstructuration, repos-params, et ainsi de suite.
+Vous pouvez même associer votre fonction anonyme avec un nom, qui ne devrait pas venir comme une surprise:
+"
+
+(comment
+
+  (def my-special-multiplier (fn [x] (* x 3)))
+  (my-special-multiplier 12)
+  ; => 36
+  )
+
+
+"(Si ce ne est une surprise, alors ... surprise!)
+
+Il ya une autre façon, plus compacte pour créer des fonctions anonymes:"
+
+(comment
+
+  ;; Whoa this looks weird.
+  #(* % 3)
+
+  ;; Apply this weird looking thing
+  (#(* % 3) 8)
+  ; => 24
+
+  ;; Another example
+  (map #(str "Hi, " %)
+    ["Darth Vader" "Mr. Magoo"])
+  ; => ("Hi, Darth Vader" "Hi, Mr. Magoo")
+
+  )
+
+
+"Vous pouvez voir que ce est nettement plus compact, mais il est probablement aussi confus. Brisons le bas.
+
+Ce type de fonction anonyme ressemble beaucoup à un appel de fonction, sauf qu'il est précédé d'un dièse, # :
+
+"
+
+(comment
+
+  ;; Function call
+  (* 8 3)
+
+  ;; Anonymous function
+  #(* % 3)
+  )
+
+"Cette similitude vous permet de voir plus rapidement ce qui se passera lorsque cette fonction anonyme soit appliquée. \"Oh,\" vous pouvez dire à vous-même, \"cela va multiplier par trois son argument\".
+
+Comme vous l'aurez deviné maintenant, le signe pour cent, % , indique l'argument passé à la fonction. Si votre fonction anonyme prend plusieurs arguments, vous pouvez les distinguer comme ceci: 1% , 2% , 3% , etc. % est équivalente à 1% :"
+
+
+(comment
+  (#(str %1 " and " %2) "corn bread" "butter beans")
+  ; => "corn bread and butter beans"
+  )
+
+"Vous pouvez également passer un param de repos:"
+
+(comment
+
+  (#(identity %&) 1 "blarg" :yip)
+  ; => (1 "blarg" :yip)
+  )
+
+"La principale différence entre cette forme et fn est que cette forme peut facilement devenir illisible et est mieux utilisé pour les fonctions courts."
+
+
+[[:section {:tags "fonctions_renvoyant" :title "Fonctions renvoyant"}]]
+
+"Les fonctions peuvent renvoyer d'autres fonctions. Les fonctions sont retournés fermetures, ce qui signifie qu'ils peuvent accéder à toutes les variables qui étaient dans la portée lorsque la fonction a été créée.
+
+Voici un exemple type:"
+
+(comment
+
+  ;; inc-by is in scope, so the returned function has access to it even
+  ;; when the returned function is used outside inc-maker
+  (defn inc-maker
+    "Create a custom incrementor"
+    [inc-by]
+    #(+ % inc-by))
+
+  (def inc3 (inc-maker 3))
+
+  (inc3 7)
+  ; => 10
+  )
+
+
+"Woohoo!"
+
+[[:chapter {:tags "mise_en_commun" :title "Mise en commun"}]]


[#183] Require verbosely when running clojure tests

--- priv/examples/run_tests.clj
+++ priv/examples/run_tests.clj
@@ -23,7 +23,7 @@
                           (map (partial path->symbol root))
                           (filter (comp not ignore-nss))
                           doall)
-          _ (doseq [ns-symbol ns-symbols] (require ns-symbol))
+          _ (doseq [ns-symbol ns-symbols] (require [ns-symbol :verbose true]))
           result (apply clojure.test/run-tests ns-symbols)]
       (when (or (pos? (:error result))
                 (pos? (:fail result)))


Derp print statement

Derp print statement

--- src/ansel/server.clj
+++ src/ansel/server.clj
@@ -105,7 +105,6 @@
         (resp/redirect (str (:context req) "/image/" image-name)))))

   (GET "/album" req
-       (println (:params req))
     (render req "album-form.html" {:next (or (get-in req [:params :next])
                                              "/albums")}))


Typo fix: s/arrociative/associative/

Typo fix: s/arrociative/associative/

--- src/latte/core.clj
+++ src/latte/core.clj
@@ -471,7 +471,7 @@

   `(==> A B)` is `(Π [x A] B)` where `x` does not occur free in `B`.

-Implication is right arrociative:
+Implication is right associative:

 '(==> A B C) ≡ `(==> A (==> B C))`."
   [& arguments]


(defn fill-language-by-spec) takes an optional source-language

--- src/babel/writer.clj
+++ src/babel/writer.clj
@@ -350,9 +350,10 @@
           (fill-by-spec spec (- count 1) table source-model target-model))
         (log/debug (str "Since no more are required, not generating any for this spec."))))))

-(defn fill-language-by-spec [spec count table model & [no-older-than]]
+(defn fill-language-by-spec [spec count table model & [source-language no-older-than]]
   (let [language (:language model)
         debug (log/debug (str "fill-language-by-spec: language: " language))
+        debug (log/debug (str "fill-language-by-spec: source-language: " source-language))
         debug (log/debug (str "fill-language-by-spec: spec: " spec))
         debug (if (not (nil? no-older-than))
                 (log/debug (str "fill-language-by-spec: no-older-than:" no-older-than)))
@@ -391,8 +392,8 @@
                          count
                          (if (> current-count 0) " more")
                          " expressions for spec: " spec))
-          (populate-with-language 1 model spec)
-          (fill-language-by-spec spec (- count 1) table model))
+          (populate-with-language 1 model spec source-language)
+          (fill-language-by-spec spec (- count 1) table model source-language no-older-than))
         (log/debug (str "Since no more are required, not generating any for this spec."))))))

 ;; TODO: no-older-than is not supported yet.
@@ -480,8 +481,8 @@
 (defn process
   "Take one or more 'units' composed of a command and arguments and perform the command on the arguments. A command is one of:
     {:fill,:fill-one-language,:fill-verb}."
-  [units target-language & [no-older-than]]
-  (log/debug "Starting processing with: " (.size units) " instruction(s) for language " target-language)
+  [units source-language & [no-older-than]]
+  (log/debug "Starting processing with: " (.size units) " instruction(s) with source language " source-language)
   (let []
     (log/debug (str "Units: " (.size units)))
     (doall (map (fn [unit]
@@ -512,6 +513,7 @@
                          count
                          "expression"
                          (-> member-of-unit :fill-one-language :model)
+                         source-language
                          no-older-than)))
                     (if (:fill-verb member-of-unit)
                       (do


Add with-latest function as replacement to with-latest-from.

And mark with-latest-from function as deprecated.

--- src/beicon/core.cljc
+++ src/beicon/core.cljc
@@ -695,11 +695,21 @@
   one observable sequence by using the selector
   function only when the source observable sequence
   (the instance) produces an element."
+  {:deprecated true}
   ([other source]
    (with-latest-from vector other source))
   ([f ^Observable other ^Observable source]
    #?(:cljs (.withLatestFrom source other f)
       :clj  (.withLatestFrom source other (rxfn2 f)))))
+
+(defn with-latest
+  "Merges the specified observable sequences into
+  one observable sequence by using the selector
+  function only when the source observable sequence
+  (the instance) produces an element."
+  [f ^Observable other ^Observable source]
+  #?(:cljs (.withLatestFrom source other f)
+     :clj  (.withLatestFrom source other (rxfn2 f))))

 (defn combine-latest
   "Combines multiple Observables to create an Observable