Fork me on GitHub
soulflyer00:04:45 I use monger, does everything I need, and it has a cool homepage/user-guide.


@soulflyer as the maintainer of CongoMongo, I'd heartily recommend Monger 🙂


Monger is better documented, better maintained, has more features, tracks updates to the MongoDB Java driver better.


CongoMongo has hardly any users left -- most of them have abandoned MongoDB completely (something we are in the process of doing, slowly migrating data out of MongoDB and into MySQL/Percona mostly).


interesting, why are you guys moving away from MongoDB?


Isn’t everyone? (Only half joking)


After this, I couldn’t take mongo seriously

😮 4

“To recap: MongoDB is neither AP nor CP. The defaults can cause significant loss of acknowledged writes. The strongest consistency offered has bugs which cause false acknowledgements, and even if they’re fixed, doesn’t prevent false failures.”

seancorfield01:04:23 Lots of reasons. Performance at scale is expensive to maintain is probably the most straightforward one.


But there are lots of problems with MongoDB. I attended a lot of MongoDB Days (one day conferences) and listened to company after company talk about what it took to keep MongoDB running, the difficulties of scaling it (and, in particular, adjusting from one architecture to another).


Right now we pretty much only use it for low-traffic, deeply-structured data -- and we're planning to migrate that to MySQL/Percona too, to be honest.


We've had instance corruptions, bad failovers, inexplicable performance problems (where we've called in experts and they can't figure it out either).


I was very enamored with the promise of MongoDB early on... and at first it was wonderful to use... but then things get harder and harder. I would never recommend it to anyone at this point.


@seancorfield this is a really good feedback, thanks. we have been using mlabs since 2016 and we don’t have any problem, but now we have a requirement that we will need to host it in our infrastructure and we are a little worried about it. In our case a document database makes total sense. what would you recommend for this scenario?


@tbaldridge thank you for the link sir, i will research a little about it.

seancorfield02:04:05 We use mLabs too -- have done for years. They're really good. Much depends on your data size and performance requirements. We had 500M documents in some collections and well over 100M in a few others. We're down to just a few millions documents spread across two databases now tho'...


What sort of queries do you need to run across your documents? Is it just a few fields? Are there special operations you need to perform that MongoDB is specifically good at?


Most SQL DBs have some sort of JSON document storage now. Several support JSON queries as well. I think it really depends what you actually need to do at a "document" level rather than a "field" (or column) level.


I recently looked as postgres in relation to json, and you can even get/set/deleted fields on a stored json.


How might I go about debugging a non-terminating Clojure instance? I’ve been experiencing an issue occasionally in my project where I run lein midje, there’s an exception during the tests, and the process just hangs once it’s done with the test suite. I don’t get this issue when running the tests via the REPL with (load-facts :all). Can I interrogate the instance somehow?


jstack PID / jcmd PID Thread.print will show you stack traces of where all the threads are. i did a demo awhile back of some of these command-line jvm tools here:


@callum Does it hang for more than a full minute? There is a known issue where calling future, or one of several other Clojure functions, causes a JVM daemon thread to be created, such that it causes the process to hang for about 60 seconds before it is terminated and the process then exits. For more details, see the comments in the examples here:


what is the best clojure library for writing hadoop tasks?


Hi, how do people manage namespace collision between .clj .cljc and .cljs files in a project that uses all three? Is there an idiomatic solution?


namespace collision in what way?


Let's say I have a namespace in both the cljs and cljc source folder and want to include the cljc one in one of my cljs sources. How does the clojurescript compiler decide which namespace to include. It's the same question for clojure.


Ah, I see. Never had that issue as we usually only have one of the cases, either clj + cljs or only cljc.


@U0677JTQX I do not consider myself the final authority on this question, but I believe that the design decision when cljc was added to Clojure/JVM was that if there is a .clj file for a namespace, anywhere in your Java classpath, and also a .cljc file for the same namespace anywhere in your classpath, the .clj file will be found and loaded in preference to the .cljc file.


If that is still the case (and I believe it is), then I don't see a very good way for a .cljc file to use a .clj file for the same namespace. For different namespaces, no problem.


If that design decision was also used in cljs, then there is likely no way to do what you are asking, and you should probably avoid trying to do that.


Thank you very much, that's basically what I assumed. My solution is to add a cljc package to the cljc namespace.


It's just good to know.


I have a legacy Java app. I have started a tools.nrepl from it. I can connect to this nrepl from Emacs. Now, I also need a way to handle dependencies. Is there a wa yto load boot as a LIBRARY in this nrepl, so I can use boot to handle my dependencies ?


@qqq maybe ask in #boot as well


Let's say I have a namespace in both the cljs and cljc source folder and want to include the cljc one in one of my cljs sources. How does the clojurescript compiler decide which namespace to include. It's the same question for clojure.


Is specter the most scalable way to handle manipulating nested objects. For example in quil my state for now has one entity, and this is how the update looks like.

(defn update-scene [state]
  (let [star (:star state)
        moved-star (move-star star)]
    (if (hit-bounds? moved-star field-size)
      (let [star-reversed (update moved-star :vec (partial map -))]
        (assoc state :star star-reversed))
      (assoc state :star moved-star))))
It looks very messy after all is said and done and eventually there's going to be different types and multiple manipulations/checks/etc. Is there something more scalable than doing it like this? I've only heard of specter but wondering if there is something else (tool or strategy) more suited for this kind of task


You can rewrite that to be more readable:

(defn update-scene [state]
  (update state :star
          (fn [star]
            (let [s (move-star star)]
              (if (hit-bounds? s field-size)
                (update s :vec (partial map -))


or even

(defn update-scene [state]
  (update state :star
          (fn [star]
            (let [s (move-star star)]
              (cond-> s
                (hit-bounds? s field-size)
                (update :vec (partial map -)))))))


or even

(defn check-hit [s]
  (cond-> s
    (hit-bounds? s field-size)
    (update :vec (partial map -))))

(defn update-scene [state]
  (update state :star (comp check-hit move-star)))


sky's the limit 🙂

🎆 4

@theeternalpulse Your update-scene function could then become something like this when you have more entities:

(defn update-scene [state]
  (-> state
      (update :star (comp check-hit move-star))
      (update :some-other-thing other-thing-fn)
      (update :yet-another-thing .....

👍 8

am I imaging this or is clojure 1.9 significantly faster, both in startup and runtime, than 1.8? I just upgraded and things feel quite different


@theeternalpulse with specter that's:

    (terminal move-star)
    [#(hit-bounds? % field-size) :vec ALL (terminal -)])

👍 8

oh thanks for the suggestions.


also doesn't convert that field :vec into a lazy sequence


does specter handle conditional updates or you have to do that before you initiate a transform?


yes, that code is doing a conditional update


a function inside a path stops navigation unless it resolves to truthy


that specter snippet is nice!


impressive stuff


Interesting, I have to look over the specter api. Also I just realized you're the creator lol.


there's a handy cheat sheet now so you can see the different kinds of navigators that come with specter


sweet, thanks for the suggestions @nathan @curlyfry @pesterhazy


The doc string for alts! says "ports is a vector of channel endpoints, which can be ... a vector of [channel-to-put-to val-to-put]" and "Returns [val port] of the completed operation", but in the case of a [ch val-to-put] it appears provide only the channel as port, not the [ch val-to-put] pair. It seems to be the doc string is incorrect or at least misleading. Thoughts?


what version of core.async? I've some code that does alts! with puts and takes and immediately destructures the results as [val ch], and it has never thrown an error because it couldn't destructure the value


Clojure 1.9.0
user=> (require '[clojure.core.async :as async])
user=> (async/<!! (async/go (async/alts! [[(async/chan 1) 1]])))
[true #object[clojure.core.async.impl.channels.ManyToManyChannel 0x45ac973 "clojure.core.async.impl.channels.ManyToManyChannel@45ac973"]]


yeah, that's not the bit I'm talking about. I'm sorry, it's subtle and confusing. I'm referring to the port bit of the return pair -- is it a port or a channel?


looks like the channel to me, and the code I have after the destructure does a cond comparing the returned channel with the passed in channel using =


right, that matches my experience. So I would expect the docstring to say "Returns [val chan] ..." but it actually says "Returns [val port] ...". So that's incorrect, right?


well a channel is a port


the docstrings for >! and <! also refer to ports


so what is [channel-to-put-to val-to-put]? From earlier in the docstring, I thought that was a port.


uh, it is a pair of the channel(port) you want to maybe put to, and the value you maybe want to put to it


right, so is that pair a "port" or a "channel"?


a channel is a port


ok, so that pair is neither of those things and yet is supposed to be supplied as an item in the parameter named ports


there are two protocols ReadPort and WritePort, and channels implement both


how can I inspect an existing clojure type? say I want a list of all functions that can work on a type?


so a channel is both a read port and write port, I think the docstrings refer to ports when they mean it only uses the channel as either a read port or a write port (confusingly without specifying which)


I usually just completely ignore the notion of "ports" because while it is sort of a thing, I think it is far more of a thing in the heads of the authors of the library than it is in the actual library


so every channel satisfies both ReadPort and WritePort (so it is a port), it is possible that a "port" if you ever come across one only satisfies one of those, so they are not entirely synonyms, but in practice they are


there is a #core-async channel too btw


@veix.q5: you can use clojure.reflect to see all of a thing's methods, or supers to see everything it implements


that said, many clojure functions accept anything that seq works on (which includes things like String where nothing about String itself would tell you seq would work)