#clojure log - Jun 16 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:06 Surgo: all the destructuring docs I see for maps use keywords for the keys; is there a doc that shows destructuring where the map keys aren't keywords?

0:08 oddcully: Seeq: :strs and :syms in the special forms page

0:09 erm sorry

0:09 Surgo: http://clojure.org/special_forms :strs and :syms

0:11 Surgo: thanks!

0:19 WickedShell: I've found update-proxy on clojure docs, which looks to fit my need. But is this really considered the correct way to change a single function within a library? (IE the library has a very long proxy and I only need to modify one of the functions)

3:49 lvh: If I just want to execute a list of side-effecting functions, (doseq [f fs] (f)) is the idiomatic pattern, right?

3:50 That seems more idiomatic than the alternative (dorun (map apply fs))

3:51 amalloy: does (apply f) even work? i didn't think so

3:51 ,(apply +)

3:51 clojurebot: #error {\n :cause "Wrong number of args (1) passed to: core/apply"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/apply"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.RestFn invoke "RestFn.java" 412]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.C...

3:51 amalloy: no, it doesn't

3:52 lvh: oh, I guess that makes the choice even easier then

3:52 that seems like an obvious degenerate case for apply though

3:52 even though the verb doesn't make as much sense anymore since you're not applying it to anything

4:43 TMA: ,(funcall +)

4:43 clojurebot: #error {\n :cause "Unable to resolve symbol: funcall in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: funcall in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: funcall i...

4:44 TMA: yea, no need for funcall in lisp-1

4:44 ,(let [f +] (f))

4:44 clojurebot: 0

4:49 profil: ,(*)

4:49 clojurebot: 1

4:49 TMA: ,1+

4:49 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 1+>

4:49 * TMA expected a symbol, not an error :(

4:51 TMA: well, that explains the choice of inc instead of 1+

4:51 ,(= 'a 'a)

4:51 clojurebot: true

4:51 TMA: ,(= 'a 'A)

4:51 clojurebot: false

4:52 profil: TMA: clojure does not have currying, multi arity

4:53 ,(source +)

4:53 clojurebot: Source not found\n

4:55 TMA: profil: Sorry, I do not understand what you are trying to say.

4:55 profil: ,(partial + 1)

4:55 Empperi: currying in clojure would be: ##(let [almost-curried (partial + 1)] (almost-curried 1))

4:55 clojurebot: #object[clojure.core$partial$fn__4525 0x64192b7e "clojure.core$partial$fn__4525@64192b7e"]

4:56 profil: Empperi: yes :)

4:56 Empperi: bah, I never remember the inline code example syntax for clojurebot

4:56 it was something like that

4:57 anyway, that is *not* real currying

4:57 it's something very similar but it's not currying

4:57 TMA: common-lisp:1+ is the function that adds one to its argument -- hence the equivalent of clojure.core/inc

4:57 what I was testing was whether 1+ is a valid symbol name

4:57 Empperi: well, clojure has several other naming conventions which differ from common lisp

4:58 first, rest vs car, cdr and so forth

4:58 TMA: first and rest are there in CL too :

4:58 Empperi: but car cdr is not in clojure

4:59 they've been slowly renamed by lisp community over the decades

4:59 the original were pretty aptly named considering what they actually did

4:59 but current implementations of eg. clojure have nothing to do with that

4:59 they just happen to solve the same problem

5:01 TMA: yes, clojure being a lisp-1, its users might appreciate that they can use car as a variable name for holding vehicle data without shadowing the list destructuring primitive

5:02 Empperi: hehe

5:03 TMA: which unfortunately does not extend to the ability to name the list parameter list in a generic list utility function

5:04 profil: Empperi: no currying is like "(+1) :: Int -> Int", written i haskell. Which clojure does not have due to multi arity?

5:05 Empperi: profil: I know what currying is

5:05 and multi-arity does complicate things

5:05 TMA: ,(let [+ *] (+))

5:06 clojurebot: 1

5:06 Empperi: but this comes to the same discussion as with recur and TCO

5:06 when it comes to recur I actually prefer the way it's in clojure

5:07 when talking about currying I'm not sure

5:07 profil: prefer to what?

5:07 Empperi: prefer to automatic TCO

5:07 like it's in haskell and in so many other languages

5:07 although in Haskell automatic TCO is less hazard since the whole language is lazy

5:08 TMA: what hazard it is?

5:08 Empperi: I like the fact that clojure compiler tells me if something can be tail call optimized

5:08 and that I can't by accident make a normal recursive call when I meant it to be TCOd

5:09 the additional "recur" is minimal overhead and actually provides better readiblity too imho

5:09 the whole discussion with currying and partial is similar

5:09 TMA: I do not concur.

5:09 Empperi: but there true currying would be more useful

5:10 TMA: The recur is a stopgap measure.

5:10 Empperi: so like I said, I wouldn't mind true currying in Clojure but I'm fine with current implementation too

5:11 j-pb: currying breaks varargs

5:11 Empperi: yup, also mentioned above :)

5:11 j-pb: ah yeah sorry

5:11 TMA: it shifts the burden of doing TCO from the machine to the programmer. And frankly it's the programmer's mind capacity that is the limiting factor these days.

5:12 j-pb: well varargs are such a big part of clojure that I don't think curring would work

5:12 Empperi: TMA: maybe but at the same time I've seen bugs in TCOd languages where the programmer had thought the compiler would take care of the optimization but he had by accident caused a regular recursion

5:13 with Clojure you can't do that bug

5:14 TMA: Empperi: could you provide me with an example of such a situation?

5:14 Empperi: usually bugs like that occur when you modify existing code which had been TCOd and after your modifications it isn't

5:14 TMA: any recursion call which isn't in tail call position

5:15 even more easy with mutual recursion

5:15 TEttinger: Empperi, you totally can in clojure, by using recursion without using loop

5:15 Empperi: to do that bug

5:15 TEttinger: thankfully we have loop :)

5:15 TMA: Empperi: I seek the example, that would be avoided in clojure.

5:15 Empperi: TEttinger: hmm? That's what I said? That if you use 'recur' compiler tells you if your making the call from non tail position?

5:16 sure you can blow the stack by normal recursion but then you're not using recur

5:16 TEttinger: yeah, I mean something like... that, yes

5:16 TMA: ah

5:16 now I see

5:16 TEttinger: if someone assumed clojure had TCO, that would be silly, but would soon blow the stack

5:16 Empperi: yup

5:16 TEttinger: I do think explicit recur makes sense

5:17 Empperi: indeed

5:17 in the beginning I thought it was a dumb idea but these days I think it is better than automatic TCO

5:17 TEttinger: I think clojure's emphasis on preferring map, reduce, filter, etc. and combinations of them makes even more sense

5:17 TMA: recur contains an assertion "I am called in tail position" and the compiler checks that

5:17 Empperi: TMA: yeah

5:17 since then compiler can be sure you really wanted tail call optimization

5:18 while with automatic TCO compiler can't make such assumptions

5:18 TEttinger: also, recur I believe is very handy in translating to better bytecode instructions, though I'm not sure

5:18 Empperi: anyway, partial isn't equal to recur but it is it's distant relative :)

5:19 there too you tell explicitly to the reader that you are currying the function

5:19 TEttinger: (I believe a call to loop can compile down to approximately the same bytecode as java's for or foreach loop, though I don't know which)

5:19 Empperi: while with true currying you have to know the function being curried that how many arities it has

5:19 that will it call the function or just create a new one

5:19 TMA: I can envision (declare (tail-call)) or some other marking that would permit the check that in other languages

5:20 Empperi: TMA: yes, and such things do exist

5:20 eg. in scala

5:20 TEttinger: but the JVM still lacks TCO even there

5:20 Empperi: yup

5:20 it's done completely on the compiler

5:20 if it's done at all

5:24 TMA: lack of support for TCO in JVM is one of my pet peeves. it prevents me to use my usual recursive programming style in Java. It makes me reconsider and rewrite in an inferior way (in a readability sense)

5:25 Empperi: well, in Java we have this thing called for loop for TCO (troll)

5:25 I seriously think that IRC needs a trollface emoticon

5:30 j-pb: wh not have both? :D

5:30 r4vi: so I might have to write some Java soon (holdme)

5:49 dysfun: Empperi: no, in that sense defn would also be TCO. ITYM 'recur' :)

6:04 kaiyin: (defn- expired? [[id session]] (pos? (- (:ring.middleware.session-timeout/idle-timeout session) (current-time)))) Shouldn't it be neg? here?

6:04 current-time is always increasing.

6:09 TMA: Empperi: yes, indeed. [response in re: IRC emoticon need]

6:11 kaiyin: Anyways this is a clj file generated by `lein new luminus`, should I file a bug report somewhere?

6:18 kaffeeboehnchen: Anyone who can help me with http-kit? I can start the server without an error but not connect :( https://paste.xinu.at/m-AByN/

6:18 TEttinger: kaiyin: I'd assume it's because it's a check for expiration, and (:ring.middleware.session-timeout/idle-timeout session) returns a larger number if it has timed out, but I'd verify the behavior is wrong first

6:19 kaiyin, sure seems weird, but it may have a reason

6:20 kaiyin: TEttinger: ok, I am not in a hurry, :-), just learning stuff.

6:22 TEttinger: kaiyin, there's a lot I'm not sure about there, is that copied from somewhere online and link-able?

6:23 in particular, I may have the wrong middleware I am looking at: https://github.com/ring-clojure/ring-session-timeout/blob/master/src/ring/middleware/session_timeout.clj

6:23 kaiyin: TEttinger: no, but if you run lein new luminus myapp, and check myapp/src/hipstr/session.clj , you should see the same.

6:24 marbetschar: Hi @all! Are there any good Datomic ressources out there for start playing with it?

6:25 kaiyin: sorry, it's myapp/src/myapp/session.clj , but you probably got it.

6:27 TEttinger: ohhhhh that's why it's so weird...

6:27 ,(:ring.middleware.session-timeout/idle-timeout {:ring.middleware.session-timeout/idle-timeout 42})

6:27 clojurebot: 42

6:28 TEttinger: it's getting that key from session, not actually calling a fn on session

6:28 the ket being :ring.middleware.session-timeout/idle-timeout

6:28 why it is called that, no idea

6:30 so that key is probably being set to when the session expires, as a number in seconds since the date/time that 0 is (january 1st 1970 I think)

6:30 meaning it expires in the future, unless the current time has caught up

6:31 naming is weird though, I think it's being used to test that things haven't expired?

6:32 kaiyin: TEttinger: than I imagine it should be named not-expired?

6:32 TEttinger: it's private, so I guess it doesn't matter. it's only used in one place

6:32 kaiyin: alright.

6:33 TEttinger: ah, yeah, it is weird but

6:33 (clojure.core/swap! mem #(->> % (filter expired?) (into {}))))

6:35 that takes mem, which is an atom that will contain a map of ids to sessions, and replaces its value with all id/session pairs that expired? returns true for, then sticks those back in a map and makes that the new mem

6:36 expired? returns true if the time the session expires is later than the current time

6:36 so it is taking out any sessions that have expired, because those returned false

6:36 it could definitely be clearer if they used neg? and remove or made it alive? instead of expired?

6:37 kaiyin: TEttinger: yeah.

6:38 TEttinger: and the keyword with a / is just bizarre...

6:39 it looks like that's all meant to be close to internal only, so I guess if it hasn't needed changing they haven't changed it

6:43 kaiyin: Could anyone help me understand this error? https://gist.github.com/kindlychung/c4571765ab3c07e3533e

6:45 If I have modified some clj file after starting lein ring server, what should i do to make this modification take effect?

6:46 mmeix: restart the server (I guess)

6:48 Compojure has "wrap-reload"

6:51 kaiyin: thanks.

6:52 mmeix: sorry... Ring I meant

6:53 https://ring-clojure.github.io/ring/ring.middleware.reload.html

6:56 oddcully: isn't namespacing this map key there actually a nice thing to do?

6:57 mmeix: you mean :dirs ?

6:57 oddcully: i meant :clojure/TEttinger ;P

6:58 mmeix: ah, ok

6:58 (brain in economy drive here)

6:58 TEttinger: oddcully, i didn't know that namespaced it, since / doesn't namespace normally...

7:04 Bronsa: TEttinger / in symbols and keywords is only allowed once and precisely to namespace it

7:04 and it's not uncommon at all

7:13 mskoud: Is there a way to call a function when using deconstruction. I'm using something like (defn route-erp-customer [{{id :id} :params :as req}] , but id i a string and i would like to convert it to an int...

7:20 sdegutis: Is Clojure suitable for parsing a pretty well structured HTML file?

7:24 J_A_Work: sdegutis: This should do nicely: https://github.com/davidsantiago/hickory

7:24 sdegutis: I LIKE!

7:25 lemme try it on my doc

7:26 J_A_Work: Also this; fewer features, but might work fine if all you want is hiccup results. https://github.com/nathell/clj-tagsoup

7:26 <3 hiccup

8:04 pandeiro: anyone know how I can get liberator to return an image resource (eg image/jpeg)? I've put "image/jpeg" in the :available-media-types but when I try to retrieve the resource, I get 'org/apache/commons/compress/archivers/StreamingNotSupportedException' as a response

8:07 (in :handle-ok I'm returning (ring-response {:status 200 :headers {"Content-Type" mime-type} :body (io/input-stream image-bytes)}) ... thinking liberator should support input streams)

8:12 wombawomba: What's the easiest way to make ring log all requests to stdout?

8:12 pandeiro: wombawomba: easiest imo would be a middleware fn that does a println

8:12 Empperi: guess I'd make a middleware

8:12 yeah

8:12 wombawomba: I figured I'd use https://github.com/pjlegato/ring.middleware.logger , but it seems to use https://github.com/pjlegato/onelog , and making that log to stdout seems complicated

8:12 Empperi: (defn logging-mw [handler] (fn [request] (println request) (handler request)))

8:13 that's it, just add that to your ring handler

8:13 tdammers: how about timber

8:13 doesn't that do what you need?

8:13 pandeiro: timbre yeah has more advanced features, prints the ns, level etc

8:13 tdammers: timbre*

8:15 pandeiro: seems my problem above is with pantomime.mime/mime-type-of, not liberator per se... huh

8:17 jtmarmon: how do you structure a system of components so that the components know that they're in testing/dev/prod mode? in testing, for example, I'd want my "twilio" component to use twilio's magic numbers instead of trying to register real twilio numbers, but that isn't something that can just be tuned by the component inputs (since the inputs to the twilio component are just account credentials - number purchasing is automated)

8:17 pandeiro: jtmarmon: environment variables?

8:18 snowell: jtmarmon: https://github.com/weavejester/environ

8:19 jtmarmon: hmmm..it seems to me that using env vars would sort of void the purpose of letting component manage dependency injection. now you have two sources of truth for configuration to worry about

8:20 rather than just a test config map, prod config map, etc

8:20 pandeiro: jtmarmon: i haven't used component a lot but couldn't the twilio component depend on the config component or something?

8:21 and then the config component sources its data acc. to env

8:22 jtmarmon: pandeiro: right that's my intention - having the config indicate to components what state they should take. it just seems messy to pass in an indicator like (->Twilio "accountsid" "authtoken" :test) to every component that has special state during test mode.. i guess there's not really a better way to do that

8:22 can you have variadic argument record constructors?

8:23 oddcully: map->Twilio perhaps?

8:25 jtmarmon: oddcully: i'm not quite clear on what the map->* syntax actually does. can you clarify for me?

8:27 pandeiro: jtmarmon: turns a map into a record i believe

8:27 oddcully: it constructs you a record from a map (with keywords like your attributes in the record)

8:28 jtmarmon: got it, ty.

8:33 pandeiro: anyone experienced w/ pantomime/tika know why org.apache.tika.Tika.detect() would be throwing a org/apache/commons/compress/archivers/StreamingNotSupportedException on a [B input?

8:34 TEttinger: [B being bytes?

8:34 ,bytes

8:34 pandeiro: TEttinger: yeah, right?

8:34 clojurebot: #object[clojure.core$bytes 0x59424635 "clojure.core$bytes@59424635"]

8:34 pandeiro: is that not the same as a byte array? :)

8:34 * pandeiro blushes at his own java ignorance

8:35 TEttinger: [B is the actual type of a primitive byte array, yeah

8:35 but you can also call it, conveniently, bytes, in type hints

8:35 ,(type (bytes [1 2 3]))

8:35 clojurebot: #error {\n :cause "clojure.lang.PersistentVector cannot be cast to [B"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentVector cannot be cast to [B"\n :at [clojure.lang.Numbers bytes "Numbers.java" 1371]}]\n :trace\n [[clojure.lang.Numbers bytes "Numbers.java" 1371]\n [sandbox$eval47 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6792...

8:35 TEttinger: hm

8:36 pandeiro: right I see that in pantomime's protocol implementation signatures

8:36 TEttinger: I think bytes is just the cast

8:36 so what class throws this?

8:36 it's possible you need to wrap the byte[] somehow so it can stream it

8:36 pandeiro: java.lang.NoClassDefFoundError: org/apache/commons/compress/archivers/StreamingNotSupportedException

8:37 TEttinger: what code throws the error

8:37 pandeiro: TEttinger: https://github.com/michaelklishin/pantomime/blob/master/src/clojure/pantomime/mime.clj#L50-L53

8:38 ...as far as I can tell...

8:40 TEttinger: https://github.com/apache/tika/blob/trunk/tika-core/src/main/java/org/apache/tika/detect/Detector.java#L57

8:41 detect takes an InputStream, and I don't think a byte array can be cast to that

8:41 kwladyka: I am looking in Clojure web framework something similar what Laraver has, for example: return redirect()->back()->withInput()->withErrors($errors); - it redirect to site from request was sended with field inputs and with error msg.

8:41 It is very usefull with POST forms

8:42 TEttinger: huh, never seen (extend byte-array-type

8:42 pandeiro: TEttinger: thanks... odd thing is it works fine in the tests where i generate base64 on the jvm side (then convert to [B, stick in postgres, retrieve at bytes and then extract mime type)...

8:42 s/at/as

8:42 TEttinger: pandeiro, right, there aren't bytes on JS

8:43 pandeiro: yeah so the http handler expects base64 and then does the decoding

8:43 thought maybe the browser's base64 encoding is funky but the file seems identical

8:44 weird thing too is even wrapping pantomime.mime/mime-type-of in a (try ...), the exception 'escapes'

8:45 didn't know that was even possible?

8:49 TimMc: That sounds like something deeper is wrong, like you're looking at the wrong source.

8:49 pandeiro: TimMc: hmm... yeah...

8:50 TimMc: because that sounds impossible

8:50 pandeiro: TimMc: ok good to know, gotta dig through it... but it is the only place in the entire source tree where that namespace and function are used

8:51 and when I comment it out, no exception

8:53 (catch Exception e ...) should catch anything right?

8:57 dnolen: ClojureScript can now compile ClojureScript, only trivial things working but still fun https://github.com/swannodette/cljs-bootstrap

8:57 TimMc: pandeiro: Oh, is this Clojure or CLJS?

8:57 pandeiro: TimMc: clojure

8:57 TimMc: Try Throwable? What is being thrown?

8:57 pandeiro: java.lang.NoClassDefFoundError: org/apache/commons/compress/archivers/StreamingNotSupportedException

8:58 could this be a crazy commons compatibility thing/

8:58 TimMc: Oh yeah, Error is a sister class to Exception, so that's why you couldn't catch it.

8:59 pandeiro: TimMc: ah, so if I want to catch *everything*, I use Throwable?

8:59 TimMc: Yeah, but it can be a bad idea. :-P

8:59 pandeiro: why?

8:59 clojurebot: why is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone

9:01 TimMc: Some Throwables are things like ThreadDeath, and you really want those to propagate. It's fine for logging purposes (but then you should rethrow), or if a thread absolutely, positively must not die.

9:01 I don't remember the details, and it's a bit folkloreish, unfortunately.

9:02 pandeiro: huh, even with (catch Throwable ...) the error/exception propagates

9:02 TimMc: That's alarming.

9:02 pandeiro: I'm alarmed.

9:02 TimMc: It must not be thrown in that scope, then.

9:03 Do you have a stack trace that actually implicates that fn, or could it be a compile-time error?

9:03 pandeiro: sure one sec

9:04 http://sprunge.us/dBFF

9:05 TimMc: Well, that's pretty clear, I guess.

9:06 I've never heard of (catch Throwable) not catching everything, though, so we're missing something.

9:06 pandeiro: what would the realm of possibilities include?

9:07 i'd really like to leave the mime detection stuff in place and be able to (try ...) in order to just revert to another heuristic or something if/when tika explodes like this...

9:08 TimMc: Well, the class not found could be a dep mismatch; see if `lein deps :tree` turns up any Commons version mismatches.

9:08 pandeiro: dunno if it matters but the code in question is here: http://sprunge.us/bDaL

9:11 TimMc: What is mime-type-of? Is it a macro? I don't see it in the stack trace, and I don't see the definition.

9:11 pandeiro: huh, don't see a direct conflict: http://sprunge.us/PIFG

9:11 pantomime.mime/mime-type-of, sorry

9:11 i :refer it

9:12 TimMc: So, is it a macro?

9:12 pandeiro: no it's a protocol... 'method'?

9:12 being given a byte-array

9:13 so should be this: https://github.com/michaelklishin/pantomime/blob/master/src/clojure/pantomime/mime.clj#L50-L53

9:14 TimMc: I see, that's why it's an anonymous fn in the stack trace.

9:14 pandeiro: yeah that's something i don't like about record/protocol-y stuff :/

9:15 ha

9:15 removing selenium from my deps at least gets me my (try ...) back :)

9:16 TimMc: You're able to catch now?

9:16 pandeiro: yep

9:16 TimMc: yikes

9:16 pandeiro: :)

9:17 tell me about it

9:17 TimMc: what the hell

9:17 pandeiro: it's odd that lein deps :tree didn't complain about any commons-* conflicts

9:18 but that stuff is in 20 different packages it seems so maybe that's why... maybe the dep graph is crazy between those things

9:18 TimMc: super grateful for the help, TEttinger: you too

9:19 TEttinger: I'm glad I could help, even if most of the time I was helping my kitten catch a june bug

9:20 TimMc: TEttinger: That's important.

9:20 pandeiro: yeah a bug's a bug

9:20 TEttinger: (inc kittens)

9:20 pandeiro: i need a cigarette

9:20 TimMc: (dec kittens)

9:20 just kidding

9:20 (inc kittens)

9:21 amalloy_: botdead

9:21 TEttinger: http://i.imgur.com/3ma6cRl.gifv

9:21 TimMc: amalloy_: It's important, I need to give karma to kittens.

9:35 TEttinger: Adorable.

9:36 TEttinger: it's octocat!

10:23 irctc: I'm trying to come up with a way of parallelizing my reduce of a huge seq of maps. Order is not important. The vanilla reduce function is to assoc several calculations onto the map. This is pure CPU bound processing (calculating geometric average with BigDecimal). All the fold examples I'm seen are virtually identical, counting items in a map.

10:24 Anybody have experience with reducers r/fold r/monoid and combining maps back into a vector?

10:25 benhuda: hello

10:26 irctc: benhuda: ciao!

10:38 phillord: Is there a function in clojure that has the "nil-safe" capabilities of some-> but doesn't do the threading

10:39 so transforms (a (b (c 1))) into something that returns "nil" if any of the c, b or a calls return nil?

10:40 pwzoii: maybe monad?

10:40 phillord: would that design work?

10:41 phillord: pwzoli: in what sense? I mean, some-> has two functionalities -- should be possible to do them both?

10:41 or rather do them independently

10:42 profil: phillord: and?

10:43 phillord: I was wondering if there were a way -- I not a great fan of threading, but I need the nil short-circuiting

10:43 stuartsierra: phillord: There's nothing built-in that does this. It would have to be a code-restructuring macro like `some->`

10:44 phillord: `fnil` can make a single function "nil-safe" with a default value.

10:44 * phillord shakes his head

10:44 profil: phillord: (and (fn1) (fn2) (fn3))

10:45 phillord: no I need it to short-circuit -- the late stuff fails

10:45 profil: and does short-circuit

10:45 phillord: profil: nope, I need to pass values between fn1,fn2 and fn3

10:45 profil: without threading? why?

10:45 phillord: never mind, was just curious -- will use threading instead

10:46 profile: I may be in a minority, but personally, I find the threading a little confusing

10:46 profil: (-> 1 (c) (b) (a)) is equal to (a (b (c 1)))

10:47 which means that the threading is done the "right" way

10:47 pyrtsa: phillord: I once did this silly little write-up where you can short-circuit by binding (reduced expr) to some "ret" binding: https://gist.github.com/pyrtsa/1af9fdd56267a3631b0c#file-ret-clj-L3-L22

10:48 Becomes nicer if you use functions (or wrappers) that return (reduced x) in case of error.

10:49 phillord: pyrtsa: looks good -- something like a let binding would make sense!

10:49 thanks for suggestions!

10:50 pyrtsa: Yep, the transformation from (let [x expr1, y expr2] body) into (ret [x expr1, y expr2] body) is pretty straightforward, I'd say. :)

10:50 Then just make the exprs short-circuit when needed.

11:19 irctc: ,(require '[clojure.core.reducers :as r])

11:19 clojurebot: #error {\n :cause "Could not locate clojure/core/reducers__init.class or clojure/core/reducers.clj on classpath."\n :via\n [{:type java.io.FileNotFoundException\n :message "Could not locate clojure/core/reducers__init.class or clojure/core/reducers.clj on classpath."\n :at [clojure.lang.RT load "RT.java" 449]}]\n :trace\n [[clojure.lang.RT load "RT.java" 449]\n [clojure.lang.RT load "RT.java"...

11:19 irctc: ,(r/fold (r/monoid conj list) (r/map #(assoc % :b (inc (:a %))) [{:a 1} {:a 9}]))

11:19 clojurebot: #error {\n :cause "No such namespace: r"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: No such namespace: r, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "No such namespace: r"\n :at [clojure.lang.Util runtimeException "Util.java" 221]}]\n :trace...

11:33 justin_smith: irctc: I think it's because reducers use threads

11:35 irctc: justin_smith: Yeah, threads, security, etc. No worries. Once I looked at the impl of r/monoid, I saw the pattern. Just thought I'd post back the essence.

11:56 voidnoid: dunno if this is OT, can anyone recommend some good books that are more theory based?

11:57 I'm aware of SICP for example, but looking for some other suggestions too if anyone has them

11:59 justin_smith: voidnoid: joy of clojure has some good theory elements to it

12:00 voidnoid: justin_smith: cool thanks

12:01 hiredman: ~bookshelf

12:01 clojurebot: bookshelf is http://www.amazon.com/Clojure-Bookshelf/lm/R3LG3ZBZS4GCTH

12:02 kwladyka: hello justin_smith :)

12:03 mmeix: So palletop/leaven serves the same purpose as Component, right? Why would I chose one over the other?

12:03 justin_smith: kwladyka: hello

12:05 mmeix: * palletops/leaven

12:06 justin_smith: mmeix: I don't know leaven at all, but I do know that component has wider general adoption (and for me it works great)

12:08 mmeix: ok, thanks

12:14 justin_smith: oh - leaven looks good, and it's cljs compatible which is cool

12:17 but I like the way component has declarative deps vs. explicit dep order

12:17 I guess that's a style thing? that's the boot / leiningen difference too

12:17 the/a ?

12:37 devn: hello all

12:37 logback + clojure.tools.logging -- is that a thing?

12:41 mnngfltg: devn, I'm pretty sure you can use it, yes

12:42 doesn't logback simply implement the log4j api?

12:42 TimMc: We use that in a projector two, yeah.

12:42 *project or

12:42 devn: other question is -- timbre? decisions, decisions.

12:43 i have a situation or two where i'll need to refer to specific classes for things like Layout

12:43 it's not totally clear to me if timbre supports that, but i havent finished digging into it

12:43 * mnngfltg thinks there's nothing wrong with a log4j.properties file in /resources

12:45 devn: that's kind of how i feel about it

12:45 but timbre does have a few things that i'd like to have, utility-wise

12:45 but i suppose there's nothing that precludes me from just using those fns

12:46 justin_smith: log4j can have per-package config, right? like applying a different log level on a package basis?

12:46 I sometimes think it would be nice to be able to modulate logging per namespace

12:46 devn: justin_smith: yes you can do that

12:47 specifically thinking of stuff like logged-future, log-and-rethrow-errors, uncaught-jvm-exceptions! -- those are nice to have

12:47 justin_smith: cool, so I assume the per-package stuff using the namespace package might just work?

12:47 devn: mnngfltg: so are you using logback with a logback.xml?

12:51 mnngfltg: devn, no I used regular log4j

12:52 devn: ah ok

13:05 m1dnight_: seems like there is a meeting of the .be clojure community at my uni

13:05 they just invited me to come and listen :>>>

13:37 Guest53: Hi @all! I'm currently playing a bit with xmpp-clj, but in the repl it seems the bot is not keeping online?

13:37 (xmpp/start-bot :username "username" :password "password" :host "host" :domain "domain" :handler (fn [m] "Hi, I'm 'Bot'!")))

13:37 returns in REPL with {:default #<XMPPConnection org.jivesoftware.smack.XMPPConnection@12368a85>}

13:38 how to send/receive messages?

13:49 jtmarmon: how does one write tests for an application using components? I need access to the datomic connection so I can add test data - is there a way I can directly get components from the system without being a component myself?

13:59 tmtwd: (ns my.library) is a namespace or a module?

14:04 amalloy: tmtwd: there's not really any such thing as a module

14:04 tmtwd: oh ok

14:05 amalloy: that form creates a namespace named my.library, and doesn't put anything in it

14:05 justin_smith: jtmarmon: you can instantiate an individual component and call call start on it individually

14:06 no need to build a system if you only need one component for a test

14:06 tmtwd: how do you get just a plain clj repl running in emacs or the terminal?

14:06 (or lein)

14:06 justin_smith: likely you would pass in placeholders (somewhat like mocks) for any other components it expects to use

14:06 tmtwd: plain cljs, or lein?

14:06 err, clj

14:07 tmtwd: either

14:07 justin_smith: tmtwd: the easiest is java -jar clojure.jar

14:07 amalloy: tmtwd: if you have lein already, the easiest is lein repl

14:07 tmtwd: ah ok

14:07 justin_smith: where you likely have clojure-foo.jar in your ~/.m2/ somewhere already

14:07 amalloy: yeah, you are right, I meant "simplest" not easiest

14:09 amalloy: justin_smith: an interesting proposal. yours is certainly simplest from clojure's POV, but i wonder if lein repl is simpler from the user's point of view since it doesn't entangle notions of what filesystem paths the relevant jars are on

14:12 oddcully: yet nothing what an alias cant fix for repetitive use

14:12 and some nice rlwrap-ping

14:13 TimMc: and pretty soon you've built lein

14:40 justin_smith: amalloy: I perhaps misunderstood the thing required - "plain clj repl" to me implied just clojure with no project deps

14:40 amalloy: and reliably getting that from lein would likely require some weird hoops

14:41 (my brain is a bit scattered today)

14:41 amalloy: probably it would, indeed. the requirements were not spelled out to an exacting level of detail, and we filled in the blanks differently

15:07 pandeiro: why might tika bork on trying to detect bytes received via jetty/http, but not when simulating the requests/response with peridot?

15:09 it's [base64 -> bytes -> tika -> mime type string] both days

15:09 i've compared the base64, identical... how can i compare the bytes?

15:09 justin_smith: pandeiro: are you sure the http stream is base64? and not the bytes themselves?

15:10 identical base64 will always be identical bytes

15:10 pandeiro: justin_smith: yeah for sure, i'm sending it base64 intentionally

15:10 right and because it's ascii encoding couldn't be it, right?

15:10 (like jetty doing something weird)

15:10 justin_smith: yeah, valid base64 only uses the ascii subset

15:11 unless one side is using utf16?

15:11 something that is not ascii compatible

15:11 pandeiro: javascript uses utf16 internally but i don't think that's it

15:11 justin_smith: java also uses utf16 or something very close to it internally

15:11 pandeiro: i've compared the base64 i get from the browser and what my tests produce and it's identical

15:12 justin_smith: if you had a utf8/ascii string on one side, and utf16 on the other, and they were being processed the same, you could see some issue

15:12 OK

15:14 pandeiro: another weird possibility: a lein development profile task running and a test profile task could have different versions of common deps potentially, i wonder?

15:15 i keep thinking my issue must be related to conflicting versions of apache commons stuff, but i don't see it in lein deps :tree

15:15 and there is only one version of tika anywhere

15:16 justin_smith: compare the numeric output of (.getBytes s) for the base64 strings on each side

15:16 (into [] (.getBytes s)) might be more convenient to read

15:17 ,(into [] (.getBytes "hello" "UTF-16"))

15:17 clojurebot: [-2 -1 0 104 0 ...]

15:17 justin_smith: ,(into [] (.getBytes "hello" "UTF-9"))

15:17 clojurebot: #error {\n :cause "denied"\n :via\n [{:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]}]\n :trace\n [[clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]\n [clojurebot.sandbox.proxy$java.lang.SecurityManager$Door$f500ea40 checkPropertyAccess nil -1]\n [java.lang.System getProperty ...

15:17 justin_smith: ,(into [] (.getBytes "hello" "UTF-8"))

15:17 clojurebot: [104 101 108 108 111]

15:17 pandeiro: justin_smith: nice, let me try that

15:20 ouch printing byte arrays into emacs shell buffer

15:27 byte arrays are identical...

15:45 pbiggar: anyone know a nice way to retry clojure.test tests if they fail? we have some flaky tests that I'd love to just retry 4-5 times (until they pass at least once)

15:46 (so I'm looking to do something like wrap them in a middleware where if the test fails its retried and if it succeeds it isn't marked as a failure)

15:58 zerokarmaleft: pbiggar: imho, at that point I think you have to ask yourself if those tests are providing any value

15:59 pbiggar: zerokarmaleft: Already did :) They provide a lot of value. But they're unreliable. Deleting them sucks. Keeping them being unreliable sucks. Retrying them doesn't suck

16:00 zerokarmaleft: is there any way to adjust the seam along which you're testing so that you can rewrite the tests to be deterministic?

16:00 pbiggar: they test against an unreliable 3rdparty service

16:00 so no

16:00 mocking isn't an option for this test

16:01 TimMc: pbiggar: Write a lazy seq that runs the fn under test, filter it for the desired answer, and test that you get at least one valid.

16:01 Also say 3 Hail Marys.

16:02 pbiggar: @TimMc: interesting. OK, will try that. Very smart, thanks!

16:02 TimMc: Maybe also donate to a charity.

16:03 pbiggar: TimMc: what about the (is) calls in the fn. Won't they update the global count?

16:05 TimMc: Only one (is) call. (is (not= (first (filter is-valid? (repeatedly 5 the-test))) nil)) or something.

16:06 pbiggar: i was thiking about putting the (is) calls in the test, so that it doesn't really change how we write tests

16:06 TimMc: Well, that won't get you what you want.

16:06 pbiggar: so something like (deftest my-test-name (with-retries 5 ....)

16:06 TimMc: I don't know enough about clojure.test in order to write that. My suggestion will "work" without any extra research.

16:07 pbiggar: maybe if I bind the assertion failure counts. starting to get messy

16:07 TimMc: yes, it will

16:07 TimMc: It *should* look ugly. :-)

16:08 pbiggar: That isa philosophy I don't subscribe to :)

16:08 looks like I can bind do-report

16:13 kaiyin: I hate to have to deal with html and css stuff, what libraries should I learn if want to develop a website using just clojure and clojurescript?

16:15 TimMc: pbiggar: If it's too easy to use, people will use it.

16:15 Remember to test that any failures are the expected kind of failure, otherwise you'll miss real failures of other sorts.

16:16 kaiyin: You'll still have to deal with HTML and CSS. :-)

16:16 kaiyin: ok, :-(

16:16 they are just ugly.

16:16 TimMc: I won't dispute that. :-)

16:18 There's a safe version of Hiccup you can use: https://github.com/ato/clojars-web/blob/master/src/clojars/web/safe_hiccup.clj (Don't use unmodified Hiccup, you'll get cross-site scripting vulnerabilities in your website.)

16:18 eriktjacobsen: /join #leiningen

16:18 whups

16:21 Does anyone have any good guides on running down compile issues? We had some conflicting versions, so I started normal route of “lein deps :tree” and start adding exclusions. The problem is now I’ve hit a brick wall in that I am getting notice a specific package is breaking, but that package has no shown dependency issues and all the correct versions should be loading for it. The compile error and output from deps is

16:21 here: https://gist.github.com/eriktjacobsen/9d02b57225db92dbe496

16:22 Adding the exclusions got me through a douplicate signer error and two other missing class issues, but those seem to have resolved via exclusions unrelated to the cheshire package

16:27 arohner: eriktjacobsen: are you AOT'ing?

16:27 eriktjacobsen: or depending on any packages that have been AOT'd?

16:27 eriktjacobsen: :aot :all

16:28 arohner: AOT also transitively compiles all dependencies

16:28 and .class files are loaded with higher priority than source .clj files

16:29 so for your deps to be respected, make sure your tree is clean, and make sure a dep isn't AOT'ing a lib version that you want to specify

16:30 pandeiro: arohner: if a dep *were* AOT'ing a lib, that version would be reflected by `lein classpath` right?

16:30 (i'm also in dep hell right now [i think])

16:31 arohner: pandeiro: I don't think so

16:31 eriktjacobsen: well, I do run lein clean before each compile, so no classes in target/. I’m guessing next step is to remove :aot during conflict resolution. How would I tell if a dep was AOT’ing a lib version I wanted to specify

16:31 pandeiro: huh

16:31 arohner: pandeiro: lein dep tells you the lein/mvn .pom asks for, not what .class files are on disk

16:31 eriktjacobsen: inspect the jar for .class files :-/

16:31 pandeiro: arohner: ie, in `target/`?

16:31 or in .m2 as well?

16:31 arohner: pandeiro: could also have .class files in a jar

16:32 and that's the tricky one

16:32 pandeiro: so how does one get the definitive list of which versions of what are being loaded by a lein process?

16:33 justin_smith: pandeiro: lein cp will generate the actual classpath used, and I have been able to plug that into an explicit java call

16:33 TimMc: Worst case you could launch a repl and ask for the .class and .clj resources.

16:34 pandeiro: there's no existing tool to diff classpaths from clojure right?

16:34 TimMc: or iterate through the classpath, call unzip -l on each one, and grep for the class.

16:34 pandeiro: It's not even the classpath that matters here, all you'll get is jars and target/ and such.

16:35 pandeiro: ah ok

16:35 TimMc: Where to look, not what's there.

16:35 arohner: pandeiro: what I'm trying to get at is there's only a loose connection between a version, and what actually gets loaded. If you have a "malicious library maintainer", they could AOT their lib against [foo "1.0"], set the project.clj to [foo "2.0"], and then zip up

16:36 pandeiro: your program downloads the lib, and [foo "2.0"], but because AOT, the foo 1 classfiles get loaded

16:36 now, that's an extreme case, and unlikely

16:36 but I've seen similar things in the wild

16:36 pandeiro: yeah, i wish mine were that exciting but i'm sure it's more banal than that

16:37 i get a ClassNotDefError when i run code with profile dev, but not with test

16:37 same code

16:37 looking at lein classpath from both profiles shows the same version of the package with the class in question

16:38 amalloy: pandeiro: i don't think there's any such thing as a ClassNotDefError. if you are going to tell people error messages, they should probably be the actual error messages, copy/pasted

16:38 pandeiro: amalloy: sure good point

16:38 NoClassDefFoundError

16:39 TimMc: ,(defn foo [] )

16:39 clojurebot: #'sandbox/foo

16:40 TimMc: ,(.getResource (class foo) "clojure/core__init.class")

16:40 clojurebot: nil

16:40 TimMc: ,(.getResource (class foo) "clojure/core.clj")

16:40 clojurebot: nil

16:40 TimMc: Interesting. But run those locally, you'll see the clj and class files be found.

16:41 (I'm using fn's class because it's a cheap and dirty way to get the right classloader.)

16:48 As a bonus, it will tell you where it found them. :-)

16:48 pandeiro: TimMc: yeah i tried it at the repl, that's cool

16:49 unfortunately i don't see how to really apply that to my problem

16:49 i have to figure out the filepath of where the the not Def'd class ought to be, i guess?

16:50 i tried (println (.getResource org.apache.commons.compress.archivers.StreamingNotSupportedException "org/apache/commons/compress/archivers.class")), which is wrong apparently

16:53 tried the file 'org/apache/commons/compress/archivers/StreamingNotSupportedException.java' (where it exists in the commons-compress src) too, grasping at straws here...

17:00 matthavener: is (seq X) idiomatic for (not (empty? X)) ?

17:00 pandeiro: matthavener: there's (not-empty x) too

17:01 matthavener: ah cool, thank you

17:02 amalloy: ugh do not use not-empty for that

17:02 that is what seq is for

17:03 AimHere: What's not-empty for then?

17:04 matthavener: from amalloy: http://stackoverflow.com/questions/3118962/what-is-the-correct-clojure-way-to-check-if-a-collection-is-non-empty#comment7947976_3120045

17:04 amalloy: it is for when you need to test for emptiness but not convert it into a seq if it's non-empty

17:04 eg (when-let [xs (not-empty (build-some-map)] (...use xs as a map))

17:07 TimMc: pandeiro: Oh, I got two conversations confused. That was actually for eriktjacobsen, I think.

17:07 eriktjacobsen: TimMc: “Worst case you could launch a repl and ask for the .class and .clj resources.” How would I go about doing that? If I remove :aot then I can start the repl, and even (require ‘cheshire.core) and see the same error message

17:08 Also sanity check: in cheshire it complains about tag not being public…. in generate.clj there is a (defmacro tag), and in generate_seq.clj there is (:use [cheshire.generate :only [tag]]) in the namespace…. and the latter is whats failing

17:09 csd_: When I try to cider-jack-in, it tells me I'm connected to the nrepl but doens't actually open a window with the repl. When I look at the buffers, I see it creates 2 nrepl buffers, one for "server" and the other for "connection". As I recall from using cider before, there should only be one nrepl window and another window labeled cider .... What might be causing this?

17:09 eriktjacobsen: afaik defmacro should be public for the :use… so just in case there is some unrelated to compiling issue this might be source problem

17:09 TimMc: eriktjacobsen: The method I described would only help you probe for AOT'd versions of a specific namespace, unfortunately.

17:09 I don't know if an easy way to search for such things.

17:10 eriktjacobsen: TimMc: so if I take out AOT and merely try to require the offending library from the repl and get same error message… any idea how I’d start running down the issue? It doesnt seem to be a problem with this often used library so I’m 99% sure its my local environment

17:12 pandeiro: csd_: the nrepl-server buffer may have useful info

17:12 csd_: pandeiro: alas, it does not :-/

17:12 pandeiro: sometimes it's just downloading 200 dependencies and taking a while

17:13 nothing at all?

17:13 csd_: it just says im connected, have a nice day

17:14 eriktjacobsen: TimMc: also I’m a bit of a loss as to what you were using the second argument of getResource… I can (require ‘cheshire.generate) without error but can’t call “ (.getResource (class cheshire.generate))”

17:16 jcrossley3: csd_: pandeiro: i'm seeing the same

17:17 csd_: jcrossley3: think its a bug?

17:17 pandeiro: brand new cider?

17:17 csd_: yeah

17:17 jcrossley3: yep, 0.9.0

17:19 pandeiro: working for me with cider-20150615.1053

17:19 (0.9.0-SNAPSHOT)

17:19 csd_: pandeiro: would i need to use git to dl that?

17:20 pandeiro: csd_: no just emacs

17:20 with the melpa repo enabled

17:20 that will get the latest snapshots

17:20 csd_: ah looks like i installed from melpa-stable

17:21 TimMc: eriktjacobsen: You need to get ahold of a Class that has the right classloader. The Class of a function defined in your program works for that.

17:22 freeone3000: I'm trying to get my first clojure application working, an anagram finder. My application so far looks like: https://gist.github.com/freeone3000/19d6224a8d2dd7142274 . my errors are included in the paste. Where am I attempting a cast?

17:23 TimMc: If you take out AOT from your own llib, you still have to contend with the possibility of an AOT'd library conflicting with a dependency. Let's say you depend on Bar and Baz, and both depend on Foo.

17:23 If Baz is AOT'd then you'll have the Foo dependency on your classpath, but also Baz's compiled version of it.

17:23 eriktjacobsen: TimMc pretend I know nothing about java/ jvm (I’ve been progrmaming in clojure for years but rarely have to worry about the java backend). where would I find the class of a defined function?

17:24 Gotcha about AOT’d dependencies

17:24 TimMc: Just like I demonstrated -- (defn foo [] ) and use (class foo) as your Class. The explanation is kind of complicated, I can't provide it at the moment.

17:24 eriktjacobsen: Ok. So class = function name?

17:24 TimMc: No, each Clojure function is backed by a Class.

17:24 ,(class +)

17:24 clojurebot: clojure.core$_PLUS_

17:25 amalloy: freeone3000: you want (defn frequency-table [words])

17:25 TimMc: ,(Class/forName "clojure.core$_PLUS_")

17:25 clojurebot: clojure.core$_PLUS_

17:25 csd_: pandeiro: its giving me an error saying my nrepl version is 0.2.6 when im using the 0.9.0 release. any idea what that's about?

17:25 jcrossley3: csd_: this may help: https://github.com/clojure-emacs/cider/issues/1050

17:26 freeone3000: amalloy: Ah, I accidentally a reserved word. Thanks.

17:26 amalloy: well actually you aren't even using that words argument

17:26 no, i don't think you did

17:26 freeone3000: amalloy: So why "words" and not "word"?

17:26 amalloy: freeone3000: i guess i am confused. it doesn't seem like your source file, as written, should cause that error

17:26 eriktjacobsen: TimMc: I’m trying to require cheshire.generate-seq but it is failing, so I can’t use anything in there as a function… likewise my own project’s core.clj includes the cheshire so it also will fail in a (require).. what function should I be putting into class? Just a random function I create in the repl itself?

17:27 freeone3000: amalloy: But "words" instead of "word" fixes it.

17:27 amalloy: uh

17:27 freeone3000: the important change was removing the &, not the name change

17:27 but i think if you change it back it should still work

17:27 clojurebot: It's greek to me.

17:27 amalloy: because you aren't even using the argument, and the name you give it doesn't matter at all

17:28 freeone3000: amalloy: Ah. Okay.

17:28 eriktjacobsen: TimMc: I’ve tried that, and upon entering (.getResource (class foo)) I get “No matching field found: getResource for class java.lang.Class"

17:28 TimMc: eriktjacobsen: You ned to ask it for a resource. (It needs another argument.)

17:30 freeone3000: amalloy: Okay, it looks like there's some change between when I make a code change and when running the program gets different results. is there a clojure agent or something similar to the scala agent that could cause problems like this?

17:30 eriktjacobsen: Gotcha, thanks. per my previous msg: “also I’m a bit of a loss as to what you were using the second argument of getResource”. So what is the other argument “cheshire.generate-seq” as this is the failing to compile file?

17:31 justin_smith: (inc eastwood)

17:31 lazybot: ⇒ 9

17:31 justin_smith: finds my bugs :)

17:31 amalloy: freeone3000: no. possible causes might include AOT, but it doesn't look like you're doing any; or your IDE is doing some funny business; or you are expecting changes to be applied before you press Save or something

17:31 TimMc: eriktjacobsen: You're asking the JVM to find the actuall .class and .clj files in the jars.

17:32 It's a quick way of searching the jars, subject to the limitation of your classloader.

17:33 eriktjacobsen: Alright, I believe I understand what you’ve said, however I’m not sure how that relates to the second argument. Is that the “actual clj files” in the jars? I’ve been throwing random strings at it, and I do get back something for “cheshire/core.clj” and the other files.

17:33 Ok so I’m getting back: user=> (.getResource (class foo) "cheshire/core.clj") #<URL jar:file:/Users/eriktjacobsen/.m2/repository/cheshire/cheshire/5.5.0/cheshire-5.5.0.jar!/cheshire/core.clj>

17:34 devn: how do i prevent clojure.tools.logging from using commons-logging, and instead have it use log4j?

17:34 eriktjacobsen: All 3 source files in question (core, generate, generate_seq) all show up as coming from cheshire version 5.5.0, however it still won’t include with (require) as it is giving this “Tag not public” error.

17:37 TimMc: eriktjacobsen: What if you look for cheshire/core__init.class ?

17:37 tcrawley: devn: I think (alter-var-root #'clojure.tools.logging/*logger-factory* (constantly (clojure.tools.logging.impl/log4j-factory))) should do the trick

17:38 eriktjacobsen: ah

17:38 timvisher: what's this error mean? `No namespace: foo, compiling bar` ?

17:38 eriktjacobsen: TimMc: AHA file:/Users/eriktjacobsen/.m2/repository/collectiveds/scraper/0.9.2/scraper-0.9.2.jar!/cheshire/core__init.class>

17:38 TimMc: There you go! The culprit.

17:38 eriktjacobsen: TimMc: How did you know to look at core__init.class, and where can I find a book or guide that would give me that same information in the future

17:39 TimMc: I happened to know that that's the format of classname that namespaces get compiled to. :-/

17:39 I think I knew that because of poking around in AOT'd JAR files or something.

17:40 eriktjacobsen: So why was looking at “cheshire/core.clj” giving me different than “cheshire/core__init.class”… because .class is higher precedence to .clj files? So I should always be inspecting with the “__init.class” appended to whatever I want to really look for?

17:40 TimMc: Maybe there's a book or guide that would tell you that but... unfortunately, I doubt there is.

17:41 Yeah, the classfile would be the first place to look. It's higher precedence in Clojure 1.6.0 and below. I think 1.7.0 switches it.

17:41 puredanger: no, it does not

17:42 TimMc: Huh. WHat does it change, then? There's something about this...

17:42 puredanger: the primary change in 1.7 is that class loads will now inspect the dynamic class cache before going to disk

17:42 but .class will still be picked over .clj if both are on the classpath

17:43 I have not read the back chat

17:43 so apologies if I'm missing all the relevant context :)

17:43 TimMc: Oooh, OK. I think I heard differently in the channel at some point.

17:44 puredanger: Context is dependencies and transitive AOT conflicts.

17:44 puredanger: well, there's a lot of subtleties :)

17:46 is this *while* compiling your own project perhaps?

17:46 uberjar for example?

17:48 I have to step away, but happy to discuss tomorrow if neede

17:48 TimMc: puredanger: Not my project, no.

17:49 Found the issue in eriktjacobsen's project, and am somewhat curious as to what I had misunderstood about .class vs. .clj precedence.

17:53 jcrossley3: csd_: you get it working?

17:54 csd_: reinstalling clojure-mode got things working for me

17:57 eriktjacobsen: TimMc: better question…. is AOT the specific reason this doesn’t show up with “lein deps :tree” ?

18:05 TimMc: eriktjacobsen: Yep.

18:06 justin_smith: ~clean

18:06 clojurebot: excusez-moi

18:17 pandeiro: anyone able to draw any leads from this: http://sprunge.us/SMhO

18:24 justin_smith: pandeiro: looks like you need to download the whole file before tika can tell you what it is?

18:24 pandeiro: justin_smith: yeah no it's downloaded, i'm testing with local files

18:24 justin_smith: http://commons.apache.org/proper/commons-compress/javadocs/api-1.8/org/apache/commons/compress/archivers/StreamingNotSupportedException.html

18:24 weird!

18:25 so ArchiveStreamFactory is being used erroneously?

18:25 pandeiro: justin_smith: no idea! none of this is thrown when i do the exact same thing in tests

18:26 i'm getting close to `rm -rf ~/.m2`

18:29 justin_smith: pandeiro: in my experience that doesn't really help much

18:29 pandeiro: it's not even clear to me which class is not being found

18:29 or which class definition

18:30 i am 80% it's related somehow to the classpath, not any actual app or library code

18:38 voidnoid: is there a good basics book available online? the primary docs http://clojure.org/reader seem to be geared more as a reference manual than an instructional book

18:38 rather, I'm guessing there is, wondering what people might suggest

18:42 pandeiro: voidnoid: http://www.braveclojure.com/ is pretty good imo

18:43 voidnoid: pandeiro: k thanks

18:47 arohner: does ring-mock (or any other ring testing library) support passing cookies around, similar to clj-http cookie manager?

18:48 pandeiro: arohner: peridot manages cookies

18:49 arohner: pandeiro: great!

19:09 pandeiro: peridot appears to be sending the header "Set-Cookie" rather than "Cookie". Am I doing something wrong?

19:11 pandeiro: arohner: ah, you're setting the cookie for the request manually?

19:11 arohner: pandeiro: no

19:11 pandeiro: trying to login to an app that uses friend for auth

19:11 pandeiro: Set-Cookie: is the name of the header that the response includes

19:12 arohner: pandeiro: right, but then the next request is *sending* Set-Cookie rather than Cookie

19:12 pandeiro: so with peridot i do something like (-> (session my-app) (do-login sample-user) (api-request :foo))

19:12 where api-request is just a wrapper over my api

19:13 and would include a cookie for my session if login succeeded

19:13 arohner: yup

19:15 hrm, actually it looks like it's losing cookies during a follow-redirect

19:23 pandeiro: aha! peridot doesn't like it if you mess with the Host header, because it uses that to decide which cookies to send

19:36 jacob_: hey guys i’m having problems connecting to datomic inside a docker container when datomic is hosted on aws. I have no problem connecting to a database that is in my local network though. any ideas?

19:37 eriktjacobsen: security groups? have you verified the port is open to that machine?

19:37 jacob_: i can expose only 1 port

19:37 i have tried many different ones, like 4334

19:38 which i think is the one that database is on

19:38 eriktjacobsen: get on the box running datomic and do “sudo netstat -nutlp” and see

19:38 it’ll tell you what ports are listening

19:38 Also: Yet another compilation question: My project has 2 libraries, lets say foo and bar, which each use the same underlying library, Bob, at different versions, 1 and 2. Foo requires 3 different sections of Bob version 1: A,B and C. (this shows in lein deps :tree as “com.Bob/A” vs “com.Bob/B”. Bar only requires A and B from version 2. If I put all 3 exclusions on bar, or all 3 on foo, or just the 2 overlapping on foo,

19:38 I get different “ClassNotFoundException”.

19:39 I’m bit of a loss as what to do. Never been a java / jvm guy. Coding clojure for 3 years and still rarely run into issues that aren’t solved with a quick exclusion

19:43 pandeiro: arohner: nice catch! good to know for future reference too

21:58 iamjarvo: are there any open source clojure webapps that show testing?

22:23 justin_smith: iamjarvo: I think circleci does

22:25 iamjarvo: i think it's just their frontend

22:25 danielcompton: amalloy: you around?

22:26 amalloy: could be

22:26 justin_smith: iamjarvo: oh, so you aren't interested in cljs test

22:27 danielcompton: amalloy: would it be possible to consolidate all of the flatland and ninjudd protocol buffer repos? It's really confusing having forks that both seem to be updated and maintained

22:27 iamjarvo: both, but more on the clojure side of things

22:33 wildnux: what is the idiomatic way of matching strings in a sequence and creating a map out of it ? for eg: ["//this is a comment line" "01-this is data line" "//TODO: todo line"]

22:34 to {:comment "//this is a comment line" :data "01-this is data line" :special "//TODO: todo line"}

22:34 justin_smith: wildnux: perhaps (group-by line-categorizer lines)

22:35 where line-categorizer takes a line of text and returns :comment or :data or :special

22:35 ,(group-by first ["hello" "world" "hippo" "welsch" "hottentot" "alabama"])

22:35 clojurebot: {\h ["hello" "hippo" "hottentot"], \w ["world" "welsch"], \a ["alabama"]}

22:36 wildnux: justin_smith: thank you, let me try

22:36 justin_smith: coming from java background, i can think of line-categorizer as something in the line of: (if (.startsWith "//) ... )

22:36 amalloy: danielcompton: i dunno. the idea was that we wanted them to be flatland repos, but those didn't show up in our personal github profiles so it looked like we never did anything interesting

22:37 justin_smith: wildnux: sure, though it needs to be a function of course

22:37 wildnux: justin_smith: is there functional way of avoiding if then else ?

22:37 amalloy: so we re-hosted the repos, and then forked them back to flatland so old links would still work and so on

22:37 justin_smith: wildnux: cond can be nicer than nested ifs at least

22:37 (doc cond)

22:37 clojurebot: "([& clauses]); Takes a set of test/expr pairs. It evaluates each test one at a time. If a test returns logical true, cond evaluates and returns the value of the corresponding expr and doesn't evaluate any of the other tests or exprs. (cond) returns nil."

22:38 wildnux: justin_smith: aah yes, thank you.. let me try it

22:38 danielcompton: amalloy: I'm pretty sure that's no longer the case, they'll show up under "Repositories contributed to"

22:40 justin_smith: ,(group-by #(cond (.startsWith % "//TODO: ") :special (.startsWith % "//") :comment :true :data) ["//this is a comment line" "01-this is a data line" "//TODO: todo line"])

22:40 clojurebot: {:comment ["//this is a comment line"], :data ["01-this is a data line"], :special ["//TODO: todo line"]}

22:40 justin_smith: of course the real art will be in making the categorizer better (eventually you might want a parser or at least regex?)

22:45 danielcompton: amalloy: the current situation is really confusing. If you still wanted it to show up as your repo on GitHub, could you remove the flatland forks, but keep the groupID as flatland?

23:12 wildnux: justin_smith: yeah, for now this should work :)

23:26 lvh: When I open up a nrepl session, say, in CIDER, it automatically honors stuff from project.clj, like :init-ns, :init and other :repl-options. What's the part that actually makes that work for CIDER? How does it ask leiningen what it shoudl to do the REPL before giving it to the user? I'm asking because I'd like to contribute that behavior to figwheel.

23:27 amalloy: lvh: leiningen does all that, not cider

23:27 cider just says "hey lein, gimme a repl"

23:29 justin_smith: and lein's all like "OK, current wait time for a repl is about 45 seconds" and then puts cider on hold

23:30 lvh: Oh, okay.

23:31 amalloy: So, right now, figwheel sets up an nrepl server, but it ignores all the nrepl middleware and other :repl-opts stuff from project.clj, since, well, it's not lein

23:31 I'm not sure what the best way to fix that is

23:31 just using stuff from project.clj seems fine, since it's already lein-figwheel

23:31 you can't really use it without it AFAIK

23:32 justin_smith: sad but true :(

23:32 I guess I'll look into leiningen to see if I find any nrepl-specific stuff? Although I guess it's not just nrepl, it's any repl

23:33 I'm kind of hoping there's something I can call that will worry about project.clj's contents for me, and specifically knows all about :repl-opts and just.. does it

23:33 I guess lein repl is always nrepl? IIRC

23:33 justin_smith: yes, but "lein run -m clojure.main" gives a vanilla repl

23:34 lvh: amalloy: Thanks! :)

23:34 Ah :)

Logging service provided by n01se.net