Fork me on GitHub

but spec isn't a type system. we have types but we don't have a type system


hmm... maybe I'm wrong about that. It's not static typing but maybe it counts as some kind of type system.


anyway, what people are generally talking about when they talk about typesystems, and what clojure lacks even with spec, is static type checking


Yes, not a type system in the traditional sense, but given that one could def, for example, what the arguments of a function are expected to look like, it serves a similar purpose, no? Perhaps I can go about this question in another way, when experienced Clojure developers see spec, how do they anticipate incorporating it into their code? Each developer will likely have a different answer, but curious on what excites people about this in general.


newbie question: how can I assoc new items into an atom?


(swap! a assoc :k v :k2 v2 ...)


or for deeper updates (swap! a assoc-in [:k :l :m] v)


thank you @noisesmith! it was the assoc-ini I was forgetting.


I just devised a nice way to send users updates for only the thing they're looking at. by keeping track of what tag they're viewing in an atom that holds all the user-ids , the swap! is instrumental


well, more like :tag [user ids] to be clear ...


Hmmm, I want to add to a vector though, not just have one user-id per tag


append instead of overwrite scrambles to clojuredocs


then (swap! a update :tag conj uid)


but if you also remove uids from tags, it makes more sense to use a set


Tell me more about sets


(defn add-id [a tag id] (swap! a update tag (fnil conj #{}) id)) (defn remove-id [a tag id] (swap! a update tag disj id))


with sets you can call disj to remove a single element by value


oh awesome. that's exactly what I was looking for


and to check for membership, you can either use the set as a function, or use contains?


(fnil ) is new to me


seems very useful and flexible .


Clojure 1.9.0
+user=> ((fnil conj #{}) nil 1)
+user=> ((fnil conj #{}) #{2} 1)
#{1 2}
+user=> ((fnil conj #{}) [] 1)


yes, fnil and update are a useful combination


so in the example above, is a an (atom #{} )


it's (atom {}) - wouldn't really work the same if the atom was a set


Oh right, but each tag within it has a val that is represented by a set


the code is much simpler if the atom is a set, just (swap! a conj x) or (swap! a disj x)


Do you think it makes more sense to create a bunch of atoms, one for each keyword I have, and use the simplified code to add/remove uids that are viewing that tag, or try and mash them all into one tag-viewers atom?


the problem with multiple atoms is it makes adding tags at runtime awkward


Ah yeah that makes sense.


if that's something you'll never need, I guess you could consider it - but I think having one item with all the tags as keys in a hashmap would be easier


Hashmap. Have yet to use one in clojure.


wait isn't a normal map in clojure a hash map?


yes - I prefer the term hashmap because we have the function map which is totally unrelated


it means the same thing


Ah, thanks for the clarification.


Yes, one atom with many tags as Keys and vectors of connected user-ids as vals


I mean on an abstract mathematical level both a hashmap and the map function describe a set of relations from one set of values to another, where each item in the first set maps to exactly one item in the second set


but that's not the level we code on, that's just a formalism 😄


Right! i am not a run-time compiler that cannot tell the difference haha


Okay I have a question. ( add-id [atom tag id) makes sense


when a user disconnects, I don't really have the pleasure of knowing which tag they were looking at, I just know they disconnected and their id


how can I get rid of every instance of their Id in the map


oh - that's trickier isn't it


you could use (swap! a #(into {} (map (fn [[k v]] [k (disj v id)])) %))


beautiful. could you give me some commentary on what that is doing?


into takes three args here - a collection {}, a transducer (map ...) and the original


it uses the transducer on each item in the original collection to generate the value to put in the result


it's very similar to calling map on the hash-map and then putting the result into a new hash-map, but unlike using map that way it doesn't need to make a lazy-seq


+user=> (into #{} (map inc) #{1 2 3 4})
#{4 3 2 5}


+user=> (into #{} (comp (map inc) (filter even?)) #{1 2 3 4})
#{4 2}


so for the line (swap! a #(into {} (map (fn [[k v]] [k (disj v id)])) %)) i can just supply id and the rest is known


that's awesome and groovy.


clojure has some nice ways to work with data, once you get into the flow it can be addictive


i noticed you used (comp) in the one


yeah - it was to show how you can combine transducing functions (and subtly it shows that they compose differently than normal function application because ... reasons)


cool. that was a fairly painless introduction into transducers ^.^


Dude thanks so much


Now I just have to make sure every connected user gets a default id of some sort instead of nil


Hi, I am calling a function from a clojure library which in turn calls a java method from a java library. The problem is instead of getting the result I get a #object[.... , how I instead get the actual result? So a bit more details: In the beginning of the file I do a (:require qbits.alia.timestamp-generator :refer :all), then I run (atomic-monotonic), and I get: #object[com.datastax.driver.core.AtomicMonotonicTimestampGenerator 0x6ba19932 com.datastax.driver.core.AtomicMonotonicTimestampGenerator@6ba19932], the library function is this:


It worked! Thank you very much! @ghsgd2

New To Clojure14:12:55

Is there do..while loop in Clojure?

do {
  n *= counter--;
} while (counter > 0);


I’d use looprecur for that, assuming there wasn’t a more functional alternative that eliminated the loop completely


This seems to compute something like n*(counter!), have a look at

New To Clojure14:12:44

@manutter51, @pcbalodi, @ralf Thank you! @pcbalodi I need to do check after executing body, not before so it's not exactly while.


There's probably a nicer, functional way of doing what you want without an explicit loop. But do-while is an easy macro to write.


(defmacro do-while [test & body]
  '(loop []
     (when ~test


Wow, jinxed

New To Clojure15:12:01


CompilerException java.lang.RuntimeException: Unable to resolve symbol: body in this context


@ghsgd2 I don’t think there are any built-in constructs, but this answer on SO suggests (

(defmacro do-while
  [test & body]
  `(loop []
     (when ~test


which is very similar to the actual while macro


(while (do body condition))

New To Clojure15:12:52

@leonoel Useful, but I need to return result value (body). I'm using this hack currently:

(letfn [(body [] body-expr)]
    (loop [result (body)]
        (if (not condition)
            (recur (body)))))


u can do something like this -

(-> (repeatedly body)
      (drop-while condition)


but I am not sure if this is the idiomatic way to do this


Is there an accepted way to handle errors from network requests in the context of an application (I don’t mean at the function level). Is it “better” to throw an exception and let it propagate up the call stack, have each function catch/throw independently, return error maps (`{:error :not-found}`) and then check them in the calling function, or something else entirely?


exceptions are ok with some principles around them


they are a way of life in java and you don't make a top-level scope aware of specific low-level exception types... Generally catch your exceptions as close to the source as possible and transform your exceptions to error values


using an ordinary map or a data-bearing exception ex-info


this is a really good question


Exceptions aren't huge in the clojure space like in python, but are just a fact of life because JVM


Whoops sorry I didn’t see this earlier - thanks for the response!


“Generally catch your exceptions as close to the source as possible and transform your exceptions to error values” effectively gets to the heart of what I was asking. Thank you.


To confirm, does that mean a lot of your code ends up looking something like this?

(let [result (make-api-call "/users")]
  (if (:error result)
    (response/ok result)))


I would like to know more about this as well, as of now, I let all exceptions be thrown in the "inner layer" of the code (ex. code that send HTTP request, database query, etc). Leaving it to the "outer layer" to catch it (in this case a ring middleware) and compose an error response. Is there a downside to this? I've found that it makes things easier to me, as I don't have to make try catch block in each function that can throw an exception. But I'm not sure if it will ultimately become a nuisance or potentially even a problem in the future.

New To Clojure20:12:09

Have unusual issue. The same code returns correct result when run under CIDER debug but returns just [] when run without debug. Code:


@ghsgd2 there’s a few problems with that code, but the main issue is that for is lazy and does nothing if nothing consumes the lazy-seq it generates. When you have debugging on the debugger consumes the values for is generating, so it accidentally works.


you can fix the immediate problem by replacing for with doseq, it’s the same syntax but actually does the thing you want

New To Clojure20:12:57

@noisesmith Got it! Guess the other issue it's non-tail recursion which could overflow stack. But that's only the 1st version of code. Thank you very much, @noisesmith!


that’s one issue, another one is that the usage of a mutable state here is gratuitous, and that definitions in that order don’t actually compile the first time because you can’t use forward-references


also, as a minor thing, #(conj % %2) can always be replaced with conj


there's a race condition in it


the debugger makes one runner of the race always win


where is the race?


I don’t see anywhere a second thread would be introduced


oh - the deref could happen before the swap! completes right


nevermind. i was thinking that it would immediately return the @result without "waiting" for the other function to complete

New To Clojure20:12:42

@noisesmith >the usage of a mutable state here is gratuitous Going to replace with volatile >definitions in that order don’t actually compile the first time Yeah, will use declare. That's because I develop mostly in REPL. >`#(conj % %2)` can always be replaced with conj Indeed, haven't noticed.


yeah, it always waits for swap! - there’s no way for it to go out of sync


even when those are "done" inside of a for loop?


@ghsgd2 volatile is still mutable, it’s just faster


@dpsutton there’s no such thing as a for loop, for is a comprehension, and it never uses a new thread


either the for executes and the swap! is waited for, or it doesn’t execute and there’s no swap! to wait for


well you could make it happen in another thread, but it won’t make a new thread on its own behalf


(defn flatten-1
  [items result]
  (for [element items]
    (if (sequential? element)
      (flatten-1 element result)
        (prn "i'm doing something")
        (swap! result #(conj % %2) element)))))


when you call the original flatten you never see the "i'm doing something".


but i'm conflating race and lazy and i think you already pointed this out didn't you


yes - laziness is thread safe, the error here is expecting anything lazy to happen for side effects

New To Clojure20:12:16

That's better version. But it looks like cheating because postwalk does all heavy-lifting (and also there's postwalk default result sequence which is ignored but still consumes memory during computation). I wonder how it's implemented but I'll keep inventing my own versions for now.

(defn flatten
  (let [result (volatile! [])]
    (clojure.walk/postwalk (fn [x]
                             (if (not (sequential? x))
                               (vswap! result conj x)))


that will act weird if you have sets or hash-maps in the input


you can use tree-seq and filter to do this without mutation and avoid odd behaviors with nested non-sequential data (if you pick the right predicate on tree-seq)

New To Clojure20:12:26

@noisesmith (tree-seq branch? children root) tree-seq needs root. I have none.


“root” is just your input


branch? is a query that decides if you can go deeper, children turns the tree into something you can recurse on, and root is the current input


so (tree-seq sequential? seq elements)

New To Clojure21:12:59

@noisesmith It could be updated to handle sets and maps as well

(fn [x] ;; postwalk 1st arg
    (if (not (or (sequential? x) (set? x) (map? x)))
        (vswap! result conj x)))
And then all numbers and keys will be returned in one vector. With your advice (maps actually are ignored but that's not an issue here):
user> (filter #(not (or (sequential? %) (set? %) (map? %))) (for [elt (tree-seq sequential? seq [1 [2 [[3]] [4 [[5]]] 6 7] 8 {:key 9} ])] elt))

(1 2 3 4 5 6 7 8)


you don’t need for here


and you can use (complement coll?) or #(not (coll? %)) as a predicate to filter


or better yet use remove coll?


@ghsgd2 the reason I say you don’t need for (for [x coll] x) is just (seq x)


and your tree-seq is already calling seq, so you don’t need that explicitly either


which leaves us with (remove coll? (tree-seq coll? seq input))


(if you want that 9 from inside the hash-map that is)


if you don’t want the 9, (remove coll? (tree-seq sequential? seq input))

New To Clojure21:12:32

@noisesmith Impressive! 🙂 The only caveat here it's that tree-seq uses non-tail recursion inside so it will overflow stack on big trees.


yes, everything that consumes trees including post-walk does that


for clojure built ins at least


you can move the stack usage into heap usage but you end up with slower code on the normal case, and more complex code to boot (basically using continuations on the heap instead of stack data)


@ghsgd2 also I think the fact that the self-calls are wrapped in lazy-seq means that this already happens with tree-seq, because lazy-seq lifts the continuation into a function on the heap internally


I’d need to double check that claim though


yes, checking the source - postwalk isn’t lazy, so it will overflow with large inputs, but tree-seq is creating a lazy-seq at each step so if consumed properly won’t overflow


the embedded mapcat may or may not risk a concat-bomb for very large inputs though…

New To Clojure21:12:22

Thank you very much, @noisesmith! Good to know how it works.


it always feels nice to replace many lines of mutating code with a small one liner

New To Clojure21:12:45

Is it a good idea to use at all? Considering what's written in


What are you trying to do with them? I think there's often abstractions built on top of them that can be used directly.


For understanding, I found the videos at really valuable to help me start figuring them out

New To Clojure21:12:49

@U054BUGT4 In this case I'm exploring what Clojure has to be prepared for upcoming tasks (I'm solving tasks at

New To Clojure21:12:08

Thank you a lot!


Personally, I wouldn't focus too much on zippers until you have a need for them (or just get the basic understanding and move on). There are pretty useful things that you can do with them though, I just haven't found it to be that common for me to need them directly.


considering other things zacaudate has said publicly I would seek a second opinion in general


(I’m not familiar with that article though)


I tried zippers a couple of time and I find them very hard to use

New To Clojure21:12:04

he said that if there's a tree [[1 2 3] []] zipper can't put cursor into 2nd empty list to add some elements

New To Clojure21:12:20

because cursor sticks to elements

New To Clojure21:12:32

not to positions inside tree


to me zippers are an overly complicated way to do things in order to remain functional, but since clojure has mutability, we can use that instead


but try them out and see if they work for you 🙂

Drew Verlee21:12:23

When dealing with very data driven basis, how does on go about understanding there options? Like, if I'm too pass a function a map, how do you know the options for that map? I guess the ideal thing is a spec or schema right?


schema spec


his argument is

1. Lack of guard rails - nil punning for most movements out of the zipper as well as using :end as end.
2. Viewing the cursor as 'on an object in the tree' as opposed to 'within the tree'.


Hey there. I have a newbie question that I’d love some help with: what’s the best idiomatic way to instantiate a Java class with a default constructor, and then invoke one of its methods? I’d like to use a method from the Apache Commons Math library as the first argument to the map function, but it’s not static, so I have to instantiate the class first. Just wondering how best to do this.


This may not be the best way but it's what I've picked up trying to answer the same question (these are from recent interop code) For functions that return a value,

(-> (ReportClientDocument.)
should create a new ReportClientDocument, call the getDatabaseController function, and return the result of that method call. To update the instance and return it,
(doto (ReportClientDocument.)
    (.setReportAppServer ReportClientDocument/inprocConnectionString))
should create a ReportClientDocument, call setReportAppServer, and return the updated instance.


You can also do

(def my-report (ReportClientDocument.))
or equivalent and use it from there


(If I want to do this, I also have to wrap the Java method invocation in a lambda, right?)


You might also try something like:

(defn my-fn [xs]
  (let [inst (Math/Whatever.)]
    (map #(.method inst %1) xs)))