Fork me on GitHub

What the best way design clj fn that eliminates state ( like config\db connection etc)


• IO boundaries with pure functions underneath • binding dynamic vars • Closures over db connections


@lsenjov can you give some example ( binding and closure over DB), thx


Binding lets you bind a dynamic variable. It’s technically still stateful but it’s convenience for things like db connections/configs for examples


IIRC binding also carries down the stack, not just in the function it’s called


Closures over connections is probably not for this, but it’s passing down an initialised function/class down the stack for usage as an argument

(let-fn [db (init-db {:connstring "asdf"})]
 (do-things-with-db db))


Also check out the mount library for handling state like this

Stas Makarov11:07:34

Hi! How can I make these functions prettier?

(defn add-days
  ;; Adds number of days to the js date object.
  ;; Months will roll over (  )
  [date days]
  (let [copy (js/Date. (js/Number date))]
    (. copy setDate (+ (. copy getDate) days))

(defn today []
  (let [now (js/Date.)]
    (. now setHours 0 0 0 0)


you should probably use doto

Stas Makarov17:07:32

Thanks! I think it looks better now, but probably there's a room for improvement still..

(defn today []
  (doto (js/Date.) (. setHours 0 0 0 0)))

(defn add-days
  ;; Adds number of days to the js date object.
  ;; Months will roll over (  )
  [date days]
  (let [copy (js/Date. (js/Number date))
        val (+ days (. copy getDate))]
    (doto copy (. setDate val))))


(doto (js/Date. date) (.setDate (+ days (.getDate date))) ?


Hi, someone can help me? I have this object

#object[Transit$TaggedValue [TaggedValue: f, 100.0]]
And I want to convert to number 100.0 I don't know how do it. in the frontend it shows [TaggedValue: f, 100.0]


I try use [cognitect.transit :as t]

Aviv Kotek14:07:59

hey, for simple XML creation/parsing, what is the differences between clojure.xml and, I see data.xml has more features, why having both libs?

Alex Miller (Clojure team)14:07:22

clojure.xml is a very old stab from early in the Clojure language and should be considered deprecated at this point

🙏 3
Aviv Kotek14:07:15

hi Alex, how would you traverse such structure? (data.xml.Element), I'd like some easy traversal like in, basically to parse an XML input

Alex Miller (Clojure team)14:07:07

you can use

Aviv Kotek08:07:38

so basically why would I need the data.xml, if I anyway move my data-structure to a zipper? why not just load directly to zipper or build a zipper? I mean, instead of String->data.xml->zipper and opposite why not just String->zipper, without using data.xml,

Aviv Kotek08:07:49

what is the usage of data.xml that I don't have with, thanks!

Alex Miller (Clojure team)14:07:48

we have not removed it so as not to break any existing code (have not yet gotten around to marking it deprecated but we will)

Alex Miller (Clojure team)14:07:00

so, use


Is there a way to dynamically start/stop and add/remove components using Stuart Sierra component library? All examples i've seen are pretty static


if you hold the component system in a var, you can stop it (or stop parts of it) whenever

Aviv Kotek14:07:30

thanks alex!


@dobbey.have.socks It's complicated in general because start / stop return a new instance of the component so you would have to rebuild the entire system. Adding and components dynamically is possible (before you start the system -- for the same reason as stated): you just assoc them in, but again that returns a new instance of the system.


(there's a #component channel if you want to dig deeper)


Quick question, I found a filter function online that helps me filter my xml-seq into the correct filter, however don’t know how it ‘works’

(def navPoints
  (->> document
       (filter (comp #{:navPoint} :tag))))
In my understanding, this would mean (from Clojure book):
((comp f1 f2 f3) x) is equivalent to (f1 (f2 (f3 x)))
but then when i ‘decomp’ this, i can’t seem to make it work:
(filter #({:navPoint (:tag %)}))
What am I missing?


^ this returns an error btw


i get that #{} is a set with unique values


but guess i don’t understand comp that well


i also tried:

(filter #(#{:navPoint (:tag %)}))
which fails as well


using map I can recreate what I am looking for after some struggling:

(map #{:navPoint} (map :tag a))
but don’t understand why without #{} won’t work:
(map :navPoint (map :tag a))
it will return: (nil nil nil nil nil nil nil nil nil nil)


The filter is using #{:navPoint} as a predicate, which is something you can do with sets that's pretty cool.

(#{:foo :bar} :foo)
=> :foo
(#{:foo :bar} :foo2)
=> nil


So (map #{:navPoint} [:wayPoint :navPoint :someOtherPoint]) will apply the #{:navPoint} test to each of the three keywords in the vector, and will return (nil :navPoint nil)


In other words, a set is a set, but in Clojure it also works like a function that takes one argument. If the argument is an element in the set, return it, otherwise return nil.


It's a bit of syntactic sugar because it supports a very useful idiom.


thanks for the explenation


do you also happen to know the ‘decomp’ of this for my understanding:

(filter (comp #{:navPoint} :tag))


i know that just doing

(filter :tag)
works by filtering on only parts of the xml that have the :tag


but then how do you add the next part of #{:navPoint} ?


(comp #{:x} :a) returns :x for {:a :x} and nil for anything that doesn't have that k/v pair


that explains why the filter seems to work on the data set


how would you write this decomposed?


just for my learning and understanding of comp


(fn [el] (#{:a} (:x el)))


or (fn [el] (let [x (:x el)] (get #{:a} x))


awesome, thanks


i can confirm this works:

(def navPoints
  (->> document
    ;    (filter (comp #{:navPoint} :tag))))
       (filter (fn [el] (#{:navLabel} (:tag el))))))


knowing that el is the input argument to the function


and that this will also work:

(def navPoints
  (->> document
    ;    (filter (comp #{:navPoint} :tag))))
       (filter #((#{:navLabel} (:tag %))))))


but seems less readable ha


yeah - some people like "point free" style (which is the term to google if you want to know more about why people use comp / partial / apply / juxt etc. so much)


the argument being that not having to give names to intermediate things clarifies the code (which is true unless you have never written point free code)


thanks i will research that


i really want to learn Clojure but seem to get hung up on what should be trivial things like parsing a Json or Xml


as a social signifier, point free sometimes says "I need to write code but would rather be doing math" haha


but in all seriousness, its elegant once you learn it, and totally mind bending before that


but in all seriousness, its elegant once you learn it, and totally mind bending before that
yeah that is exactly my problem 😅


i’m doing all kinds of exercises with comp, partial, apply


(and the convention of using hash-maps and sets as if they were functions comes directly from the most commonly used mathematical definition of function btw)


and then i work on the XML i’m trying to parse/filter now and see this solution online and go.. huh!!?


Trying to understand why the simplest clj app(generated via lein new app luminusdiff) works fine locally:

~  luminusdiff  cat project.clj
(defproject luminusdiff "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url ""
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url ""}
  :dependencies [[org.clojure/clojure "1.10.1"]]
  :main ^:skip-aot luminusdiff.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all
                       :jvm-opts [""]}})
~  luminusdiff  cat src/luminusdiff/core.clj
(ns luminusdiff.core

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!"))
~  luminusdiff  lein run -m luminusdiff.core
Hello, World!
And fails on CI/Github Action:
Run lein run -m luminusdiff.core
Retrieving nrepl/nrepl/0.7.0/nrepl-0.7.0.pom from clojars
Retrieving clojure-complete/clojure-complete/0.2.5/clojure-complete-0.2.5.pom from clojars
Retrieving nrepl/nrepl/0.7.0/nrepl-0.7.0.jar from clojars
Retrieving clojure-complete/clojure-complete/0.2.5/clojure-complete-0.2.5.jar from clojars
Can't find 'luminusdiff.core' as .class or .clj for lein run: please check the spelling. Could not locate luminusdiff/core__init.class, luminusdiff/core.clj or luminusdiff/core.cljc on classpath.
 at clojure.lang.RT.load (
    clojure.lang.RT.load (

Github/CI env:
JAVA_HOME_8.0.262_x64: /opt/hostedtoolcache/jdk/8.0.262/x64
JAVA_HOME: /opt/hostedtoolcache/jdk/8.0.262/x64
JAVA_HOME_8_0_262_X64: /opt/hostedtoolcache/jdk/8.0.262/x64
CLOJURE_INSTALL_DIR: /opt/hostedtoolcache/ClojureToolsDeps/1.10.1-469/x64/lib/clojure
Perhaps somebody have an idea on what might be causing it?


are you sure that lein is being run inside the right directory?

👍 3

@nfedyashev Most likely you're not running lein run in the corre... yeah, what @noisesmith said 🙂


those deps it downloaded are its own deps, you should have seen your deps download if you had any :D


(there were no deps aside from Clojure listed in project.clj)

😸 3