Fork me on GitHub
Marc Rios09:12:06

Hello, are there any good resources out there on how I can use Clojure with MongoDB? I've done some searches but I haven't found any tutorials or extended examples. All help is greatly appreciated!


Hi marc, my search retrieves me monger, the first result in google for clojure mongodb. Isn't it ok for you?


In my experience, the easiest way to use a library is to find a clojurian who did already the wrapper

Marc Rios09:12:33

Hello Caumond, thank you for your reply. I'm new to Clojure and MongoDB, so I was hoping to find something like a TODO app tutorial. If there isn't something like that, I'll just read the Monger documentation carefully and puzzle it all out.


no pb, I'm new too.


The monger seems to be a good starting point to experiment mongo in clojure

Marc Rios09:12:26

Hi Caumond. Thank you. I'll take a look at those right now.


As a beginner too, I'm never trying to call directly a java function without that kind of wrapper. It is always possible, but never completely natural.


Thx to you, I'll have a try too during holidays,

Marc Rios09:12:59

I have no Java experience but I've done a lot of Lisp programming, so I try my best to avoid the Java classes 🙂

Marc Rios09:12:06

But sometimes they're very convenient.

👍 3

one of the clojure super power: small community but huge number of libraries

Marc Rios10:12:53

Monger is working well enough right now. It's simpler than it looks.

David Pham10:12:54

What is your strategy for selecting your libraries when going for native vs clojure version? I use a popularity metrics for making my decision, I focus on how much documentation a library possess to make my choice, if I can understand the test cases and quickly skim on the source code. The consequence is I usually prefer to keep my own thin wrapper on top of native libraries. Am I doing something wrong?


hi david, personally, I don't have a strong strategy.... Having a look to issues number, latest commit, quality of "getting started". And I was about to complement my decision with a question on this slack, (;p


Is a higher issue number better or worse?


More issues can mean: people want more features


but it can also mean: has a lot of bugs... imo it's only an indicator of how invested people are to make issues


I mean open issues, and the delay for solving them


Even that isn't really a good indicator. E.g. I have made a lot of open issues in clj-kondo, but most of them are not bugs, just future plans


if there are many people refering the lib, many issues at the beginning and few now, quickly solved, so I'm reassured


it's true some libs are selecting precisely issues vs enhancements and some are not


I was not speaking of a mathematical indicator by the way, when I'm looking at the library I'm reading the issues to check what kind of issues there are: bugs vs information request or noob questions or enhancement...


makes sense


@UEQGQ6XH7 I don't think there's a clear cut answer to your original question. I know some Clojurians who will always use a wrapper library rather than raw (Java) interop and I also know some Clojurians who say "Clojure is a hosted language" and fully embrace using the underlying native libraries via interop with no wrapper.


For me, a wrapper is worthwhile if it enables substantially simpler code than interop. I think things like and clj-time etc are worth using since they provide a simpler, more consistent API. Even so, simple time operations can be done very easily with interop and Java Time directly so you can get a long way before the time wrappers are really beneficial.

Aviv Kotek12:12:58

hey! using cognitent-aws-api, i'm failing to retrieve ec2 instances with aws-filter (simple filter by tag): my EC2 instances contain tag-key "name" (def ec2 (aws/client {:api :ec2})) (aws/invoke ec2 {:op :DescribeInstances :Filters [{:Name "tag:Name" :Values ["test"]}]}) would return every existing instance and not the filtered one, doc: (aws/doc ec2 :DescribeInstances) => {:Filters [:seq-of {:Name string, :Values [:seq-of string]}], ....} what am I missing here? ty!


all APIs take :op and :request, so your example should be: {:op :DescribeInstances :request {:Filters ...}}

🙏 3

Hi, I have two strings “abc” and “ABC” and I would like to get pairs using list comprehension this way “aA” “bB” “cC”. Is there an example? Thanks


sorry, (map str "abc" "ABC") should make it


Yep! If you want pairs from multiple sequences you map over the sequences. If you want all possible combinations of sequences you for

🙌 3

do not try - Yoda


do or do not there is no try


What is the trick to write a unit test that checks if a macro generates the correct code?


@st3fan Use macroexpand on the quoted form of the macro invocation?


Hello, it's my first time messing with atoms and concurrency! I've got this atom called collision-holder, that for testing purposes only holds {:type ""} I've also got this function called collision-type that reads a file line by line to determine what kind of collision is going on in each line (I'm processing some simulation data) The function itself works well, I've tested it with println before moving to the concurrency part collision-type swap!s collision-holder using assoc I am trying to print the value of collision-holder every second rather than every iteration of the collision-type loop using print-collision :

(defn print-collision
  (dotimes [_ 9]
    (doto (Thread. (collision-type)) ;; function that modifies the value of collision-holder 
  (doto (Thread. (fn []
                   (Thread/sleep 1000) ;; sleep for 1 second
                   (println (:type @collision-holder))))
But it never gets to the printing function, though it does evaluate collision-type I'm guessing that it's waiting for a return value from collision-type, but it won't get there since I'm processing a very large file, which it will take at least 2 hours to completely process Does anyone know how to make this work?


@ricardolopez.zagal Can you share an outline of what collision-type does? When invoked, do it read one line or multiple lines?


@ricardolopez.zagal Ah, I think the problem is (Thread. (collision-type)) -- Thread expects a function and you're passing in whatever (collision-type)) returns.


@seancorfield Ah, I see... Yeah, the only thing it will ever return is nil


(Thread. collision-type) is probably what you want, if (defn collision-type [] ...)


I ran your code with a mocked up collision-type function and got exceptions printed from the attempts to start a thread that did not have a function passed to the constructor.


@seancorfield That makes sense I could show you what collision-type looks like, but in short, it's a (loop [...] ... (recur ...)) with a few conds inside that determine what the type the collision actually is. The function modifies the value of collision-holder every iteration, but it only returns a value (`nil`) when the function is done with reading the file


It got fixed when passing the code as a fn. Thank you very much!