#clojure logs

2015-04-04

02:46justin_smithtolstoy: you don't need to .stop the server if you pass it var-quoted (run-server #'my-routes {:port 8001})
02:46justin_smiththat way if you redefine my-routes, the new def is used
03:12tsdhHow do I specify a java.util.Comparator in Clojure which can be refered to with clojure.api from the Java side (and cast there to Comparator<Object>)?
03:13tsdhI have already a function with args [a b] which returns 0/pos/neg as required for comparators.
03:13justin_smithtsdh: reify java.util.Comparator
03:13tsdhjustin_smith: Ah, ok.
03:14justin_smithand use the code for that function, or the function itself, in the compare method
03:15amalloyjustin_smith: functions implement Comparator
03:15justin_smithamalloy: oh, wow, I had no idea
03:15justin_smitheven better :)
03:15justin_smith(inc amalloy)
03:15lazybot⇒ 252
03:15justin_smithactually, you have probably mentioned this before, but I forgot
03:15amalloyprobably
03:19TEttinger,(def people (doto (ArrayList.) (.add "Mike") (.add "Jim") (.add "Bob")))
03:19clojurebot#error{:cause "Unable to resolve classname: ArrayList", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.IllegalArgumentException: Unable to resolve classname: ArrayList, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6732]} {:type java.lang.IllegalArgumentException, :message "Unable to resolve classname: ArrayList", :at [clojure.lan...
03:19TEttinger,(def people (doto (java.util.ArrayList.) (.add "Mike") (.add "Jim") (.add "Bob")))
03:19clojurebot#'sandbox/people
03:20amalloyTEttinger: (ArrayList. ["Mike" "jim" "Bob"])
03:20TEttinger,(Collections/sort people #(> (.length %1) (.length %2)))
03:20clojurebot#error{:cause "No such namespace: Collections", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: No such namespace: Collections, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "No such namespace: Collections", :at [clojure.lang.Util runtimeException "Util.java" 221]}],...
03:20TEttinger,(java.util.Collections/sort people #(> (.length %1) (.length %2)))
03:20clojurebotnil
03:21TEttinger,(vec people)
03:21clojurebot["Mike" "Jim" "Bob"]
03:21amalloyTEttinger: that doesn't look like a correct comparator
03:21justin_smithit should return an integer, right?
03:21amalloyyes
03:21justin_smithneg, zero, or pos
03:21TEttingeryep, I have never used comparators :|
03:21amalloyjustin_smith: though of course ##(doc comparator) exists
03:21lazybot⇒ "([pred]); Returns an implementation of java.util.Comparator based upon pred."
03:22amalloyto convert a predicate to a comparator
03:22tsdhamalloy, justin_smith: No matter if with plain function or reified comparator, I get "clojure.lang.Var cannot be cast to java.util.Comparator" on the java side.
03:22justin_smithamalloy: wow, cool
03:22amalloywell don't pass it a var
03:22tsdhamalloy: ?
03:22justin_smithtsdh: get the thing the var holds - automatic deref of vars doesn't happen in java
03:22TEttinger,(java.util.Collections/sort people #(- (.length %1) (.length %2)))
03:22clojurebotnil
03:22TEttinger,(vec people)
03:22clojurebot["Jim" "Bob" "Mike"]
03:22TEttingerthere we go!
03:22justin_smithtsdh: deref will give you the thing in a var
03:23TEttingeryou need an IFn I think
03:23tsdhBut there's no deref method (or Var) in clojure.api. All you get is IFn which you can just call() or invoke().
03:23justin_smithtsdh: uhh...
03:23justin_smith,(deferf #'+)
03:23clojurebot#error{:cause "Unable to resolve symbol: deferf in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: deferf in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: deferf in this context", :at [...
03:23justin_smitherr
03:23justin_smithhaha
03:24justin_smith,(deref #'+)
03:24clojurebot#object[clojure.core$_PLUS_ "clojure.core$_PLUS_@13b78423"]
03:24TEttingerwas that a definition or a deref, justin_smith?
03:24justin_smithyes, you can deref vars, they are a mutable container
03:24amalloythe clojure.java.api.Clojure API is very minimal
03:25justin_smith,(.deref #'+)
03:25clojurebot#object[clojure.core$_PLUS_ "clojure.core$_PLUS_@13b78423"]
03:25justin_smithyou can use the deref method too
03:25amalloyif you have a var which contains a value, and you need the value instead of the var (because it's not a function, you'll have to get the var for deref, and call it on your var
03:25amalloyjustin_smith: c.j.api.Clojure gives you everything as IFn, not even Var
03:25justin_smithahh
03:25amalloyso you'd have to cast it to var and then call .deref
03:26amalloybut better to find the var for deref and use that
03:26tsdhamalloy: Got the same error when my clojure-defined comparator as a plain function.
03:26justin_smithinteresting
03:27tsdhHm, indeed (supers (class (fn [a b]))) says it implements Comparator.
03:28justin_smithtsdh: and you are definitely getting the fn and not the var holding it?
03:28tsdhI do final static IFn MATCH_COMPARATOR = Clojure.var(SOLUTION_NS, "match-comparator"); in java.
03:28justin_smithyeah, that's the var (as IFN, which is a super of var)
03:29tsdhI did the same with other fns which I can myIFn.invoke(args); in java.
03:29justin_smithtsdh: yeah, calling a var implictly derefs when invoking
03:29justin_smith,(#'+ 1 2)
03:29tsdhI guess I could invoke my comparator with myComp.invoke(a, b); but I need to pass it on to some framework.
03:29clojurebot3
03:31amalloytsdh: (Comparator)deref.invoke(myvar)
03:31tsdhAha: comparator = (Comparator<Object>) ((Var) FunnyQTBenchmarkLogic.MATCH_COMPARATOR).deref();
03:32tsdhamalloy: Ah, requirirng deref and invoking it on my var would also work. Anyway, gotta run. Thank you both!
03:32amalloywell i did suggest that a few times
03:33justin_smithhaha
03:33justin_smiththat amalloy, he gets no respect I tells ya what
03:34amalloyall i get is this useless karma
03:35TEttinger(dec amalloy's respect)
03:35lazybot⇒ -1
03:35TEttinger(inc amalloy)
03:35lazybot⇒ 253
03:35TEttingerless than no respect!
05:31constlWhat does the "&" mean in a general form? e.g. (while test & body)
05:32TEttingerconstl, it means that you can pass additional args after the & and they will be available as a seq with the name body (there, at least)
05:32TEttingerso "& args" in the typical clojure -main fn means you can pass a number of arguments and get them from a seq called args
05:33constlTEttinger: So in my example it means that body can have multiple s-expressions ?
05:34TEttingeryes, since an s-expression is just a form. hm, that isn't a an argvector though so....
05:34TEttingeractually I haven't seen that in a general form
05:34TEttingercan you link to the code where that was?
05:35TEttingerit's possible there's some surrounding macro that defines & in its body
05:35TEttinger(doc while)
05:35clojurebot"([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"
05:35constlThis reference is from a book called "Clojure in action" and it is explaining the functional iteration capabilities
05:35constlso to examplain the while general form it gives that example
05:37constlSorry my English doesn't make any sense in the above two sentences. But i think you've answered my question already
05:37TEttinger,(while (not= 0 (rand-int 10)) (def inner-form 1) (def another 2) (+ inner-form another))
05:37clojurebotnil
05:37TEttinger,(while (not= 0 (rand-int 10)) (def inner-form 1) (def another 2) (print (+ inner-form another)))
05:37clojurebot333333333
05:38TEttingerI think the & is a typo in there
05:38TEttingerit makes sense in an argument list
05:38TEttingerwell, argument vector
05:38TEttingerunless it's using that as pseudocode to mean one or more forms in body
05:39constlWell it is also found when describing the "when". e.g. (when test & body)
05:39TEttinger(which is totally useful to be able to write that, but they should have explained it better)
05:39TEttingeryeah, when also allows multiple forms, unlike if
05:39constland it gives this explanation, (when true (do-this) (and-that) (and-return-this))
05:39TEttingeryep
05:40TEttinger,(if true 15 :not-found :something-not-allowed)
05:40clojurebot#error{:cause "Too many arguments to if", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Too many arguments to if, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6732]} {:type java.lang.RuntimeException, :message "Too many arguments to if", :at [clojure.lang.Util runtimeException "Util.java" 221]}], :trace [[cloju...
05:40TEttinger,(when true 15 :not-found :something-that-is-allowed)
05:40clojurebot:something-that-is-allowed
05:41TEttingerbut when is pretty much exactly the same as (if test (do & body))
05:42TEttingerthe only difference between an if with a do block for the "test is true" condition and no "test is false" block...
05:42constl,(if true (do 15 :not-found) :something-that-is-allowed)
05:42clojurebot:not-found
05:42TEttingerthe only one i can think of is that when is usually used by clojure programmers to show that it's being used for something stateful or side-efecting
05:43TEttingerexactly
05:43TEttingerand do is the simplest example of what the book would use & for
05:43TEttinger(do & body)
05:43TEttingerit just does every form in the body
05:43TEttingerin order
05:43constlRight!
05:44constlCheers for the insight
05:47TEttingergreat! clojure's a fun language. (I think the most fun part is when someone else is writing java code and your clojure version ends up being a quarter the size)
05:48TEttinger(not accurate in the general case, I've had it be a fifth sometimes and 2/3 maybe sometimes)
05:48constlTEttinger: Well coming from a Java background and being an average Joe i would say it boils my brain
05:52TEttingerit was hard for me for a long time, tbh. it did click, in parts, the more I wrote
05:52TEttinger4clojure helped, if I was starting today I'd read the heck out of brave clojure
05:57constlTEttinger: Well i started with brave clojure but somehow i felt it moved too fast so i resorted to Clojure in action and it seems its ok for me.
05:57constlWhat's 4clojure ?
05:57TEttingerit's an excellent koan-like site. it presents you with fill-in-the-blank problems
05:58TEttingeryou write code that solves all of the blanks on the page
05:58TEttingerlike one could be simple, (= 2 (+ _ 1))
05:58TEttingerso for that one you just enter 1
05:59constlI ll check that then, sounds fun
05:59TEttingerthe next will be trickier, like (= "Hello, World!" (_ "World"))
06:00TEttingerwhere you would need to fill in a function that it would run with the arg "World"
06:01TEttingerby maybe 10-20 problems in (maybe earlier, I don't remember) they start being very tricky and challenging. a lot have you re-implement fns from clojure's library, without using those fns or sometimes certain similar ones
06:01TEttingerthe one that has you reimplement nth is a fun one
06:02constlDo i have to register to start ?
06:03constlI mean when you registered you are presented with a sequence of problems or is it just that you simply select which one to solve?
06:03TEttingeryeah, it's a good idea to register to keep track of your progress
06:03TEttingeryou usually start with Number 1
06:03TEttinger(not sure if there's a 0)
06:04TEttingera good piece of info that may be handy for the one with nth: several data structures clojure provides are also usable as functions, like maps can be used as functions that take a key as an argument and try to get that key in the map
06:04TEttinger,({"alpha" 1 "beta" 2} "alpha")
06:04clojurebot1
06:05TEttingerexperiment a bit with what you can do there, trying a list, a vector, and a set for example
06:07constlbut it will need to go hand by hand with some learning material, it's a learning source by itself right?
06:08TEttingeryeah, you would still need the book
06:08TEttingerit's more practice or exercises to test your knowledge in ways that you might not get otherwise
06:09constlhmm
06:10constlis there a way to submit its form without the mouse ? like a keyboard shortcut ?
06:11TEttingermight be a good issue report, Raynes I think is a primary author
08:25constl_,(println "Hello chan")
08:25clojurebotHello chan\n
08:26constl_Im trying to create a simple function that you can pass two numbers and it will countdown from first to second
08:26gfrederickscountdown like by printing?
08:27constl_gfredericks: Yes, and i'm using loop and recur but somehow the code i came up with doesn't look very optimal
08:27constl_Can i paste here for your opinion to this trivial question ?
08:27gfredericksuse refheap.com
08:29constl_https://www.refheap.com/4f21f193624bf80669e7e6c16
08:30gfredericksconstl_: the loop part is redundant, you can recur to the function itself
08:31gfredericksyou can also replace (if c (do ...)) with (when c ...)
08:31gfredericksnot sure what else you don't like abou it
08:32constl_gfredericks: So if i understood correctly its better to remove loop, and rebind decremented value to x and call that function again ?
08:35constl_Something like this https://www.refheap.com/99226
09:03gfredericksconstl_: yeah it's a little simpler
09:03gfredericksconstl_: you might also look at range and doseq for an alternative approach
10:11caterndear clojure fans
10:11caternhow would I idiomatically get the sequence of partial sum of another sequence?
10:12caterni.e.: [1 2 3 4 5] -> [1 3 6 10 15]
10:12catern(preferably lazily)
10:26dysfuncatern: i'd probably do something like this:
10:26dysfun,(->> [1 2 3] (reductions conj []) rest (map (partial apply +)))
10:26clojurebot(1 3 6)
10:26catern:(
10:26caternthat does a lot of unnecessary work
10:27caternwait!
10:27caterndysfun: you're being silly!
10:27caternreductions is the function to use
10:27caternthat's all I was looking for :)
10:27catern,(reductions + [1 2 3 4 5])
10:27clojurebot(1 3 6 10 15)
10:28dysfunaha, that's pretty nice
10:28dysfuni haven't woken up properly today :)
10:28dysfuni'm in grunt mode, so i'm writing tests
10:35justin_smith,(reductions + [1 2 3 4 5])
10:35clojurebot(1 3 6 10 15)
10:35justin_smith^ catern
10:35justin_smithoh, never mind
10:35justin_smithhaha
10:37expezI think I'm making this harder than it should be, how can I get the content of a clj file without the (ns ..) form?
10:38justin_smithexpez: as a string?
10:38expezjustin_smith: yes
10:41expezMy first attempt skips into the ns form and then drops tokens from the string until a paren count of 0 is reached. But then I realized parens might occur (without being balanced) in the docstring so I would have to account for that.
10:41caternon the off chance
10:42caterndoes anyone/can quickly think of a way to nicely and idiomatically do a queueing process simulation?
10:42justin_smithyeah, it's not an easy problem
10:42caternbrb, /me goes off to think about it
10:42justin_smithsorry, expez: that is not an easy problem
10:43justin_smithcatern: queueing process simulation, I would use either agents (which are all backed by queues they use to implement send / send-off) or core.async (channels are queues)
10:44caternjustin_smith: not quite like that :)
10:44gfredericksexpez: read can do this actually
10:44justin_smithoh, of course
10:44caternjustin_smith: as in, I draw values from a distribution and accumulate them to get arrival times
10:44caternbut I just realized that I could search for examples in Haskell or something
10:44gfredericks,(def my-file (java.io.StringReader. "(ns foo) (hey) (hooray)"))
10:44clojurebot#'sandbox/my-file
10:44gfredericks,(read my-file)
10:44clojurebot#error{:cause "java.io.StringReader cannot be cast to java.io.PushbackReader", :via [{:type java.lang.ClassCastException, :message "java.io.StringReader cannot be cast to java.io.PushbackReader", :at [clojure.core$read invoke "core.clj" 3630]}], :trace [[clojure.core$read invoke "core.clj" 3630] [clojure.core$read invoke "core.clj" 3628] [clojure.core$read invoke "core.clj" 3626] [sandbox$eval47 i...
10:45gfredericks,(def my-file (java.io.PushbackReader. (java.io.StringReader. "(ns foo) (hey) (hooray)")))
10:45clojurebot#'sandbox/my-file
10:45gfredericks,(read my-file)
10:45clojurebot(ns foo)
10:45gfredericks,(read my-file)
10:45clojurebot(hey)
10:45gfredericks,(read my-file)
10:45clojurebot(hooray)
10:45gfredericksexpez: ^
10:45expezgfredericks: that was my first though, to read the entire file and drop the first form I read, but that would change the formatting of the file when I spit it back out.
10:45justin_smithcatern: ahh, not processes with queues for communication, but simulating the process of a queue
10:45caternjustin_smith: indeed
10:46gfredericksexpez: maybe you want a reader that knows how much has been read
10:46justin_smithcatern: if you had an ordered list of entities, and some way to calculate how long each takes to get served, I would use reductions to get a series of wait times
10:46gfredericksthere's gotta be something for that; all you need to know is the position of that last paren
10:47expezgfredericks: yeah
10:47justin_smithexpez: shell out to elisp :P find the matching paren to the ns form, and drop the form
10:47justin_smithor call read to drop the ns form, and then slurp to get the rest unchanged, maybe
10:48expezjustin_smith: the current implementation uses mechanical turk for human assistance, but since the op is sync this caused some users to complain about performance
10:48gfredericks,(def my-file (java.io.PushbackReader. (java.io.StringReader. "(ns foo) (hey) (hooray)")))
10:48clojurebot#'sandbox/my-file
10:48gfredericks,(read my-file)
10:48clojurebot(ns foo)
10:48gfredericks(slurp my-file)
10:48gfredericks,(slurp my-file)
10:48clojurebot" (hey) (hooray)"
10:48gfredericksnice
10:48justin_smiththere we bo
10:48justin_smithhaha, go
10:49expezdamn, that's hot stuff. Thanks!
11:21caternokay, I have an idea for my queue simulation
11:22caternbut I need to map over two seqs, and my mapping function needs to know the last value I created
11:22catern,(map f (range 5) (range 5 10))
11:22clojurebot#error{:cause "Unable to resolve symbol: f in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: f in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: f in this context", :at [clojure.lang.Ut...
11:23catern,(map + (range 5) (range 5 10))
11:23clojurebot(5 7 9 11 13)
11:23caternbut + also needs to have access to 5 while calculating 7, 7 while calculating 9, etc.
11:23caternshould I just mantain some mutable variable or is there a nice way to do that?
11:23justin_smith,(map list (partition 2 1 (range 5)) (partition 2 1 (range 5 10)))
11:23clojurebot(((0 1) (5 6)) ((1 2) (6 7)) ((2 3) (7 8)) ((3 4) (8 9)))
11:24gfredericksdoes that sound like reduce at all?
11:24justin_smithgfredericks: sounds like a reduce to me yeah
11:24caterngfredericks: a little, but doing it with reduce would also be weird
11:24caternbecause I'd need to recalculate the last value every time
11:25catern(which would be fine, it'd just be weird... also what if there was randomness or state in the calculation of the last value?)
11:25justin_smithcatern: you can do whatever you want to calculate each value, but the previous is an input, sounds like reductions
11:26caternjustin_smith: not sure how reductions is any different from reduce here
11:26justin_smithcatern: gives you the series
11:27caternyeah, but I can't access that series while I'm calculating it... well, I could, I suppose, but specifically I can't access the last element of that series
11:27justin_smith,(reductions (fn [prev [a b]] (+ (/ prev 10.0) a b)) 0 (map list (range 5) (range 5 10)))
11:27clojurebot(0 5.0 7.5 9.75 11.975 ...)
11:27justin_smithcatern: reduce makes it easy to access your previous result
11:27justin_smithas does reductions
11:28caternhmm
11:28caternI'll try it
11:28justin_smithcatern: and you absolutely can always get the previous value returned, it is the guaranteed first arg to your function in reductions or reduce
11:33justin_smithcatern: so you want a running sum but also the previous args?
11:33caternjustin_smith: yes, I think
11:34justin_smith,(reductions (fn [[sum prev] [a b]] [(+ sum a b) [a b]] [0 0] (map list (range 5) (range 5 10)))
11:34clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
11:34justin_smith,(reductions (fn [[sum prev] [a b]] [(+ sum a b) [a b]]) [0 0] (map list (range 5) (range 5 10)))
11:34clojurebot([0 0] [5 [0 5]] [12 [1 6]] [21 [2 7]] [32 [3 8]] ...)
11:35justin_smithsecond one should have had nil as the init
11:35justin_smithbut hopefully the idea should be clear - first item in pair is the running sum, second item is the previous pair
11:44dysfunwin 20
11:45caternhey, yeah, reductions works perfectly, thanks justin_smith
11:45justin_smithnp
11:48wirrbelRunning lein ring server-headless, shouldn't my server just rebuild upon source changes?
11:49justin_smithno, it doesn't and won't
11:50justin_smithwirrbel: if you pass your app/handler whatever as a var, the server will see updates to the definition though
11:50justin_smitheg. #'my-app.core/handler instead of my-app.core/handler
12:24gfrederickswhen passed no args, alter-var-root returns a destructive transducer that just messes everything up
13:45CL4Y3RSCLUBSO?
13:52justin_smith~so
13:52clojurebotso is (add-to-list 'erc-keywords '("\\bso\\b" erc-default-face))
13:52Bronsamakes sense clojurebot
13:53justin_smithoh, of course, that's how to unhighlight so, who isn't around anymore
13:53justin_smith$karma so
13:53lazybotso has karma -34.
13:53justin_smiththe poor sould
13:53justin_smith*soul
13:54Bronsalol
14:08catern(inc clojure)
14:08lazybot⇒ 21
14:09justin_smith$karma Clojure
14:09lazybotClojure has karma 21.
14:09justin_smithahh, ignores caps
14:09justin_smith(inc clojure)
14:09lazybot⇒ 22
14:09justin_smith$karma Clojure
14:09lazybotClojure has karma 22.
14:14justin_smithnoncom: I found support for unquoted field names in cheshire
14:14justin_smithnoncom: https://github.com/dakrone/cheshire/blob/master/src/cheshire/factory.clj#L15
14:30gfredericksjustin_smith: oh hey look at those dynamic vars
14:30gfredericksI'm trying to figure out if they can be used to solve the global extensibility problem
14:30justin_smithgfredericks: that's what I was looking for when I found those actually :)
14:31gfredericks,'com.fasterxml.jackson.core.JsonFactory
14:31clojurebotcom.fasterxml.jackson.core.JsonFactory
14:31justin_smithsadly I don't think the coercions are per-factory
14:31gfredericks,com.fasterxml.jackson.core.JsonFactory
14:31clojurebot#error{:cause "com.fasterxml.jackson.core.JsonFactory", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonFactory, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.ClassNotFoundException, :message "com.fasterxml.jackson.core.JsonFactory", :at [java.net.URLClassL...
14:31gfredericks&com.fasterxml.jackson.core.JsonFactory
14:31lazybot⇒ com.fasterxml.jackson.core.JsonFactory
14:31justin_smithif they were, yeah, the logger could have its own factory
14:31gfredericks&(.isInterface com.fasterxml.jackson.core.JsonFactory)
14:31lazybot⇒ false
14:32gfrederickshmph
14:33gfredericksyeah I guess if cheshire coerces everything beforehand
14:33justin_smithyeah, it uses the JSONable protocol, with a single method, to-json
14:33justin_smithand that can't be a local binding
14:35justin_smithand clojure.data.json has the JSONWriter protocol, with -write method
14:37gfredericksI feel like I asked stu about this assymetry a couple years back, but have no idea what he said
14:40gfredericksmaybe that was more about data readers
14:42gfredericksI guess transit avoids the global thing a bit better than clojure's printer does
14:45justin_smithgfredericks: oh, that's a great point, maybe transit would be the best backend for this
14:45gfrederickswhat
14:45gfredericksfor what
14:45gfrederickswhat are we
14:45gfredericksis this even talking about
14:48justin_smithnever mind, I may have been confusing transit for something else
14:48justin_smithI thought it would work with various formats, but no
14:48justin_smiththat's not the one
14:49gfredericksno transit is like a frontend
15:00tomjackisn't transit what happens between ends?
15:01tomjack(and starts and stops I suppose)
15:03justin_smithtomjack: there is a specific lib for sending data between processes called transit
15:03tomjackyes :)
15:04tomjackbut the name was chosen with some care, I presume
15:17matthavardHow would I add this library as a dependency: https://github.com/dcolthorp/matchure
15:17matthavardoh oops there's an installation section ignore me
15:18justin_smithmatthavard: have you tried [matchure "0.10.1"] ? that's what it has in the project.clj
15:18justin_smithoh yeah, that's what it would tell you to do also
15:18matthavardYeah haha I'm dumb I was trying [org.clojure/matchure "0.10.1"]
17:20sveriHi, how can I define a return type of Foo[] for a clojure method? (defn ^Foo[] fname seems not to work for me
17:31scottjsveri: maybe ^"[Lnamespace.Foo;"
17:33sveriscottj: I just found some thread from 2009 suggesting this should work: #^"[Lnamespace.Foo;" But your one looks like it works in the latest clojure, at least that how ever return type definitions are declard
17:33sveriThank you very much
17:35scottj^ used to be #^, afair
17:35sveriYea, that makes sense :-)
18:47noncom|2is there any particular reason on why a lein's project file is a call to some (defproject ..) instead of being a simple edn {} ?
18:49tolstoynoncom|2: Total guess, but defproject is a macro and probably does some lightweight transformation?
18:50justin_smithyeah, I think that's pretty much it
18:50noncom|2tolstoy: yeah, sure, i think.. but i totally see no reason for it being this way. afaik project.clj is a plain data map, so why complicate the file with a call to some fn or macro?
18:50justin_smithtolstoy: it supports heavy weight transformation via ~
18:50noncom|2ah, so it's about ~
18:50justin_smiththat could be part of it, at least
18:50justin_smithyou can evaluate arbitrary code in there
18:51noncom|2uh..
18:51noncom|2does not seem to clean though.. but probably useful at times
18:51noncom|2s/to/too
18:51justin_smithI'm not saying it's a good idea
18:51justin_smithI am saying it's possible
18:52justin_smithand it would make reading a project.clj as edn a problem
18:52justin_smithalso, a project.clj is only the parts of the config you altered, it gets merged with the base options
18:52justin_smithunless you used ^:replace, etc. etc.
18:53justin_smithbtw, noncom|2, did you see my link earlier about being able to replace cheshire's json-factory with one that supports raw keys in maps?
18:53justin_smithit's in factory.clj
18:54noncom|2i did not see the link! but i know that it is possible to (binding ..) factory for a json operation, but it only affects reading..
18:54noncom|2was there something about writing a json string too?
18:54justin_smithfactory is for generating
18:55justin_smithwell, maybe not only for generating, but it definitely affects generation
18:55tolstoyYou can have multiple forms in project.clj, so one of 'em has to be tagged as the project.
18:55noncom|2it's like string -> factory -> clojure data struct
18:55justin_smithit's also like clojure data struct -> factory -> string
18:55noncom|2wow, did not notice that this was possible
18:55tolstoyhttps://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/project.clj#L398-L405 Suggests that (def project {}) works, too.
18:55noncom|2do you still have the link?
18:56justin_smithhttps://github.com/dakrone/cheshire/blob/master/src/cheshire/factory.clj#L15
18:56justin_smithtolstoy: I am enlightened but not surprised :) cool
18:56noncom|2tolstoy: yeah, looks like we have the potential to write another OS with lein projects :D
18:56justin_smithhaha
18:57justin_smithnoncom|2: note that the comments there explicitly state that the factory is used for both encoding and decoding
18:59noncom|2justin_smith: so, this factory, yes.. i tried it, but i only managed to make cheshire use it when reading.. the properties are mapped to JsonParser class.. which sounds like it parses the string. however, right.. the comment says both enc/dec..
18:59noncom|2i must give it a second, closer look at monday
19:00noncom|2playing with neo4j, yeah, in making a little mudy thing :)
19:00noncom|2this neo4j takes in this wrong kind of json as parameters for its objects. the json kind without the quotes on fields names
19:06underplankSo Im trying to get a repl working in emacs using cider-jack-in command. And the repl seems to be starting, but I can get the buffer to open. Any ideas how to get that to happen?
19:07justin_smithunderplank: can you use M-x cider to connect to a repl that is already open?
19:09underplankhmm… thats wierd. I dont get a prompt or anything.
19:09underplankIt looks like I have the connections, but nothing executes.
19:12justin_smithunderplank: has cider ever worked for you in the past? do you have the cider-nrepl plugin set up?
19:13underplankI’ve had it working in the past. lein deps :tree shows that I have 0.8.2 installed. I do that in my lein profiles.clj
19:13underplankDo I need to have that in my project.clj as well?
19:13justin_smithno
19:14underplankhmm.. I didnt think so.
19:14justin_smithif it has worked in the past, the likely problem is that you upgraded your cider elisp without deleting the elc files
19:14justin_smithcider breaks binary compatibility, and elc doesn't handle that nicely
19:17underplankahh. that might make sense. I think my emacs.d folder is in a … not great state..
19:18justin_smithfind . -name '*.elc' will show you where they are
19:18justin_smithbecause of how elisp works, it can be effected by elc files that are not part of cider proper, if they call things in cider
19:19underplankyeah looks like I have like three versions in here or something.
19:19underplankwhoops!
19:19justin_smithwhen I said "binary compatibility" above, I should have said API compatibility (argument types, counts, etc. etc.)
19:19justin_smithwell, that can be fine, as long as you are loading the right one
19:19justin_smithheh
19:20underplankare elc files just like compiled version of source, so If I blow them away it will rebuild the ones it needs?
19:20justin_smiththey are like aot
19:20justin_smithif they don't exist, emacs will just use the source files
19:20justin_smithand startup may take a little longer
19:20underplankahh great.. thats what I thought.
19:27underplankjustin_smith: works! just cleaned up a few packages and installed the latest.. thanks!
19:27justin_smithnp
19:28bordatouecould anyone please tell me how to change nrepl version 0.2.6 to 0.2.8 under lein , currently I had created ~/.lein/profiles.clj file with the following setting {:user {:plugins [[cider/cider-nrepl "0.9.0-SNAPSHOT"]]
19:28bordatoue :dependencies [[org.clojure/tools.nrepl "0.2.7"]]}}
19:29justin_smithwhy do you ask for 0.2.7 ?
19:29bordatoueok need to change it from 0.2.6 --> 0.2.7 ; the
19:29bordatouethe problem is it downloads the 0.2.7 jar but still startsup with 0.2.6
19:30tolstoybordatoue: It's up to 0.2.10 now.
19:30bordatoueit seems to only work if I add the dependencies under the project.clj file
19:30bordatouetolstoy: the point is i can't get it to work with any version other than 0.2.6 it keeps chaning every day
19:31justin_smithbordatoue: there's a weird issue, you may also be able to use :dev rather than :user in profiles.clj to get the proper version
19:31tolstoybordatoue: I added 0.2.10 under {:dev {:dependencies ...}} as it's just used for nrepl. Seems to work okay.
19:32bordatouei can't understand this why they keep chaning this all the time , everytime i update my emacs then the entire repl breaks
19:32bordatouetolstoy: I will try that, thanks a lot
19:32justin_smithbordatoue: this is why I stopped using cider, the development is too chaotic
19:32justin_smithtolstoy: yeah, that's what I was trying to suggest :)
19:32bordatouejustin_smith: what do you use
19:33justin_smithbordatoue: inferior-lisp, which has 0 features, but it actually works
19:33bordatouehave you tried intellij plugin for clojure is it any good
19:33justin_smitheg. I don't even get completion or anything
19:33bordatouei don't mind any feature but consistency is my top priority
19:33justin_smithbordatoue: I'm too much of an emacs addict, but I have heard nothing but good things about it, and have watched people use it and been pretty impressed
19:34justin_smithcursive that is
19:34mfikesbordatoue: Yes, Cursive is great.
19:34justin_smithbordatoue: yeah, I switched to inferior-lisp because I was tired of the break / update cycle
19:34bordatouegreat guys, I will give it a try
19:35tolstoyI stuck with 0.8.2 for a long while. Seemed stable to me.
19:35tolstoyinf-clojure has its appeal.
19:38bordatouetolstoy: can you please paste what you have entered in your profile.clj file
19:38bordatouei tried :dev :dependencies and it is still not working
19:38tolstoybordatoue: Sure, but I don't use profiles.clj for that anymore.
19:39bordatouethen what do you use ? are u adding it to the project.clj file
19:39tolstoyWhat's the refthingy we can paste to?
19:39justin_smithhttp://refheap.com
19:40fredddcan anyone tell me if transducers and reducers play nice? as in, is it possible to use transducers for most of a pipeline, but use reducers/fold for the final combination for the fork/join parallelism benefits?
19:40tolstoyhttps://www.refheap.com/99240
19:41tolstoybordatoue: Here's a more complete :profiles vector in my project.clj file (for a super new project): https://www.refheap.com/99241
19:42underplankHi all.. When using uberjar what is the difference between the standalone jar and the uhh non-standalone jar?
19:42freddd_dang, got cut off just after asking my question regarding reducers/transducers. if anyone replied, would you mind replying again? :)
19:42bordatoueso everytime you create a project you need to explicitly add this
19:43justin_smithunderplank: one contains your project, the other contains your project plus all deps, it uses the project one as part of constructing the other one
19:43tolstoybordatoue: I do that just for my own self so that I'm super clear what's interfering with my project. Personal taste.
19:43underplankahh.. is there a reason you would want to use the non-standalone?
19:43justin_smithfreddd_: as long as you are using transducers and reducers properly, they should combine just fine, yes
19:44justin_smithunderplank: not really, it gets created as part of making the other one
19:44bordatouetolstoy: thanks
19:44underplankis there a way you can tell uberjar to just make the standalone one?
19:44BengCompsI have been trying to run clojure on a macbook has anybody succedeed?
19:44justin_smithunderplank: like I said, it uses it while making the other one, so the option isn't to make it or not, it is to delete it or not, but I don't think it has an option for deleting it
19:45underplankBengComps: doing it right now. what seems to be your problem?
19:45underplankjustin_smith: fair enough
19:45BengCompsany link should help, where to start underplank
19:45underplankI would start with Leiningen.
19:45justin_smithBengComps: I think more people use osx for clojure than use windows
19:46underplankhttp://leiningen.org/
19:46justin_smithlein is just a single download
19:46justin_smithvery easy to use
19:47BengCompsThanks a lot guys
19:47BengCompsRight on it
19:47BengCompsjust for curious sake does any of you uses latex? and if so how do you run texmaker on yosemite
19:48justin_smithsomeone was talking the other day about using org mode with latex and clojure together, but now I forget who it was
19:49justin_smithto do inline calculations, then charts and such from those calculations
19:50BengCompsI have been using sharelatex.com but the online compiler crashes as soon as my documents has a lot media content in it
19:52tolstoyUgh. It's difficult when folks use that graphic for Clojars dependency declarations. Can't select it!
19:53justin_smithtolstoy: that graphic is svg, svg is selectable
19:53justin_smithunless your browser is bad
19:53tolstoyI mean select it to paste it into Emacs. Hm.
19:53justin_smithtolstoy: right, it has real text in it
19:54justin_smithwhich you can Control+F for, or drag and select etc.
19:54tolstoyYeah, it doesn't select for me. Safari loses?
19:54justin_smithI guess
19:54justin_smithhmm, one moment
19:54justin_smithtolstoy: remind me again one of the libs that uses that?
19:54tolstoyhttps://github.com/xsc/pandect ;; works for you there?
19:55justin_smithtolstoy: oh man, they way they embed it, it doesn't actually work
19:55underplankoh.. yeah that does seem anoying… is it because it comes straight from clojars?
19:55underplankso they dont have to update it?
19:55tolstoyNo idea.
19:55justin_smithso I guess I should have said, svg text *should be* selectable
19:56andyfBengComps: There is a program called MacPorts that lets you install many different open source software packages, including latex.
19:56underplankYeah. Its way of getting the latest version from clojars in the README and not have it out of date.
19:56underplankthe md is [![Clojars Project](http://clojars.org/pandect/latest-version.svg)](http://clojars.org/pandect)
19:56justin_smithunderplank: I knew it - you have to open the svg itself
19:56justin_smithhttps://camo.githubusercontent.com/63193fb6d7a245fd83b93937eed69353e06121f9/687474703a2f2f636c6f6a6172732e6f72672f70616e646563742f6c61746573742d76657273696f6e2e737667
19:57justin_smithon the svg itself (accessed via right-click / open image in new tab) you can select the text
19:57underplankannoying..
19:57justin_smiththe problem is the way it is embedded, or the css in the parent document
19:57tolstoyYou might as well just click on it, _then_ select the text.
19:58justin_smithright, but theoretically, since it is an svg, the text should be selectable
19:58underplankI guess the problem is making it a cross realm query… svg/images makes that easy. I guess if you wanted it as text you would have to soemthing else? jsonp or something?
19:58justin_smithbut it isn't when inside that page, for some weird reason
19:59justin_smithunderplank: yeah, I think that's part of it
20:00justin_smithI've always thought svg was underutilized and poorly exploited. The fact that you can exactly control the display, and it has selectable / copyable text is awesome
20:00justin_smithand under utilized
20:00FrozenlockIt is.
20:01FrozenlockA project in cljs almost entirely in SVG https://labs.hvac.io/editor
20:01justin_smithcool, is that yours?
20:01Frozenlockyes
20:01justin_smithvery nice!
20:02tolstoyThat's really great.
20:03justin_smithlol
20:03Frozenlockjustin_smith: Make sure to save it :-p
20:04justin_smithnice!
20:05justin_smithFrozenlock: was this a student thing, or a learning exercise?
20:06FrozenlockNo, it's a project in development for my own needs.
20:07justin_smithcool
20:11Frozenlock(thus the rough edges)
21:16caternI have two infinite sequences
21:16caternI'd like to merge them, sorted by some comparator
21:16caternidiom?
21:17TEttingerI'm not sure if there's a way to sort a literal infinite sequence
21:17caternah... good point...
21:17andyfI think catern means to merge them, producing a new infinite sequence?
21:17caternboth of them are increasing sequences, though
21:18andyfI assumed you meant that the two were already sorted
21:18caternandyf: yes
21:18catern(temporarily forgot that after TEttinger's remark)
21:18andyfMerging them is possible. Can hack up a few lines of code here in a minute or three. No 1-line version I?m aware of
21:18justin_smithI know I've written this function before
21:18justin_smithand yeah, it was like a three liner
21:19caternthree lines?! so verbose ;_;
21:19TEttingerha
21:19ccallebsIs there a specific clojure beginners channel?
21:19catern#clojure-beginners
21:19ccallebsAh, nevermind. I see it in the MOTD :)
21:19catern:)
21:19ccallebsSorry, using a new IRC client and it wasn't immediately obvious.
21:20caternso, what would be the general approach to this merging?
21:20caterni mean
21:20caternI guess I know how to actually manually do this
21:25sobelwhy might timbre prevent a (fairly simple) program from exiting after its -main returns?
21:25sobeli've narrowed it down to: if i call (info) to make a log entry it doesn't exit.
21:25sobelif i don't make any log calls, it exits normally
21:29justin_smith,(defn merge-sort [& seqs] (let [[[s0 & ss :as s] & seqs] (sort-by first (remove empty? seqs))] (lazy-seq (when (seq s) (cons s0 (apply merge-sort (cons ss seqs)))))))
21:29clojurebot#'sandbox/merge-sort
21:29freddd_hey, again. i'm mapping over a list of files and would like to ultimately have a hash-map output with keys of the file names and values of the file contents. the solution i'm using seems lacking, and i'm wondering if anyone can offer some advice. mock code here: https://www.refheap.com/99243
21:29justin_smith,(merge-sort [0 1 2 3] [2 3 4] [-1 8 9 10])
21:29clojurebot(-1 0 1 2 2 ...)
21:30justin_smiththat's a mouthful of a destructuring
21:31justin_smithfreddd_: you can use a vector instead of a hash-map for each one
21:31justin_smithfreddd_: also, unless the keywords ever get used as literals in your code, it's better to just keep the strings as keys
21:32justin_smithsobel: try shutdown-agents
21:32justin_smithsobel: timbre might be using futures in order to avoid slowing down your code, since the logging produces no result your code needs
21:32sobellikely
21:33justin_smithsobel: it uses a future to get your hostname? not seeing other usages of future (other than logged-future, but I don't see any calls to that within its codebase)
21:33freddd_justin_smith: isn't it still wasteful to create some inner collection that just gets flattened anyway?
21:33justin_smithanyway, all it takes is one call to future, then you need shutdown-agents
21:34justin_smithfreddd_: the vector does not get flattened, because maps are made of two element vectors
21:34sobeljustin_smith: thanks! that was far from clear to me.
21:34justin_smithand it can reuse the underlying datastructure (and does)
21:35sobel(and fixed my not-exiting problem, which i diligently chased from the stupid start of my processing chain)
21:35justin_smithfreddd_: eg. ##(seq {:a 0 :b 1 :c 2})
21:35lazybot⇒ ([:c 2] [:b 1] [:a 0])
21:35sobels/diligently/stupidly
21:35justin_smithfreddd_: those are the vectors I am talking about ^
21:35justin_smithcatern: oh, I forgot to highlight you when I pasted my merge-sort above
21:36justin_smithanyway, my merge-sort, which I pasted above, should do what you want
21:36caternjustin_smith: yeah, I got it. I actually need to do sort-by kind of thing, so I'm modifying it
21:36andyfcatern: Not nearly as pretty, and only works for 2 input sequences, but https://gist.github.com/jafingerhut/41e9ceb258d1ddf05eff
21:37sobelone more i haven't solved: i got timbre logging to a file but can't disable console output
21:37justin_smithandyf: that one is likely faster for the two list case than mine though
21:37justin_smithsobel: did you remove the console logger from its config atom?
21:38sobeljustin_smith: not finding the key easily
21:39sobelaha :standard-out
21:39justin_smithsobel: it will be one of the :appenders
21:39justin_smithyeah
21:40justin_smithyou should be able to dissoc that from the atom
21:40caternhmmm
21:41sobelit has a convenienc fcn
21:41sobelok, sweet. shoulda come here sooner. haha. and had more confidence in the WORKING part of my code.
21:42justin_smithheh
21:45caternthanks again justin_smith
21:46caternyours is cool too andyf :)
21:47morgan_hi all, i have a question about clojure's data representation philosophy. when i have some data, do i annotate it with type information even when this is unnecessary for the logic of the program?
21:48morgan_simple example. to represent a point in the plane, should i just use a pair [x y] of doubles
21:48morgan_or should i define a record, like
21:48morgan_(defrecord point [x y])
21:52justin_smithmorgan_: a record is an extended hash map, so it is easy to code with maps {:x 1 :y 3.3} and upgrade to a record later if you need it
21:53justin_smithalso, records are idiomatically capitalized, because they generate a Class
21:54morgan_justin_smith: thanks! so let me see if this correct: in idiomatic clojure, you wouldn't define a record for a type of data unless you needed the special capabilities of records (ability to implement protocols, etc., i assume). correct?
21:55justin_smithright
21:55caternzomg
21:55morgan_ok, thank you!
21:55caternwhy is dissoc even in the language when disj is there
21:56justin_smithbecause sets are not associative?
21:56justin_smith,(disj {:a 0} :a)
21:56clojurebot#error{:cause "clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.IPersistentSet", :via [{:type java.lang.ClassCastException, :message "clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.IPersistentSet", :at [clojure.core$disj invoke "core.clj" 1453]}], :trace [[clojure.core$disj invoke "core.clj" 1453] [sandbox$eval25 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval...
21:57caternaw :(
21:57justin_smith,(dissoc #{:a} :a)
21:57clojurebot#error{:cause "clojure.lang.PersistentHashSet cannot be cast to clojure.lang.IPersistentMap", :via [{:type java.lang.ClassCastException, :message "clojure.lang.PersistentHashSet cannot be cast to clojure.lang.IPersistentMap", :at [clojure.lang.RT dissoc "RT.java" 806]}], :trace [[clojure.lang.RT dissoc "RT.java" 806] [clojure.core$dissoc invoke "core.clj" 1438] [sandbox$eval49 invoke "NO_SOURCE_FI...
21:57catern(i thought disj worked on maps)
21:57justin_smithcatern: it would make sense to have one function that does both
21:57caternwould it?
21:57justin_smithbut probably too late for that design decision
21:57justin_smithcatern: an inverse of conj, I guess
21:58caternyeah
21:58caterndisj
21:58justin_smithcatern: but conj works on maps
21:58justin_smithand lists
21:58caternyeah, disj should work on them
21:58justin_smithand vectors
21:58TEttingerand sets
21:59justin_smithTEttinger: well, luckily disj already works on one of these things
21:59TEttingerheh
21:59TEttinger...futures?
22:04justin_smith,(clojure.string/join "☃" "")
22:04clojurebot"☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃â˜
22:04justin_smith&(clojure.string/join "☃" "")
22:04lazybot⇒ "☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃â˜
22:04justin_smithomghax
22:05TEttinger,(count "")
22:05clojurebot135
22:05TEttingerI had to press left a lot to get through all them BOMs
22:06TEttinger,(map int "")
22:06clojurebot(65279 65279 65279 65279 65279 ...)
22:08TEttinger,(distinct "")
22:08clojurebot(\)
22:11SeyleriusWhat was clojurebot's prefix for an inline eval?
22:11TEttingerlazybot uses ##
22:11TEttingerlike this ##(+ 1 2 3)
22:11lazybot⇒ 6
22:12justin_smithSeylerius: but it needs some matching pair of brackets, otherwise talking about certain IRC channels would get annoying
22:13caternmaybe it's ,,(inc 1)
22:14sobelhow would i figure out, short of trying it, whether Robert.Hooke works in ClojureScript?
22:16justin_smithI forget whether clojurescript has vars (wiki still says no) but if not, then it won't work at runtime
22:16justin_smithafaik
22:16justin_smithhttps://github.com/clojure/clojurescript/wiki/Differences-from-Clojure#concurrent-programming
22:17SeyleriusTEttinger, justin_smith: Thanks. I thought I saw something about clojurebot being able to do that too, but I can't find where someone mentioned it.
22:39d9k_Hi! How to check in clojure module whether it's running from LightTable instarepl or from lein run?
22:50justin_smithd9k_: for one thin, lein run will call -main, the instarepl will not
22:50justin_smithunless you make it do that, of course
22:52eraserhdI'm having a huge brain fart.... how does one lexicographically compare vectors?
22:52justin_smitheraserhd: compare
22:53justin_smith,(compare [:a :b :c] [:b :c :d])
22:53clojurebot-1
22:54eraserhdjustin_smith: Thanks.
23:00eraserhdgetting close to the next avi release: searching (`/`, `?`, `n`, `N`, `*`, and `#`).
23:00eraserhdI shall implement syntax highlighting as my next big project, I think.
23:09d9k_ How to check in clojure module whether it's running from LightTable instarepl or from lein run? [2]
23:09justin_smithd9k_: -main will get run from lein run, but probably not from an instarepl
23:10justin_smithd9k_: also, there is a :repl profile in lein, which you could combine with environ for some detection magic
23:10justin_smithd9k_: but your question makes me suspect that you have top level side effects, and you wouldn't need to worry about this if you moved them into function definitions
23:16d9k_justin_smith, thanks, better than nothing
23:17justin_smithd9k_: unless you need to call -main from the instarepl, I would just set a var inside -main
23:26tolstoyHow do you tell if a Datomic db has been initialized with the attributes you want?
23:26tolstoyIf you transact all the attributes over again, you get a new "hash value" back when you (d/db conn).
23:32tolstoyI suppose I can use d/attribute to see if any of the attributes have been defined.