#clojure log - Sep 16 2014

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

0:50 gzmask: hello guys, what is the clj-http translation of "curl -s https://aaa.com -d "a=b&c=d" ?

0:52 justin_smith: (client/post "https://aaa.com" {:form-params {"a" "b", "c" "d"}})

0:53 also, example.com is the canonical filler url

0:57 gzmask: thanks justin_smith. but paypal doesn't think they are the same :(

1:02 dbasch: gzmask: the user agent obviously is not the same. Does it work with curl and not clj-http?

1:03 gzmask: yes, it worked with curl, but gives RESPMSG=User authentication failed for clj-http

1:04 dbasch: what if you do (client/post "https://aaa.com" {:form-params {:a “b” :c “d”}})

1:05 gzmask: same error. I tried the query-params, no luck either.

1:06 it's escaping my "!" char to "%21" . now sure if this cause the error

1:13 It did cause the error!! Why in the world would you change ! to %21 ....

2:16 cisza: Hi guys

2:17 seangone: hi cisza !

2:27 raspasov: hello

2:27 noncom: hi

2:28 cisza: what's up guys?

2:29 raspasov: coding :)

2:29 seangone: tends to be quiet in here at night US time :)

2:29 raspasov: yea

2:29 I'm SFF

2:29 SF*

2:29 seangone: I'm off to The Strange Loop in a few hours...

2:30 raspasov: yea? nice

2:31 seangone: Powered by JavaScript too... should be fun...

2:31 raspasov: what do you mean powered by JavaScript? :)

2:32 seangone: Manning's one day three track conference the day before Strange Loop

2:32 raspasov: ah I see

2:32 seangone: http://www.manning.com/poweredbyjavascript/

2:32 raspasov: any ClojureScript in that?

2:32 seangone: there's a bunch of pre-conference stuff... workshops, future of programming, and pbj :)

2:33 I was hoping there would be some compile-to-JS stuff but there doesn't seem to be

2:33 I'm interested in React.js and stuff like that tho'...

2:33 raspasov: yea React is good

2:45 clj-learner: hi, im trying to solve http://www.4clojure.com/problem/82 and having difficulty, this seems like it can be solved with graph theory(?) could someone point me to a tutorial to be able solve this?

2:51 averell: it would be possible. you make edges between words where the distance is 1, then find a hamilton-path (that is a path of all nodes). Pretty sure it's overkill for this though.

2:52 amalloy: heh, looking back at my solution to that problem it's not actually correct

2:52 clj-learner: so how would i solve it?

2:52 averell: do you have distance already? just try all combos

2:53 clj-learner: distance?

2:53 averell: i mean, something to decide if the words are "similar enough"

2:53 amalloy: or, i dunno, maybe it does. the flaw i thought i saw in my algorithm is exercised by the tests

2:54 averell: did you do something clever?

2:54 clj-learner: i did this (fn chain? [s1 s2] (= (inc (count s1))

2:54 (count (union (set s1) (set s2)))))

2:55 averell: ok, that's not enough though

2:56 amalloy: i'm not sure. i compute the degree of each node, and then i assert that there are are at most two nodes with degree less than two. that certainly doesn't sound sufficient to me

2:56 seems like i should fail on '(sit sat sot dog)

2:56 averell: ah, that's for euler-path i think :)

2:57 amalloy: averell: well it's not really sufficient in either case, because of disjoint subgraphs

2:57 clj-learner: i think this is probably too much for me, ill just pass this one for now

2:57 i dont know graph theory

2:57 averell: oh right

2:57 clj-learner: at least i completed all other 81

2:57 averell: nice

2:57 clj-learner: thanks for the help

2:59 dbasch: clj-learner: you want to find a Hamiltonian path

3:06 amalloy: even with connected subgraphs it's still not sufficient

3:06 amalloy: indeed, it's quite wrong in a lot of ways

3:07 dbasch: that problem should have test cases that forced you to solve it right

3:08 amalloy: dbasch: of course. but it's easy to miss edge cases; 4clojure is littered with such problems

3:08 dbasch: amalloy: for that one it's not hard, just create a couple of evil graphs

3:09 e.g. a fork and a join

3:10 amalloy: but that entails thinking of all the hard cases that someone might incorrectly identify with a wonky algorithm. you say "not hard", but of course it's impossible to find a set of inputs that causes only correct algorithms to pass

3:10 if nothing else, the standard 4clojure cheat of mapping each input test case directly to its output will always work

3:10 averell: there certainly are drawbacks to posting all test-cases :)

3:11 amalloy: *shrug* i don't think so, averell. you only cheat yourself when you cheat a 4clojure problem. if that's what gives you satisfaction, feel free. i don't see that as a drawback

3:12 and it drastically improves the user experience for the actual target market, ie people trying to learn clojure. imagine "you passed all the test cases you can see, but there's an input i won't tell you about that breaks your program"

3:12 averell: hm true. but i have poor self-control...

3:13 amalloy: there certainly are drawbacks to having no self control

3:13 averell: obviously a problem that should be solved externally.

3:16 dbasch: amalloy: yeah, I was just thinking of cases that would force you to either cheat or try to solve the Hamiltonian path problem

3:19 you also learn by breaking other people's solutions :P

3:23 I ran into some code that goes (defn foo ^String [^bytes x] ….)

3:24 I have no idea what's the intended purpose of ^String there

3:41 cdr_: Hey :)

4:01 SagiCZ1: ~lazy-logs

4:01 clojurebot: lazy-logs is http://logs.lazybot.org/

4:12 cdr_: Soo... does some1 chat here ?

4:12 Or just come online and leave ?

4:13 TEttinger: when people have questions they usually get answered, cdr_

4:13 cdr_: Ohh, thanks :)

4:13 TEttinger: this is more of a quiet time since most of the US-based people are asleep

4:14 cdr_: Ohh... i am from EU, so this is morning for me :D

4:16 maxthoursie: There's a bunch of EU ppl here too

4:18 hyPiRion: It's usually silent until about 2-4pm EU time, but it varies

4:57 ssideris: EU-based and present! (but yes, usually silent)

5:07 yotsov: If I want to build a clojure webapp with some ajax-like functionality but without clojurescript, are there tools that would be recommended?

5:14 perplexa: do people use System/getenv or weavejester/environ?

5:41 ddellacosta_: perplexa: I like environ, personally

5:42 yotsov: the backend wouldn't change (from a typical Clojure web app), and the front-end would be whatever non-CLJS thing you wanted...what are you asking about in particular though? I'm not sure I understand.

5:50 yotsov: ddellacosta_: just wondering if there are things known to work together with examples out there, such as a particular js ajax framework with a particular clojure lib on server side...

5:52 ddellacosta_: yotsov: well, based on my experience with Om, I can tell you that using React with an immutable data structure lib like Mori and a Clojure backend could be a good fit

5:52 yotsov: but I will sell ClojureScript a bit--it's quite nice, seriously. :-)

5:54 yotsov: ddellacosta_: thanks. Do you think cljs makes sense even for just like 2 very small ajax-ish features? It would not feel like an overkill?

5:55 ddellacosta_: yotsov: I mean, no, but I use it every day and find it to be "no big deal." Have you done much CLJS?

5:56 yotsov: for example, take a look here for something very simple to set up and get going: http://swannodette.github.io/2013/10/27/the-essence-of-clojurescript/

5:56 yotsov: apologies if you're beyond that

5:56 borkdude: CLJS makes me less afraid of javascript.

5:56 ddellacosta_: borkdude: ha, never thought of that, but I think that's true for me too

5:57 it also makes me more aware of JS's idiosyncracies

5:59 borkdude: Actually I find it quite fun to write front end code now.

5:59 although I haven't really got much experience with javascript

6:00 yotsov: ddellacosta_: I am not very familiar with cljs, have just played with it a bit (hello world, a bit of Om). I wanted to postpone learning it, as I have a lot going on right now. But, interestingly enough, it seems that for clojure+ajax it is pretty much the easiest way to start, due to the sheer amount of examples out there

6:01 borkdude: yotsov ajax, look at cljs-http and channels

6:01 ddellacosta_: yotsov: yeah, I would say that it's actually easier in terms of the "impedance mismatch" to get CLJS + CLJ working vs. Clojure and JS

6:01 borkdude: it's also lots easier to just be able to send edn back and forth

6:02 haven't tried Transit though

6:05 yotsov: borkdude: If I go the cljs road, I hope to be able to do without channels, just with Om. I actually still have hard time understanding how people mix the two

6:06 to me it sounds a bit contradictory, basically injecting mutability into something immutable

6:06 borkdude: yotsov you can also just use a callback, but working with channels and asynchronous is really nice, because you have the illusion that they work synchronously

6:06 *requests

6:07 yotsov the combination ajax+channels is something apart from Om

6:08 yotsov: borkdude: yes, but it seems to be in fashion to use both channels and Om, which confuses me

6:08 borkdude: yotsov You can use channels with Om to communicate changes to components, like: the request has finished and here are the results, now update yourself

6:09 or: update the app state, or whatever

6:09 yotsov in this way you can decouple logic from components

6:09 yotsov: wouldn't you rather send the full state of the page to Om then, which would then update just the necessary component?

6:09 I see

6:10 borkdude: yotsov to "send the full state" you would first have to update it

6:11 for example, I have a function: lookup-items. Its parameter is a channel. It doesn't know where it sends the results, but the component that reads from the channel knows that it should update the app state when something arrives there.

6:11 yotsov: borkdude: in my case, the webapp is fairly simple, and I can have everything the user sees at any point of time in just one data structure. In that case Om is enough and I do not need channels, right?

6:12 borkdude: yotsov you can do everything in one giant component and avoid channels

6:12 yotsov: borkdude: got it, thanks

6:13 ddellacosta_: yotsov: actually Om *without* channels is a major mess and a pain in the ass, basically impossible if you ask me.

6:13 yotsov: no way to effectively communicate back up the component hierarchy

6:13 borkdude: yotsov ddellacosta_ communication upwards happens through channels or handlers

6:14 ddellacosta_: borkdude: yeah, I find using a lot of handlers is more frustrating

6:14 ...thank channels

6:14 than*

6:14 borkdude: yotsov ddellacosta_ but if you have just a small app and every part has access to the whole app-state, you can do without. That's what I meant with "giant"

6:15 ddellacosta_: borkdude: sure, fair enough--if you don't have a deep component stack it's fine, it becomes tricky when you have complicated UI interactions

6:15 borkdude: ddellacosta_ yeah

6:15 yotsov: borkdude ddellacosta_ I think handlers should be fine for me

6:16 ddellacosta_: yotsov: give it a shot, just keep in mind that channels really do help out once communication gets complex--if you find yourself swearing about passing state around, come back and talk to us. ;-)

6:17 borkdude: ddellacosta_ I actually found having many channels wiring component to each other can get complex too. I am now using just one channel and a pub/sub mechanism to keep it simple, where I can, unless the communication is very local.

6:17 ddellacosta_: borkdude: that's a fair point. I have a few components with like six channels, and that really is not nice to keep track of. I guess there's a sweet spot with a few channels.

6:18 borkdude: I need to look into something like your pub/sub mechanism, it's become pretty obvious we need something like that to alleviate the pressure in a few spots

6:18 "complexity pressure" so to speak

6:18 yotsov: borkdude ddellacosta_ thanks guys, I think I see a bit more clearly now. Can you recommend a sample Om webapp that uses handlers rather than channels?

6:18 borkdude: ddellacosta_ yotsov http://yobriefca.se/blog/2014/06/04/publish-and-subscribe-with-core-dot-asyncs-pub-and-sub/

6:19 ddellacosta_: borkdude: nice, thanks

6:19 cityspirit: yotsov: you could also look at luminus with reagent. with the +cljs option you'll get a template with an example built in. I found that a really easy way to get started with simple clojure app with a clojurescript + react frontend.

6:19 ddellacosta_: borkdude: oh, but that has no Om, sad. Well, still, good tip

6:20 (we're using pub/sub elsewhere not just with Om yet)

6:20 borkdude: ddellacosta_ in Om I have two channels in global state: one event-ch to write to and one event-publication to subscribe to.

6:20 ddellacosta_ the rest is very easy to figure out, once you read the blog post

6:20 ddellacosta_: borkdude: and then if a child component needs to talk to a parent, the parent just listens on that topic basically, right?

6:20 ...and child sends on that topic? That could work really well, hmm

6:21 borkdude: ddellacosta_ that's what I meant with "local", if it's just a parent-child relationship, I will sometimes still use a dedicated channel, but you could do it with pub sub also

6:21 ddellacosta_: borkdude: gotcha

6:22 that along with shared data is our biggest problem

6:22 borkdude: ddellacosta_ shared data?

6:23 ddellacosta_: borkdude: yeah, if you have a bit of data that needs to be used in child components pretty deep in the stack. I have used shared a bit, but it doesn't seem to update in the way I need it to--so I end up putting stuff in state or app data

6:23 borkdude: ddellacosta_ you can also use pub sub for this

6:24 ddellacosta_: borkdude: well, but then I have to manage updates myself somehow

6:24 borkdude: in IWillMount you put a go loop that reads from the subscription

6:24 ddellacosta_: borkdude: I want to leverage React/Om's update mechanisms as much as possible

6:25 borkdude: ddellacosta_ it depends on what the data is. it could be something worthy of the app-state

6:25 yotsov: Om examples without core.async seem to be as common as clojure ajax examples without cljs :) I guess I should not try kicking against the pricks and go with Om + core.async channels...

6:25 ddellacosta_: borkdude: that's the thing, it usually is--it's just not in the right form, or it needs to be referenced deep in the hierarchy, so a child has to have a copy of something that has effectively been "stirpped out" by that point

6:25 *stripped

6:25 borkdude: ddellacosta_ if you do a go loop in will-mount that reads from the right subscription and updates it's local state, the component will re-render

6:26 ddellacosta_: borkdude: yeah, but again, I don't want to have to do that--I do stuff like that now

6:27 borkdude: ddellacosta_ then pass it down the hierarchy with state. I don't know other options so far, sorry. My time with Om has been limited to a few weeks now :)

6:27 ddellacosta_: borkdude: no, we do that too...again, though, it is usually app data that we are abusing. I do like to keep state and app data appropriately separate.

6:27 borkdude: I mean, yeah, everything you're suggesting makes sense, I think this is a limitation in Om right now is all

6:28 borkdude: ddellacosta_ actually, I'm rewriting an app now that "abused" the app state to store component state

6:28 ddellacosta_: ha

6:28 "Abusing State for Fun and Profit with Om," my new ebook

6:28 borkdude: ddellacosta_ in order to make components re-usable, it should not depend on the app state too much

6:28 yotsov: ddellacosta_ borkdude there are several alternatives to Om for using react.js. Are you guys familiar with them? Is any of them simpler than Om and making using core.async more optional?

6:29 ddellacosta_: yotsov: a lot of folks seem to like reagent, and say it is simpler, per what cityspirit was saying above

6:29 borkdude: yotsov I hear reagent is simpler, but I don't know its limitations, my only experience is with Om really

6:30 yotsov: borkdude: ddellacosta_: thank you!

6:31 ddellacosta_: yotsov: my sense is that it's easier to get going but (this is a guess, I don't know for sure) harder to build out bigger systems with--Om's rigidity also helps enforce some good practices, not withstanding its weak points

6:31 ...which makes it easier to build big complex web apps (as we have done)

6:32 but again, that's not really fair to reagent, since I have barely touched it; it could be equally good, I need to give it a shot

6:32 borkdude: ddellacosta_ is what you want a shared local state between parent and childs?

6:32 yotsov: ddellacosta_: thanks. I need to build just a small demo that will never become more than that

6:32 ddellacosta_: borkdude: no, I basically want to be able to restructure app data and re-attach things at various points/drop new cursors in at various points

6:33 re-attach things = re-attach different pieces of app data

6:34 maybe shared can do it, but my recent experiences suggest it doesn't update as predictably as I need it to, not like app-data/state

6:34 borkdude: so for example, app-state: {:foo {:bar :baz}}, parent component has cursor too app-state, child component gets cursor into :bar, but his child component needs :foo again?

6:38 ddellacosta_: borkdude: (assuming app-state in your example is app data, not component local state, to be clear)

6:38 borkdude: ddellacosta_ yes

6:38 ddellacosta_: borkdude: yeah, or more like I have {:foo [{:id 1 ...}{:id 2 ...}] :bar [...other relevant data...]} and I use build-all on :foo, and I need :bar also in each :foo

6:39 borkdude: I'm guessing that is not how react works: you can't re-render a child without re-rendering the parent maybe?

6:39 ddellacosta_: borkdude: no, you can totally re-render a child without re-rendering the parent...if your data is structured correctly

6:40 borkdude: that's the point of the virtual DOM really

6:40 borkdude: ddellacosta_ ok, could be, I don't know :)

6:40 ddellacosta_: borkdude: well, if you've only been using it a few weeks, then I'm still impressed with your knowledge of Om. ;-)

6:40 borkdude: ddellacosta_ I've been asking a lot of dumb questions in #clojurescript ;)

6:41 ddellacosta_: borkdude: jeez, I should be hanging out there, I'm never in there

6:47 borkdude: ddellacosta_ so basically, the whole parent-child structure makes no sense in re-rendering. Each component should just be able to pick what to subscribe to in the app-state?

6:47 ddellacosta_: borkdude: no, it totally makes sense I think--it's just that I want to be able to restructure the data itself, or pass different bits around so they are reintegrated later, at certain points in the component hierarchy. I find this hard to do now in Om.

6:47 borkdude: ddellacosta_ you can just pass (dissoc cursor :foo :bar) to the components, but probably that's not what you want either

6:47 ddellacosta_: borkdude: well, but what if I want those things later on down the chain?

6:47 borkdude: ddellacosta_ oops, I mean the opposite of dissoc, only select those two keys

6:47 yocapybara: any emacs/cider whizzes here? I'm finding I'm working in a certain way and it feels like it isn't optimal, just wanted to check with others whether they do a similar thing or if they (as I suspect) do something much smarter

6:48 ddellacosta_: borkdude: oh, yeah, but again--what about all the stuff it's leaving off, and what if it's a build-all?

6:48 yocapybara: I've gone back and forth between cider and just having a repl open w/emacs separate

6:48 borkdude: ddellacosta_ often I don't use build-all, but just map

6:49 ddellacosta_: borkdude: to be fair, that's all build-all is

6:49 borkdude: (map #(om/build ... cursor {:opts {:foo %)}) [1 2 3 4])

6:49 ddellacosta_: yocapybara: sorry, not a super useful answer. Some folks I know are really brilliant with loading and running stuff in cider, but I think it takes some practice. :-/

6:50 borkdude: opts means it's not going to trigger a re-render though.

6:50 borkdude: ddellacosta_ it's not the same, because in my map example the children get acces to the whole cursor

6:50 ddellacosta_: borkdude: yeah, I mean, that's one solution

6:50 borkdude: ddellacosta_ yeah, whatever, could be :state as well :)

6:51 ddellacosta_: borkdude: it's tough though, if you want to build individual elements and take advantage of keys and whatnot

6:51 yocapybara: ddellacosta_: any info is useful man, thanks! I'm finding that I copy or (C-c M-p) each expression into the REPL buffer so I can play around with my code, if I execute an expression it doesn't seem to be executed in the actual repl buffer even if I've got one running. I feel like I'm missing something about how it works - like there should be a very easy way to issue a command to have the REPL run all the expressions in

6:51 my buffer.

6:51 I've had good luck with lighttable but I wanted to give emacs/cider a proper go

6:52 borkdude: ddellacosta_ I think we need concrete cases to talk about.

6:53 ddellacosta_ but I'm very interested, because these are the problems I also deal with \

6:55 apod: yocapybara: you probably need to switch the namespace, try C-c M-n

6:55 ddellacosta_: borkdude: yeah, I'm probably not explaining it well, sorry. I have to put some solid examples together that really expose these confusing points, 'cause I run into them a lot day-to-day

6:57 apod: yocapybara: to evaluate the buffer C-c C-k

6:59 yocapybara: apod: thanks, this is exactly what I was missing and I hadn't put the pieces together - have just tried it and that's doing exactly what I was missing

7:00 apod: thanks loads :)

7:00 apod: yocapybara: also you can evaluate an expression under the point with C-c C-e (or C-c C-c to evaluate the top level form under point) and see the result on the minibuffer

7:03 yocapybara: apod: thanks also for that - I was doing that but I think perhaps due to not switching the namespace it seemed like anything I had previously executed with C-c C-e wasn't accessible. But having switched the namespace all clicks into place. I should have realised but didn't. Thanks! :) closer to clojure nirvana

7:05 yotsov: ddellacosta_: borkdude: my first attempt will be to use this approach https://github.com/yogthos/reagent-example (corresponding blog post http://getprismatic.com/story/1405451329953 ), It looks so simple and accessible and great that I got high on adrenaline+endorphin combo like in my early clojure days :)

7:06 ddellacosta_: yotsov: awesome, whatever keeps the enthusiasm going. :-)

7:06 borkdude: yotsov :)

7:45 lvh: In clojure.test, how do I test multiple predicates, but retain useful error messages?

7:46 currently I'm doing (and (p? example) (q? example)) which results in totally useless error messages :(

7:56 hyPiRion: lvh: I usually `(do (is (p? example)) (is (q? example)))`

7:56 at least then you know which one failed

9:09 piranha: I wonder if anybody has some code to generate simplest documentation for a liberator-based API? It seems there are no ready tools for that so I'll have to invent something...

9:20 CookedGryphon: what's the best way to do distinct? on a collection?

9:20 where the collection might be empty

9:20 best I can come up with so far is (apply distinct? :unlikely/ham coll)

9:21 otherwise I get an error with empty collections and have to do a separate check

9:21 TimMc: File a JIRA, wait, and sob.

9:22 Mourn for http://dev.clojure.org/jira/browse/CLJ-1179

9:22 CookedGryphon: ffs

9:23 TimMc: srsly

9:23 It's shit like this...

9:23 justin_smith: ,(map (fnil #(apply distinct? %) [0]) (map seq [[] [:a] [:a :a] [:a :b :c]])) ; CookedGryphon

9:23 clojurebot: (true true false true)

9:24 justin_smith: unless you want (distinct? []) to be false, then change the last arg of fnil to [0 0]

9:25 sadly fnil only does its magic if the input is coerced via seq before you use it

9:29 CookedGryphon: justin_smith: yeah, it's still a bit messy though

9:29 feels a bit more professional than my :ham version :P

9:31 justin_smith: (defn distinctish? [& args] (or (empty? args) (apply distinct? args)))

9:31 another option

9:32 that's likely the clean one ... or (and args (apply distinct? args))

9:33 CookedGryphon: yeah, that's what I've done

9:33 just defined the less stupid distinct? function

9:33 dnolen_: (defn distinct-coll [coll] (reduce (fn [s x] (if (contains? s x) (reduced false) (conj s x))) #{} coll))

9:34 CookedGryphon: It would make some amount of sense if it errored out on one argument as well

9:34 but apparently that's fine

9:36 can anyone offer any sort of explanation as to why it would be undesirable behaviour to return true rather than explode?

9:37 one single example of where it's not correct behaviour to just return true for the zero arity version

9:37 xemdetia: I don't think there is an opposing argument CookedGryphon

9:38 if you have variable length arguments surely you must handle gracefully a case where no arguments are passed

9:38 CookedGryphon: sorry, not in here, but on the jira ticket linked earlier apparently the change was rejected by rich

9:39 xemdetia: did anyone follow up with Rich?

9:39 CookedGryphon: not sure, all I have is the info on the ticket http://dev.clojure.org/jira/browse/CLJ-1179

9:40 xemdetia: I saw the ticket a while ago but it's clearly a sore point

9:40 that's why I asked if anyone followed up

9:46 dnolen_: CookedGryphon: xemdetia: likely not considered that important, also there are other fns with the exact same "problem" i.e. =, <, etc.

9:47 xemdetia: ah

9:47 CookedGryphon: dnolen_: I'm not sure it's as clear cut with = and <

9:47 xemdetia: still I think it's one of those

9:48 variable # arity functions should do something other then exceptions

9:48 when passed 0 args

9:48 CookedGryphon: there's an equal argument for true and false with = and not=, it's undefined i would say...

9:48 dnolen_: CookedGryphon: anyways, clearly there are more nuances none which are in the ticket

9:55 justin_smith: xemdetia: what about / ?

9:55 ,(/ 2)

9:55 clojurebot: 1/2

9:55 justin_smith: ,(/)

9:55 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core//>

9:55 justin_smith: ,(/ 1 2 3) ; for good measure

9:55 clojurebot: 1/6

9:56 justin_smith: I guess (/) could return NaN

9:56 xemdetia: justin_smith, I wouldn't normally consider / a variable length argument

9:56 justin_smith: but it is!

9:56 xemdetia: it is clearly :)

10:04 I guess I have to adjust my expectation, but so I will reduce it to still believing vararity -? functions should handle a 0 case. A query against an empty set still should provide a meaningful result, even if it's NOSETSILLY

10:07 CookedGryphon: but yeah, especially for distinct, it's really cut and dry. It currently does not perform the function described in its docstring "Returns true if no two of the arguments are =", point at the two arguments which are equal in (distinct?) and (distinct? 1)

10:11 bja: I should start returning 'NOTSETSILLY instead of nil for the 0 case

10:11 with a link to this irc history

10:11 TimMc: dnolen_: I've never heard rhickey give nuance on tickets regarding base cases.

10:12 I *have* to assume he just doesn't see the problem.

10:13 dnolen_: TimMc: I also don't see the problem unless there's some larger discussion about apply not working on empty collections.

10:13 for many fns.

10:13 TimMc: What do you mean?

10:13 &(apply + [])

10:13 Oh, not apply, but the fns themselves.

10:14 xemdetia: well it should be well-defined that it's going to error out so we don't have to point to some obscure Jira issue

10:14 dnolen_: ,(apply = [])

10:14 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/=>

10:14 dnolen_: ,(apply < [])

10:14 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/<>

10:15 xemdetia: numeric functions make sense to fail, I now reduce my argument to only predicate functions (-?)

10:15 TimMc: I don't think there's much to discuss -- base cases need to be defined unless there's a compelling reason not to. I mean it's a Lisp ffs. You'd think we'd get recursive base cases correct. :-/

10:16 But all I get from JIRA is... "nah".

10:16 dnolen_: xemdetia: they do not make sense to fail

10:16 ,(apply + [])

10:16 clojurebot: 0

10:16 dnolen_: ,(apply * [])

10:16 clojurebot: 1

10:17 dnolen_: people can keep pretending like there a simpler answer here

10:17 or just write distinct-coll? and move on

10:17 TimMc: To the extent that there needs to be a larger discussion, it's "why do so many reasonable patches get rejected without comment?"

10:18 justin_smith: TimMc: meanwhile, Hickey is all like "let them eat transducers"

10:18 TimMc: (I am fine with comments like "we don't need that feature in core", that's a perfectly reasonable judgement call to make, even if I disagree sometimes.)

10:30 mavbozo: in leiningen :repl-options, the :ack-port is used for what?

10:31 borkdude: piranha I have seen a presentation on someone who used Swagger in combination with Liberator. That might be interesting for you?

10:31 piranha: borkdude: for sure!

10:31 borkdude: piranha it was at Euroclojure 2014. The video might be up

10:31 piranha: I'll look for that, thanks

10:32 borkdude: piranha http://vimeo.com/100485830

10:32 mavbozo: i couldn't find the description for :ack-port in leiningen sample project here https://github.com/technomancy/leiningen/blob/master/sample.project.clj

10:32 piranha: borkdude: thanks :)

10:32 mavbozo: but :ack-port is used in leiningen.repl

10:33 corecode_: hi

10:33 i think i found a bug in 4clojure or clojail, but i'm new to clojure and might be wrong

10:34 hyPiRion: mavbozo: ack-port is used to decide which port the acknowledgement from the repl server is sent/received

10:34 corecode_: anybody like to indulge in following the issue?

10:34 hyPiRion: It's then used to generate e.g. .nrepl-port and similar

10:34 ~anyone

10:34 clojurebot: anyone is anybody

10:34 hyPiRion: ~anybody

10:34 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

10:34 corecode_: https://www.4clojure.com/problem/21 <- if you supply (fn [[h &t]] 1), it complains about nth being used

10:35 hyPiRion: finger reflexes?

10:35 borkdude: piranha sorry, no liberator in it, but still interesting ;)

10:35 corecode_: hyPiRion: did you read what i wrote before?

10:36 tbaldridge: corecode_: yeah, I think the destructuring is calling nth

10:36 corecode_: tbaldridge: ah, not in my clojure

10:36 tbaldridge: ,(macroexpand ,(let [[x y] (range 2)] x))

10:36 clojurebot: 0

10:36 tbaldridge: ,(macroexpand '(let [[x y] (range 2)] x))

10:36 clojurebot: (let* [vec__52 (range 2) x (clojure.core/nth vec__52 0 nil) y ...] x)

10:36 hyPiRion: corecode_: right, just saying that people would reply if they know the answer :) It's not always easy to say "I'll help" if they don't know the problem

10:37 tbaldridge: corecode_: see my example there, it is calling nth via the let macro. So 4clojure is probably mocking out nth to make sure you're not calling it. But you are, just via a macro

10:37 corecode_: hyPiRion: i think mindlessly doing the ~anybody is as bad as mindlessly asking such questions the bot refered to

10:37 jcsims: I've got a friend who wants to participate in the clojure cup with me, but is not familiar with clojure (he's comfortable in haskell). Any recommendations for someone coming to clojure from haskell?

10:38 corecode_: tbaldridge: (macroexpand (read-string "(fn [[h & t]] h)"))

10:38 (fn* ([p__978] (clojure.core/let [[h & t] p__978] h)))

10:38 different clojure, i guess

10:38 tbaldridge: corecode_: that only macro expands a single form, you'd want something like macro expand all.

10:38 corecode_: aha!

10:38 thanks

10:38 tbaldridge: corecode_: your let inside the fn hasn't been expanded to let*

10:39 corecode_: right

10:39 piranha: borkdude: indeed, just watched slides. fnhouse-swagger is 54 lines, so maybe it won't be very hard to swaggerize my bidi + liberator setup...

10:41 corecode_: hyPiRion: wouldn't you agree?

10:42 ncthom91: hey y'all. Can I define a map literal where one of hte keys is a local variable?

10:43 { my-var "val" } ?

10:43 oh nvm, that works :P

10:45 hyPiRion: corecode_: I'm not saying it's bad to ask for help in that way, neither does the bot. It's just very common that new people ask "does anybody want to help me?", in which the reply rate is significantly lower than if you just ask the question itself

10:45 mavbozo: hyPiRion: why leiningen.repl creates another nrepl-server just to handle ack replies from the nrepl-server it creates?

10:47 hyPiRion: mavbozo: No, it creates only a single nrepl-server. Let me see if I can explain

10:48 mavbozo: hyPiRion: thanks

10:48 corecode_: hyPiRion: what i'm saying is that it is bad to type ~anybody as a reflex to seeing the word

10:49 dbasch: I saw this code: (defn foo ^String [^bytes x] ….) <- is there something I'm missing or the ^String does nothing?

10:49 justin_smith: dbasch: it means foo returns String right? or is that the wrong place for that metadata?

10:50 dbasch: justin_smith: thst would be (defn ^String foo …)

10:50 justin_smith: in that case, I would guess it was a typo, and they were trying to do that

10:51 dbasch: justin_smith: it's interesting that it compiles quietly

10:51 hyPiRion: corecode_: Sure, but that wasn't what I did (or at least not what I was trying to convey). You asked if anybody wanted to indulge in the issue, which most people won't reply to

10:51 justin_smith: dbasch: well, it's not an error to add metadata to whatever silly thing you want to put it on

10:52 I guess that is putting metadata on the args vec?

10:52 cocquecigrue: has anyone ever had issues testing monger code in tests? I have a weird issue where when I run tests in the repl it works fine, the app itself works fine but when I use lein test it fails with nullpointerexception

10:53 i use clojure.test

10:53 justin_smith: cocquecigrue: the first thing I would suspect is that you are using something like map, where the result is forced in the repl but not in your code

10:54 dbasch: justin_smith: I suppose, but how would you even access that metadata?

10:54 justin_smith: dbasch: I don't think you could

10:54 cocquecigrue: justin_smith: what do you mean by map?

10:54 wait a second I push my code to github

10:54 justin_smith: cocquecigrue: the function map, which is lazy, but will seem not to be lazy in the repl because the print stage forces the result

10:55 cocquecigrue: but yeah, push your code, that will help

10:55 cocquecigrue: https://github.com/joelmarty/bonjour-compojure/blob/master/src/bonjour_compojure/database.clj

10:56 so the idea is to store the db object in an atom

10:56 when I call the init function

10:56 justin_smith: cocquecigrue: why would (:mongo-host (io/resource "app.edn")) return anything but nil?

10:57 oh, sorry, "defconfig", I missed that

10:57 cocquecigrue: that's the first thing i looked into :)

10:58 you can check the test in test/database

11:00 justin_smith: list-empty? is oddly named

11:00 it tests the reverse of that, right?

11:01 cocquecigrue: I don't use that yet

11:01 so it doesn't really matter

11:01 justin_smith: why do you nest use-fixtures inside deftest?

11:01 I don't know if that works, but I have never used it that way

11:01 it works just fine as a top level form

11:01 cocquecigrue: that's how the doc says to use it

11:02 justin_smith: weird

11:02 I have only used it as a top level form, and it works

11:03 cocquecigrue: when I use https://github.com/joelmarty/bonjour-compojure/blob/master/src/bonj

11:03 oops

11:03 when I use clojure.test/run-tests 'namespace in the repl it works just fine

11:04 but when I use it through lein that fails because the atom that holds the db is nil

11:04 so I guess the issue is not from the test but from the interaction with lein

11:05 maybe it's related to my environment i don't know

11:05 justin_smith: cocquecigrue: use-fixtures is a side-effecting function that changes how all functions in an ns are run, putting it inside a test makes no sense

11:05 cocquecigrue: how would you use it?

11:05 justin_smith: it is global, it does not modify the current scoped test definition, it alters all tests in the ns

11:05 cocquecigrue: you said to use it as a top form, what did you mean with that?

11:06 justin_smith: (use-fixtures :once f) will wrap all tests in one invocation of f

11:06 top level means not inside any other definition

11:06 cocquecigrue: ok

11:06 justin_smith: at the top level of the namespace

11:06 because it is a function that modifies the whole namespace

11:07 I think you would want (use-fixtures :each f) for your example

11:07 cocquecigrue: no I just want to create the db, run all the db-related tests and destroy it

11:07 justin_smith: OK

11:07 cocquecigrue: aaaaaaaaaaaah

11:08 justin_smith: then yeah, :once is fine

11:08 cocquecigrue: and it works

11:08 justin_smith: right, I told you you were using use-fixtures wrong

11:08 cocquecigrue: I must have misunderstood the doc, thank you :)

11:08 kudos

11:09 nburtsev: Hello

11:09 justin_smith: hi

11:09 nburtsev: user=> (defn test2 [] (prn "hello") (map (fn [[k v]] (prn k "-" v)) {:test "test" :test2 "test2"}) (when-not false (prn "hello2")))

11:09 #'user/test2

11:09 user=> (test2)

11:09 "hello"

11:09 "hello2"

11:09 anyone knows why map is not running ?

11:09 justin_smith: map is lazy

11:10 agarman: (doall ...

11:10 justin_smith: if you want it to run for side effects use dorun on it, or use doseq instead of map

11:10 agarman: or that

11:10 justin_smith: agarman: doall is pointless if you are not using the return value

11:10 it just generates garbage

11:11 doall is for when you need to force evaluation within a specific scope

11:11 nburtsev: thanks a lot!

11:12 it was starting to hurt my brain :\

11:12 justin_smith: laziness is weird (it also creates weird stack traces sometimes)

11:22 perplexa: is (let [x []]) preferable over (let [])

11:22 borkdude: Is it possible in Om to inspect the state of children components? I have a form with fields that have local state :valid? and I want to "calculate" if the form as a whole is valid

11:22 perplexa: is (let [x []]) preferable over (let [x (vector)]) ?

11:22 justin_smith: yes

11:22 perplexa: ty

11:22 clgv: perplexa: is a matter of taste I guess - in the minimal case you posted [] is awful ;)

11:23 perplexa: but usually [a b ...] is pretty concise

11:23 perplexa: well i need an empty vector to which i conj later :P

11:24 borkdude: I could solve this with callbacks, but it really seems overhead to me

11:24 justin_smith: perplexa: usually, I find putting [] directly at the site of usage makes more sense than binding it to some symbol and using the symbol

11:27 clgv: borkdude: I have no idea about Om, but couldnt those components just implement a protocol where you can ask them "(valid? child)"?

11:27 perplexa: justin_smith: yeah i prefer it too tbh :)

11:28 clgv: lol yeah, since [] already is that symbol when you think about it ;)

11:28 justin_smith: if I am binding [], that would be in an atom or agent

11:28 clgv: indeed

11:29 borkdude: clgv don't know if this is possible

11:29 clgv: borkdude: me neither, it's just a general strategy where you do not have to know about the state which works often in general ;)

11:34 agarman: @justin_smith yeah I didn't read his example completely... missed that he was only doing prn

11:52 pjstadig: any opinions experience around sending a schema definition over the wire as data (Clojure->ClojureScript), reading it in as data, then using it to validate something ClojureScript side?

11:54 noonian: i think more commonly you would just use the same source file client and server side using cljx

11:54 schmir: pjstadig: why not? I'm doing something similar with clojure on both sides

11:55 noonian: you'd have to make sure they are serializable

11:55 pjstadig: noonian: we want to describe services and their data in a generic way, we don't know the schema ahead of time

11:55 noonian: ah, i see

11:55 pjstadig: the service would send a schema over the wire that could be used to construct a UI and validate before submitting a request

11:57 clgv: pjstadig: you might have to define a schema data since some constructs are not EDN serializable (if that is a requirement), e.g. regexps...

12:06 pjstadig: clgv: the challenge is that s/Str resolves to either java.lang.String or a javascript string and gets printed out in a way that cannot be read in the same with both Clojure and ClojureScript, most of the other stuff like vectors and sets seem to be fine

12:07 clgv: pjstadig: yeah and regexps are problematic ;)

12:07 pjstadig: so we're thinking of defining a deftype that represents a string, extending the schema protocol to it, defining its print method, and defining a data reader that we can use to write/read the schema as edn

12:08 clgv: sounds reaonable

12:21 radix: there's no insert operation for vectors, right? just double-checking my reading :)

12:23 justin_smith: radix: only append

12:23 radix: maybe you want a finger-tree

12:23 https://github.com/clojure/data.finger-tree

12:24 radix: oh, I see that hyPiRion is here. I actually got confused because his blog post (ostensibly about clojure vectors) talks about efficient insertion, but I guess that's not a property of clojure's vectors

12:24 justin_smith: oh cool

12:24 justin_smith: efficient insertion, but only at the end :)

12:26 hyPiRion: radix: Hrm, where do I talk about that? Because that's wrong, and I should change the wording if you belived that

12:26 Apologies for the confusion

12:26 radix: hyPiRion: I guess I just assumed mentions of "insertion" are the generalized case of insertion, not just appending.

12:27 hyPiRion: by the way, thank you for writing that series, it's very very good :)

12:27 hyPiRion: radix: Ah, right. I should clarify that I mean appends. And thanks! :)

12:28 clgv: radix: you found bad wording there ;)

12:30 radix: finger trees look cool.

12:33 dnolen_: radix: there's also rrb-trees, they are available for both Clojure/ClojureScript

12:34 noonian: you could also just use a hashmap

12:35 dnolen_: radix: rrb-trees have the same api as vectors and can be used in their stead

12:37 radix: that's cool, I'll look at those too.

12:56 lodin: There's no harm in firing up lots of go blocks, right?

12:59 bendlas: lodin: not for your thread count, if that's what you mean

12:59 clojer_: Compiling my cljs file produces: "Invalid token: :America/North_Dakota/Beulah" but this map key causes no errors when I test it in an Emacs cider repl.

12:59 bendlas: you'll eventually run out of memory though

13:01 clojer_: hm, looks like symbols with more than one / are not allowed in cljs. They are definitely allowed in clj. dnolen_ do you know about this?

13:01 clgv: lodin: you won't be able to sell it as "Green IT" ;) :P

13:01 clojer_: bendlas: Token originates from tzinfo so I need to keep it exactly as is.

13:02 lodin: bendlas: Sure. Memory is a cap. But that I don't think I have to worry about.

13:02 perplexa: mmh, i have a vector and want to append to that vector for each item in a different list with conj. i assumed it would change the referenced vector but didn't. what i got is: (doseq [source-cfg sources-cfg] (conj sources (source-tap (key source-cfg) (val source-cfg)))) - how do i get conj to append to the existing vector repeatedly?

13:02 justin_smith: clojer_: why not use it as a string?

13:02 bendlas: clojer_: maybe not save it into a keyword? seems wrong.

13:02 justin_smith: or a symbol

13:02 lodin: clgv: I'll have to find another angle then. ;-)

13:03 clgv: perplexa: persistent datastructures!

13:03 justin_smith: ,(get {"a" 0} "a") ; the syntax is a little funkier, but it works

13:03 clojurebot: 0

13:03 perplexa: ,(let x [] (conj x "1") x)

13:03 clojurebot: #<CompilerException java.lang.IllegalArgumentException: let requires a vector for its binding in sandbox:, compiling:(NO_SOURCE_FILE:0:0)>

13:03 clgv: clgv: you need `reduce`

13:03 perplexa: ,(let [x []] (conj x "1") x)

13:03 clojurebot: []

13:03 perplexa: how do i make that return 1?

13:03 [1] to be precise

13:04 clojer_: bendlas: Do you mean use a string as a map key instead?

13:04 justin_smith: perplexa: as clgv said, use reduce

13:04 bendlas: ,[(namespace :name/space/name) (name :name/space/name)] <- also consider this

13:04 clojurebot: ["name" "space/name"]

13:04 clgv: perplexa: please do read some introductory material on clojure since you fail the simplest basics

13:04 justin_smith: clojer_: no, use a string as the key

13:04 perplexa: clgv: i know :P

13:04 thx

13:04 bendlas: clojer_: yes, string is the way to go

13:04 perplexa: i know about macros though :D

13:05 i'm actually just learning it by implementing a project

13:06 clojer_: bendlas: OK. The map is very large so will it impact performance significantly using strings?

13:06 clgv: perplexa: you'll have much quicker learning progress if you read either one of the online available introductions or a book while implementing that project

13:07 bendlas: clojer_: probably not, the map entry is found by hash anyway

13:07 perplexa: clgv: well i do that, too.

13:07 but i honestly don't get how to use reduce in that case.

13:08 bendlas: clojer_: if you want to make sure to have no performance impact, intern the strings

13:08 but shouldn't be nessecary at all

13:08 clgv: perplexa: then read up on reduce ;)

13:08 perplexa: at it

13:11 clojurebot: so reduce + fn + conj it is :P

13:11 clojurebot: Ok.

13:11 perplexa: oh dude left :)

13:12 bendlas: perplexa: I think your case is served by into

13:12 ,(into [1 2 3] (list 4 5 6))

13:12 clojurebot: [1 2 3 4 5 ...]

13:13 bendlas: just make sure that you always go ahead with the return value (same as with conj)

13:13 into is essentially (reduce conj to from)

13:14 perplexa: thx

13:15 bendlas: _the_ central value proposition of clojure is that functions like conj _never_ mutate in-place

13:17 lodin: perplexa: Beware that conj depends on the data type though.

13:17 ,(into (seq [1 2 3]) (list 4 5 6))

13:17 clojurebot: (6 5 4 1 2 ...)

13:21 perplexa: lodin: yeah i read about that.

13:29 dnolen_: bendlas: "'/' has special meaning, it can be used once in the middle of a symbol to separate the namespace from the name"

13:29 bendlas: http://clojure.org/reader

13:29 bendlas: it's not clear to me that means / can be used multiple times even though the reader implementation may allow it

13:31 bendlas: dnolen_: ok, question rephrased: is that incompatibility with clojure intentional? Schould we harmonize behavior in either direction?

13:32 dnolen_: bendlas: I don't see a need to harmonize an implementation detail w/o asking on clojure-dev what is intended

13:33 Bronsa: AFAIK some-ns// is the only valid symbol that can have multiple "/"

13:34 hlprmnky_: I have myself confused about a simple syntax question and cannot see what I’m doing wrong - I’m binding a java class inside a let form, and the thing I get in the form reports itself as a class, but calling ‘new’ on it is passing the bound name to ‘new’ instead of the class symbol

13:35 e.g. (let [class java.lang.String] class) returns java.lang.String, but (let [class java.lang.String] (new class)) throws a CompilationException that the class ‘class’ cannot be found

13:35 bendlas: Bronsa: is that your interpretation of the reader doc?

13:35 hyPiRion: ,'_//_

13:35 hlprmnky_: I have searched many permutations of germane terms, read docs on java interop, and I still don’t see what I’m doing wrong htere

13:35 clojurebot: _//_

13:35 hlprmnky_: there*

13:35 bendlas: hlprmnky_: new is a special form, that only works with literal classes

13:36 hyPiRion: It's strange stuff.

13:36 ,'_//_//_

13:36 clojurebot: _//_//_

13:36 Bronsa: bendlas: no, until 1.4.0 IIRC foo// would throw an exception and only clojure.core// was allowed. then a ticket was made to allow any-ns// that got in, but never has foo/bar/baz been a valid symbol

13:36 bendlas: if you want to instantiate from a class object, you need reflection

13:36 Bronsa: hlprmnky_: new is a special form that doesn't evaluate its first expression, the class name must be literal

13:37 bendlas: ,(namespace 'foo/bar/baz)

13:37 clojurebot: "foo"

13:37 hlprmnky_: I see

13:37 bendlas: ,(name 'foo/bar/baz)

13:37 clojurebot: "bar/baz"

13:37 bendlas: Bronsa, seems to be valid

13:37 Bronsa: ,(symbol "foo bar")

13:37 clojurebot: foo bar

13:37 agarman: name of symbols accounts for the namespace it's in

13:37 ,(name 'foo.bar/baz)

13:37 clojurebot: "baz"

13:37 Bronsa: bendlas: clojure doesn't do much input validation, just because it accepts some inputs doesn't mean they are valid

13:38 bendlas: Bronsa: so what was the ticket to _make_ it valid about?

13:38 hyPiRion: bendlas: defining a function named /

13:38 in other namespaces other than clojure.core

13:38 Bronsa: bendlas: only symbols whose name is "/"

13:39 bendlas: So that was the only thing, that didn't actually work?

13:39 hyPiRion: that works fine

13:40 ,(defn / [x y] (+ x y))

13:40 clojurebot: #<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>

13:40 hyPiRion: except not in clojurebot

13:40 Bronsa: bendlas: right, in 1.4.0 'foo// would cause an exception

13:40 bendlas: or is a working foo/bar/baz a side effect of makeing foo// work?

13:40 Bronsa: ok, IC

13:41 Bronsa: bendlas: I suspect that the reader change that made foo// a valid symbol made the reader accept foo/bar/baz aswell, unintentionally

13:42 dnolen_: Bronsa: foo/bar/baz has actually worked for a long time, it's seems like a real ambiguity to me

13:42 agarman: Bronsa: not sure why bar/baz shouldn't be valid

13:43 Bronsa: tools.reader for example doesn't use tha same regex as LispReader.java and errors out when trying to read foo/bar/baz

13:43 bendlas: interesting, so i guess clojure.tools.reader does more input validation; and since that's what cljs uses by now there is this incompatibility

13:43 Bronsa: dnolen_: oh, you're right

13:43 dnolen_: well it's just another case of GIGO

13:45 the docs are explicit about that, so I'm confident in saying that foo/bar/baz is -- and has always been -- invalid

13:46 bendlas: Bronsa: I'm not so sure, stuff like (symbol "foo bar// $#%" "baz//zab") is perfectly valid

13:46 there is just no reader syntax for it

13:46 Bronsa: bendlas: it's allowed because there's no validation, but it's not valid

13:47 bendlas: nope, even if there was validation, it should only ever be in the reader

13:47 the docs you're referring to are also on a page called /reader

13:48 Bronsa: at least that's my firmly held opinion, that constructors for symbol, keyword, ... should do no further validation than to see if namespace and name are strings

13:49 agarman: Bronsa: the docs I'm reading just says that symbols containing / are qualified

13:50 Bronsa: my understanding of qualified is that the namespace will consume the symbols string to the first / not that there can be no additional /

13:50 bendlas: agarman: well, it says '/' has special meaning, it can be used once in the middle of a symbol

13:50 hyPiRion: The docs are outdated

13:50 bendlas: that can conceivably be interpreted to mean "at most once"

13:51 hyPiRion: There's nothing about quote being a legal part of a symbol on the /reader page.

13:51 agarman: bendlas: the rest of that doc is "to separate the namespace from the name" nothing stating that an additional / can't be used, but it's assumed that it won't have special meaning then

13:52 not assumed it's explicit that any other / won't have special meaning

13:52 bendlas: agarman: yes, I tend to follow this interpretation. Bronsa seems to be against it and dnolen_ seems to be on the fence and wants it discussed on clojure-dev

13:53 agarman: hyPiRion: (other characters will be allowed eventually, but not all macro characters have been determined) would cover '

13:54 in that the expected behavior is indeterminate

13:55 Bronsa: bendlas: agarman wrt "foo/bar/baz", as hyPiRion says the clojure.org docs are outdated and open to interpretations, however if you read https://github.com/edn-format/edn#symbols it's clear that "foo/bar/baz" is not valid

13:56 agarman: edn is a data exchange format... it doesn't represent the full capabilities of the reader

13:56 though I'd agree that they should be fairly consistent

13:56 Bronsa: agarman: I'm well aware of that but I hardly doubt that an edn symbol and a clojure symbol would differ

13:57 bendlas: Bronsa: but they do, ' isn't mentioned in edn symbols either

13:58 Bronsa: (edn/read-string "foo'") works though

13:58 Bronsa: bendlas: eh, that's a bug in the spec

13:58 agarman: ,(clojure.edn/read-string "foo/bar/baz")

13:58 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.edn>

13:59 agarman: ,(require '[clojure.edn :as edn])

13:59 clojurebot: nil

13:59 agarman: ,(edn/read-string "foo/bar/baz")

13:59 clojurebot: foo/bar/baz

13:59 * bendlas chuckles ....

13:59 agarman: valid is what works

13:59 dnolen_: Bronsa: well I think supporting quirks is OK - but I definitely never thought of foo/bar/baz as being valid

13:59 agarman: docs or code should be fixed though

13:59 dnolen_: agarman: sadly it is not, it's just undefined

13:59 justin_smith: ,(edn/read-string "this\nis\nmultiple\lines")

13:59 clojurebot: #<RuntimeException java.lang.RuntimeException: Unsupported escape character: \l>

13:59 hlprmnky_: Bronsa, bendlas: thanks for the assistance - I was (after only a few moments of slack-jawed disdain) able to use .getConstructor … .newInstance to do what I wanted

13:59 justin_smith: ,(edn/read-string "this\nis\nmultiple\nlines")

13:59 clojurebot: this

14:00 hlprmnky_: slack-jawed disdain at the hoops you have to jump through to make Java give you an instance of something via reflection, not at new being a special form :)

14:00 agarman: ,(type (edn/read-string "foo/bar/baz/quux/giggle"))

14:00 clojurebot: clojure.lang.Symbol

14:01 bendlas: hlprmnky_: yw

14:01 hyPiRion: that's because

14:01 ,(read-string "foo/bar/baz/quux/giggle")

14:01 clojurebot: foo/bar/baz/quux/giggle

14:02 Bronsa: agarman: bendlas I'm in the difficult position of using an uncomplete/outdated spec as basis of my thesis, but I think the documentation is clear on the foo/bar/baz issue.

14:04 agarman: bendlas paraphrasing, it says "those are the valid characters you can use in a symbol, additionally you can use '/' once in the middle of the symbol", that "once" is definitely "once and only once" if you take into account how it's phrased for '.': "it can be used one or more times in the middle of a symbol"

14:04 bendlas: but why not take a step back, and admit that it should mean, what we want it to mean, with Rich having the last say of course.

14:06 Bronsa: yeah, ok, foo/bar/baz really should be disallowed in edn _and_ in the reader, because it's unnessecarily surprising

14:06 however, (symbol "foo/bar" "baz") aswell as (symbol "foo" "bar/baz") should be considered valid

14:07 (and distinct)

14:11 Bronsa, dnolen_, agarman, hyPiRion: unless any of you is already at it, I'll do a writeup to clojure-dev

14:14 Bronsa: bendlas: you might be right about "runtime symbols" not being restricted in the same ways of "reader symbols", I have to say that every time the discussion about (symbol "foo bar") being valid has come up, the consensus has been that it's just a result of GIGO -- go on with a ml writup if you want official answers

14:27 shoepie: any vim users know how to correctly indent .clj files using vim-clojure-static?

14:32 TimMc: ,(.newInstance String) ;; hlprmnky: It's easy if you want the nullary constructor.

14:32 clojurebot: ""

14:33 hlprmnky: true, but I actually needed a String constructor

14:34 it’s not so bad, considering, I just don’t have to wander down that deep into the boilerplate mines very often

14:35 amalloy: hlprmnky: clojure.lang.Reflector/invokeConstructor is easier to use

14:36 ,(let [c java.util.ArrayList] (clojure.lang.Reflector/invokeConstructor c (object-array [10])))

14:36 clojurebot: []

14:36 amalloy: (that 10 is the initial capacity, so it still just looks like an empty list

14:36 )

14:36 hlprmnky: !

14:37 that is indeed much nicer

14:37 thanks!

14:44 TimMc: So that's if you only care about dynamic dispatch to a constructor, not static dispatch.

14:44 handy

14:47 amalloy: TimMc: indeed, i think it's the same logic that (Foo. x y z) goes through if you don't hint x/y/z

14:48 the last time i wanted to reflectively invoke a constructor i wanted to do it multiple times, though, so i ended up saving the Constructor handle to reuse it

14:48 the reflector doesn't give you that flexibility

14:48 (if you care about performance, anyway)

14:52 upwardindex: I’m getting Unsupported major.minor version 51.0 when trying to lein `cljsbuild once`. Google tells me something about not having the right jdk/jre. Has anyone encountered this?

14:55 amalloy: upwardindex: you're running something compiled against java 7, on a jre 6 or lower

14:55 justin_smith: upwardindex: what does "java -version" return in your shell?

14:56 upwardindex: justin_smith: java version "1.6.0_65" in terminal but in system preferences it says java 1.7something

14:56 justin_smith: upwardindex: then call the 1.7something version, or fix your path so it is before the 1.6

14:57 upwardindex: you can explicitly set the java location via an env var or project.clj setting in lein

14:58 upwardindex: justin_smith: thank you, I’ll look into that

14:58 justin_smith: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L259

14:58 example in the above link

15:13 ToxicFrog: Huh.

15:13 So I can't use :refer :all even for things that will be released as an uberjar, because the warning messages from the compiler can't be supressed and are emitted when it's run from the jar, too

15:15 noonian: ToxicFrog: you might find slamhound helpful; it will automatically figure out which vars you're using and generate a nice require form for you

15:15 https://github.com/technomancy/slamhound

15:16 bendlas: ToxicFrog: Don't use :refer :all, only acceptable usage is from a repl session how or why should uberjar protect from its perils?

15:17 yeah, slamhound's pretty cool for that

15:18 ToxicFrog: bendlas: I'm :refer :alling core.typed, so that I get all of the typenames in scope, rather than having an ugly mix of naked type names and t/ prefixed type names.

15:18 TimMc: bendlas: It is sometimes appropriate.

15:18 ToxicFrog: However, this also brings in core.typed/for et al which generates the shadowing warnings.

15:18 TimMc: You can exclude that, I think?

15:18 ToxicFrog: I was hoping that the requiring would happen entirely during the compilation process, and thus there would be nothing to warn about during runtime when the jar is executed.

15:19 Of course, this doesn't address at all the common case where you want to refer those and quite deliberately shadow the clojure.core versions

15:19 AFAICT, in that case, you're just screwed

15:19 TimMc: ToxicFrog: :refer-clojure :exclude

15:20 bendlas: ToxicFrog: yeah, it would be pretty cool for clojure to be able to compile that way

15:20 similar to cljs

15:20 maybe we'll get there one day, with the lean-compile stuff

15:20 ToxicFrog: TimMc: holy this I did not know about refer-clojure

15:20 Thank you

15:24 jlongster: do you have to use a buffer when using a transducer with a channel?

15:31 linman32: hi i have a clojure compile error.

15:31 http://pastebin.com/ZZFaNFFC

15:32 the error doesn't seem to point to a specific file though

15:32 ToxicFrog: Welcome to clojure compile errors: abandon every hope, ye that enter

15:33 justin_smith: /tmp/form-init3292773767470107555.clj:1:72 is something your toolchain likely created

15:33 no promises that it is readable...

15:33 the :1:72 mean line 1, character 72

15:33 stompyj: jlongster: I’ve only ever seen it done that way, but I don’t know for sure

15:34 linman32: the file is no longer there

15:34 jlongster: stompyj: I think that's true. reading the source, and it kinda makes sense

15:35 justin_smith: linman32: what did you run when you got that error? lein repl?

15:35 linman32: justin_smith: should i try updating my toolchain? i got leiningen recently. like 3 days ago

15:35 justin_smith: yes

15:35 justin_smith: was this run from inside a project directory?

15:36 linman32: yes

15:36 justin_smith: can you share your project.clj?

15:36 I suspect a string where there should be a symbol, in either project.clj or your core namespace

15:37 linman32: justin_smith: https://github.com/AustinClojure/groops/blob/master/project.clj

15:38 justin_smith: :init-ns should not be a string, it should be a symbol

15:38 that may be the issue

15:38 (under :profiles / :dev / :repl-options)

15:39 so try taking out the quotation marks, and running lein repl again - that may just fix it

15:40 linman32: wow, seems to be working! that was a nice find

15:41 caldiar: New to clojure and was wondering if it's considered "proper" clojure to make use of records rather than maps. Or are records/protocols there to make transitioning to clojure easier for people used to object-oriented design?

15:41 linman32: justin_smith: how did you find it so fast?

15:41 justin_smith: linman32: those temp files are created based on the contents of project.clj

15:42 the error was string could not be cast to symbol

15:43 so I looked for strings that should not be strings, it's a small file

15:43 double checked with the lein example project.clj that :init-ns should not be a string

15:43 perplexa: had some time to read up on reduce+conj \o/

15:44 caldiar: To provide some context, I have several entities which can have different behaviors such that a minotaur can move 1 unit at a time while an imp could move 2 units at a time. I was thinking a protocol and records which implement the move method would be best suited for this or if there was a more idiomatic way.

15:44 justin_smith: caldiar: you can switch to records if maps are slowing you down in a bottleneck

15:44 a multimethod can determine behavior from any function on your data

15:44 also, multimethods that use keywords can take advantage of multiple inheritence via derive

15:45 (this is not possible with records)

15:45 well, I guess it could be, but it isn't possible with protocols is what I really meant

15:48 caldiar: one of the ways I'm seeing things done (from the caves of clojure series of articles) is that there's multiple protocols and a record which uses extend-type for each protocol it would like to implement

15:48 justin_smith: that's another way to do it

15:48 protocols are a pain in the ass in interactive development

15:48 mdeboard[IND]: Elixir helped me understand protocols in Clojure much better

15:49 caldiar: my concern is that I don't want to get into bad habits and wind up having things come back to bite me later

15:49 justin_smith: maps upgrade seamlessless to records

15:50 caldiar: alright, thanks guys

15:53 borkdude: I would like to start my clojure app in a Docker container, wait until the server is started and then run tests against that server in the same docker container. My question: can I run test from something like an uberjar which I will add to the container?

15:53 so basically it all runs in one container

15:54 and I don't want to install leiningen etc in the image, too much work

15:54 justin_smith: borkdude: you can use test/run-tests for each test-ns inside an init function

15:55 borkdude: justin_smith ah, of course, thanks.

15:55 justin_smith: you may want to make sure the test namespaces are compiled into the uberjar, of course

15:55 borkdude: will the test code be included in an uberjar?

15:55 justin_smith: if it isn't, there should be a simple path to make it happen

15:55 borkdude: justin_smith hmyeah

15:57 justin_smith: and its easy to check if those files are in your uberjar - a jar is just a zip with special properties

15:59 borkdude: justin_smith right

17:13 mikerod: I'm wanting to understand the rationale behind this:

17:13 ,(coll? {})

17:13 clojurebot: true

17:13 mikerod: ,(instance? java.util.Collection {})

17:13 clojurebot: false

17:14 mikerod: Are there any good links?

17:14 :D

17:14 jkj: mikerod: well i quess java collections have features that coll doesn't need

17:14 let's see

17:14 mikerod: jkj: searching has been difficult

17:14 hitting completely unrelated topics

17:15 justin_smith: ,(instance? clojure.lang.IPersistentCollection {})

17:15 clojurebot: true

17:15 justin_smith: that's what coll tests

17:15 mikerod: yes, justin_smith I was just shorthand'ing that part

17:15 jkj: mikerod: momentos. firing up my repl

17:15 mikerod: ,(instance? java.util.Collection [])

17:15 clojurebot: true

17:15 jkj: when do we have fast start

17:15 mikerod: I just see that Clojure chose to view a Persistent*Map as a IPersistentCollection

17:16 but not as a j.u.Collection

17:16 jkj: ,(map :name (:members (clojure.reflect/reflect java.util.Collection)))

17:16 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.reflect, compiling:(NO_SOURCE_PATH:0:0)>

17:16 jkj: oops. it is cljs?

17:16 justin_smith: mikerod: based on the docs for Collection, it is not used for maps

17:17 jkj: mikerod: (:bases (clojure.reflect/reflect {}))

17:23 mikerod: justin_smith: I don't see the docs that you are referring to for that

17:24 It makes sense to me that Clj maps are not a j.u.Collection since j.u.Map is not though. I guess I should just look at it that way.

17:25 justin_smith: http://stackoverflow.com/a/2651833/2258453 answer has a quote from the java design documents

17:31 mikerod: Oh, yes I should have looked for that. Thanks justin_smith

17:32 and thanks jkj for the input

18:02 razum2um1: is there any library to inspect java object - for now i use https://gist.github.com/razum2um/ffaaf90731f27a988141 but maybe someone has better ways?

18:07 better to say - is there any way to get, say, annotated source from maven (if possible) and show members with descriptions. Or (javadoc) with lucky google is best option?

18:10 justin_smith: #(apply dissoc % [:exception-types]) is #(dissoc % :exception-types)

18:11 #(contains? (:flags %) :public) could be (comp :public :flags) in this case

18:11 celwell: Hello, what's a good library (or technique) for running a function every 3 minutes?

18:12 Jaood: sleep?

18:13 celwell: Jaood: is that safe? i just don't want to run out of memory after a few days

18:13 Jaood: Thread/sleep

18:13 justin_smith: celwell: depends on whether you are using loop / while or simple self call

18:14 arrdem: Bronsa: so does the scheduler buy you anything performance wise?

18:14 justin_smith: celwell: for more power (and complexity) there is java.util.Timer which you can use via interop

18:15 bendlas: razum2um1: just the other day, I've written a thing that uses reflection to pretty-print java classes: https://github.com/webnf/webnf/blob/master/base/src/webnf/base.clj#L100

18:16 it's turned out pretty nifty for exploring interacting with java objects from repl

18:16 razum2um1: justin_smith: thanks for feedback ;)

18:17 justin_smith: there is also bean, which suffices for some objects (and at least helps with others)

18:17 ,(bean "hello")

18:17 clojurebot: {:empty false, :class java.lang.String, :bytes #<byte[] [B@1c1e75a>}

18:17 razum2um1: bendias: could you provide an example of this?

18:18 Bronsa: arrdem: no, it just automates the pass composition/dependency resolution

18:18 arrdem: Bronsa: :thumbsup:

18:18 Jaood: celwell: I guess using a delay with some time api could be more elegant

18:19 dbasch: celwell: that question is pretty generic, it depends on what you want to do and what level of operational reliability you need

18:19 celwell: e.g. if you don't trust your own code you could use cron to start a jvm every time

18:19 razum2um1: bendlas: may I mention webnf in https://github.com/razum2um/awesome-clojure under frameworks?

18:20 celwell: dbasch: I'm running a ring server and need to spawn a 3-minute-interval-called function that gets certain rows from a db and may or may not update those rows.

18:20 Bronsa: arrdem: I was able to reduce the number of complete tree traversals from 8 to 7 but I doubt it's going to result in a noticeable speedup

18:21 bendlas: razum2um1: here http://pastebin.com/CsUGvAy5

18:21 arrdem: Bronsa: yeah that sounds about right.

18:21 bendlas: razum2um1: of course!

18:22 dbasch: celwell: as long as you don't hold on to the rows so they can be garbage-collected, and you run your jvm with enough heap, you should be fine

18:22 bendlas: although, it's intended to not be a framework, but a set of orthogonal libs that happen to interact well

18:22 dbasch: celwell: if you're on linux there's always a chance that the kernel might kill your process, so you may want to have a watchdog script to restart it

18:23 celwell: dbasch: are you saying that same would be true for the ring server itself? it might just die without auto restarting?

18:23 dbasch: celwell: yes, any jvm on linux could die without autorestarting

18:24 celwell: you can tell the oom killer to ignore a process, but it's usually not the best idea

18:25 arrdem: dec finite memory machines

18:25 celwell: dbasch: I'm relatively new to the JVM (coming from PHP). Do you know of any material I can read to learn how to have a reliable ring server. Sorry I guess that's vague. But with PHP I would just let it run until I something messed up and i would restart apache.

18:26 razum2um1: bendlas: looks nice, maybe extract some fns like that?

18:27 bendlas: razum2um1: by 'extract' do you mean 'pack them in a library, so that they can be used independently'?

18:27 razum2um1: bendlas: pack

18:27 bendlas: if so, that's what I'm doing with webnf

18:28 razum2um1: bendlas: they are too different, e.g. hostname and pr-cls

18:28 dbasch: celwell: the important thing is to run the jvm with appropriate parameters, and to have a cron job or script to restart it if it dies unexpectedly

18:28 bendlas: it's basically all the fns, that I kept copy-pasting from project to project

18:28 dbasch: celwell: you also want to configure it to run on boot if your machine could lose power or reboot for some reason

18:28 razum2um1: bendlas: )) yep. saw this in clojure community everywhere

18:29 celwell: dbasch: thanks for the advice

18:30 razum2um1: hm folks, why not to join efforts and have one modular project like webnf, but having MORE than 1 contributor. just like active support in ruby land?

18:30 bendlas: yeah, I'm trying to split them into sub projects tastefully, it's always a balancing act between getting on with my projects while pushing snippets into webnf, and then refactoring webnf itself, e.g. introducing new packages

18:31 razum2um1: now I see everyone is duplicating some fnsctions with different names or even copypaste them into HIS toolbox library

18:31 is it really a trend to have *my-own-helper-library* ?

18:31 justin_smith: no

18:32 razum2um1: e.g. timbre's author has his lib too

18:32 bendlas: razum2um1: yay, I'd be all for it. problem is maintainership in all its facets

18:32 justin_smith: check out flatland/useful for a general set of useful stuff that isn't in core though https://github.com/flatland/useful

18:33 razum2um1: justin_smith: 6 contributors ;)

18:33 justin_smith: and they accept pull requests

18:34 razum2um1: justin_smith: I meant forces are disjoint. compare rails with 2k contributors (of cource, clj is not widly used, but *there ARE more than 6 clojurists)

18:35 noonian: ,(def truthy? (comp not not))

18:35 clojurebot: #'sandbox/truthy?

18:35 justin_smith: razum2um1: I'd say 6/2000 is about the ratio of clojure to ruby users (maybe it is a bit hight actually)

18:35 noonian: isn't that what boolean does?

18:36 ,(map boolean [true false nil 1 0 () []])

18:36 clojurebot: (true false false true true ...)

18:36 noonian: justin_smith: heh, i guess so; i didn't know boolean was a core function :P

18:36 razum2um1: justin_smith: e.g. in golang land there are LOTS of lein/bundler analogs all of them are depending on 1-2 devs. we have lein and it's cool or pain of choice ;)

18:37 i meant *no* pain of choice ;)

18:38 justin_smith: there have been alternatives to lein, but they haven't gone far

18:38 noonian: i think most clojure libs tend to be smallish and so much easier to maintain by 1-2 people, also tend to get to a point where they work and aren't touched much except for major refactors or api changes

18:38 xemdetia: such is the land of lisp

18:39 razum2um1: justin_smith: yes and 227 contributors to lein show where the mainstream is. why there is no lein-like "activesupport" what do you think?

18:40 justin_smith: razum2um1: for the most part, clojure people hate frameworks and don't use them

18:40 razum2um1: it doesn't have to be one repo

18:41 but can be ogranisation

18:41 bendlas: razum2um1, justin_smith: so IMO, if we were to have a place where everybody could maintain their favourite helper code, it would nessecarily have to be split into various subprojects with different focus

18:41 justin_smith: razum2um1: and if there was a single lib that supplied multibyte strings, internationalization, time zones, testing, etc. for clojure, people would ask why so many different things were in one lib

18:41 xemdetia: I thought we already had github /snark

18:41 bendlas: that's why i laid out webnf that way from the start

18:41 razum2um1: bendlas: yes, but I don't see any so far

18:41 oops, perhaps webnf is it ;)

18:42 but again, bendlas, you are *alone*

18:42 justin_smith: razum2um1: thanks to lein / clojars, we don't need everything to be coming from one organization. It is easy for anyone to share whatever libs they would like to share.

18:43 bendlas: yeah, ML reactions to new announcements have become increasingly apathetic, last couple of years

18:44 razum2um1: justin_smith: I didn't mean that, I mean some really mainstream helper lib. like clojure.contrib before, *but* it doesn't have to be single project/repo

18:44 noonian: it seems like we are somewhat converging in terms of ways to design system with design patterns like stuart sierra's component and libraries building on those ideas like trapperkeeper and modular

18:44 bendlas: I mean, leiningen + clojars gets you 90% there, the only thing that's really missing are dependency sets to get rid of those ridiculously long :dependency lists

18:44 i.e. webnf.deps/*

18:44 razum2um1: bendlas: :)

18:44 justin_smith: razum2um1: we have a mainstream helper lib. If you want a bigger, more comprehensive one, go ahead and make it I guess?

18:45 razum2um1: justin_smith: there will be no good since I will be only one, who is using it

18:46 justin_smith: if it's good enough, other people will use it, if it isn't good enough they shouldn't be using it - I really fail to see what the problem is here

18:47 noonian: i bring prismatic plumbing into all the project i make now, i think they've done a good job extending the language with small useful functions/macros

18:47 bendlas: justin_smith: the problem is, that even for more that good enough code, if it doesn't hit an immediate need (like leiningen did), you have a discoverability problem (i.e. marketing)

18:48 razum2um1: justin_smith: it starts when I started write class-inspection function and setup a repo for it and some more others, then saw bendlas's webnf, then you… everyone has his own. it dramatically reduces recognizable of other's code

18:48 noonian: the ?> and ?>> conditionals for use with the threading macros are really nice

18:49 razum2um1: justin_smith: I mean to read someone's code with *HIS* helper functions we must read them all too

18:49 justin_smith: some standard is needed i think

18:49 justin_smith: how much of rails code have you read?

18:49 I mean the underlying code

18:49 razum2um1: justin_smith: lots and have commits there

18:51 bendlas: FWIW, i don't think rails is the model we should be aiming for, despite its success

18:51 razum2um1: and some not accepted PR's since I made gems for that, but it's offtopic

18:51 bendlas: I try to think more along the lines of the new clojure contrib stuff

18:52 single-purpose, replaceable

18:52 justin_smith: bendlas: agreed 100%, just checking if razum2um1 was actually one to read the source for all the libraries used by the libraries he uses

18:52 razum2um1: bendlas: now I mean some very specific thing: activesupport is *widely* accepted, without rails too, and I read code with it much faster

18:53 bendlas: OIC

18:54 i think, the excellent platform support of clojure hurts this cause. Most people are just like: 'eh, i can use that java lib'

18:54 justin_smith: and they are probably better off just using the java lib too, in many cases

18:55 bendlas: true\

18:55 bja: I don't think I even use very many clojure libraries. Mostly just wrappers for java stuff

18:56 razum2um1: bja: do you think it's better *even* no to wrap them?

18:57 noonian: i prefer pure clojure libs to java wrappers if they are available

18:57 razum2um1: actually I'm late to this party, is this trend still in (wrap java)?

18:57 noonian: tend to agree

18:58 bendlas: i'd say yes, but only for stuff whose java impl is excellent

18:58 matthiasn: hey guys, I am stuck with a problem. I have an application that runs nicely on my mac but when I try to run it on Ubuntu 14.04 (lein run or the uberjar makes no difference) I get the following error: Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :make-writer of protocol: #'clojure.java.io/IOFactory found for class: nil, compiling:(/tmp/form-init5185754411886008906.clj:1:72)

18:58 Does anyone have an idea where to look? thanks a lot

18:58 noonian: when there are big java libs that don't need to be re-written people tend to wrap them, like aws java clients for example

18:59 rweir: weird java errors always make me trash ~/.m2/repos just in case

18:59 justin_smith: matthiasn: wait, the uberjar is referring to /tmp/form-intblablahblah?

18:59 noonian: matthiasn: when you say it runs fine on your mac did you try running from an uberjar or just in the repl?

18:59 bja: razum2um1, it depends on the java library. I go back and forth on whether marceline is an improvement over regular JVM interop for Storm's Trident API

18:59 bendlas: matthiasn: thats basically a null pointer exception. Probably from a resource fail, that's not been found on the different platform

19:00 matthiasn: @noonian on mac either repl, run or uberjar all work

19:00 bendlas: lol, *resource file

19:01 matthiasn: @justin_smith: that was when doing lein run

19:01 justin_smith: matthiasn: OK, what is the error with an uberjar?

19:01 noonian: matthiasn: maybe forgot to check a resource into git or something?

19:01 justin_smith: also, the error with lein run points to a file, in /tmp/ that is generated based on your project.clj

19:02 matthiasn: noonian: there’s one config file that’s not checked in because of credentials, but it’s there locally

19:02 justin_smith: matthiasn: with an identical path?

19:02 bendlas: look for stuff that would lead to (clojure.java.io/writer nil)

19:03 matthiasn: justin_smith: with uberjar its just: Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :make-writer of protocol: #'clojure.java.io/IOFactory found for class: nil

19:04 bendlas: does it try to write to some OSX specific path like /User/... ?

19:04 matthiasn: justin_smith: in the project root

19:04 justin_smith: yeah, something in there is trying to create something to write output to (a file? a network connection?) and is getting nil

19:04 matthiasn: can you share your project.clj?

19:05 matthiasn: sure: https://github.com/matthiasn/BirdWatch/blob/master/Clojure-Websockets/project.clj

19:05 justin_smith: matthiasn: in the ubuntu computer, is there a target/ directory? git won't create it if it doesn't have any checked in files inside it

19:06 matthiasn: Oh I have an idea, let me check

19:07 justin_smith: also, "target/%s" may need to be "target/%s/" - at least that is how it is done in the example project.clj

19:08 matthiasn: found it :-)

19:08 justin_smith: what was it?

19:09 matthiasn: so there was a new key in twitterclient.edn for the name of the PID file to write

19:09 and I did not add that key in the edn file on the server

19:10 that was the right pointer with the program trying to write something :-) thanks a lot

19:18 phao: Hi. I'm curious. Does Clojure have something like CL's loop facility?

19:18 And... Does Rich Hickey come in here? Hehe

19:18 justin_smith: phao: not really, there are for and doseq, but we don't use DSLs as much as CL does

19:18 phao: justin_smith, Ok. Thanks =).

19:18 matthiasn_: hmm, got kicked out of my network for the last three minutes or so

19:18 thanks for the help, much appreciated

19:18 noonian: what does cl loop macro give you that for doesn't? i'm not trying to be argumentative i just don't have any cl experience

19:18 justin_smith: phao: actually some uses of "loop" would even be covered by our own loop, or reduce (in combination with reduced for short circuiting), or iterate as well

19:18 noonian: it is an embedded language for describing recursion

19:18 (loop for item in list for i from 1 to 10 do (something))

19:18 technomancy: CL LOOP can do basically anything

19:18 phao: noonian, I do have experience in CL, but not much. It could be just likely that you know more about it than I do.

19:18 justin_smith: (loop for i from 20 downto 10 ...)

19:18 technomancy: in clojure you would express it as a series of sequence operations, but in CL you just mush it into a single macro

19:18 phao: I was just curious because my belief is the same as technomancy's.

19:18 justin_smith: (loop for k being the hash-keys in h using (hash-value v) ...)

19:18 it's almost like cobol

19:19 phao: technomancy, any clues on why loop-ish macros aren't in clojure?

19:19 technomancy: even among CL fans loop is pretty controversial because it tries to be english-like instead of being lispy

19:19 phao: you mean why huge english-like macros in general aren't in wide use?

19:19 phao: technomancy, that as well =)

19:19 justin_smith: right, it is a COBOL like language for describing loops, that just happens to sit in a lisp file

19:19 phao: justin_smith, hehehehe

19:20 technomancy: I would have thought that'd be self-evident. trying to be english-like pretty much always results in weird unpredictable idiosyncracies because english is a crazy language.

19:20 phao: technomancy, I didn't know loop also had these issues

19:20 justin_smith: but in all seriousness, the clojure design goals are to make small composible things that combine powerfully, rather than monolithic standalone features

19:20 phao: I thought it kept itself to simple syntactical constructions.

19:21 technomancy: loop is basically its own language... we already have a language that we like for describing sequences; adding another one doesn't make sense

19:21 phao: justin_smith, Right. CL seems, to me, to approach the other end of that.

19:21 technomancy: I'm sure someone has ported it as an exercise though

19:21 noonian: (loop for i from 1 to 3 sum (* i i)) would be (reduce + (range 1 4)) in clojure

19:21 justin_smith: phao: https://www.refheap.com/90332 this is a valid usage of the loop macro

19:22 from this page http://www.gigamonkeys.com/book/loop-for-black-belts.html

19:22 phao: hahahahaha

19:22 it looks like those algorithms book pseudo-code

19:22 justin_smith: not quite as verbose as COBOL, and not in all caps, but the same "we want to program in english" concept

19:22 noonian: most of the examples from here look like they would read better in clojure imo

19:22 http://www.unixuser.org/~euske/doc/cl/loop.html

19:23 cl loop macro for beginners

19:24 phao: justin_smith, stuff like this breaks my foundations on believing that there is a logic which controls it all.

19:24 arrdem: so um... what does this macro _not_ do

19:24 justin_smith: "it all"?

19:24 arrdem: solve the halting problem? dunno, maybe it does that too

19:24 phao: justin_smith, In this case, what is acceptable or not by the loop, and what it does, and how the macro decides what to do, and many other aspects.

19:25 arrdem: justin_smith: if it does I'm handing in my badge

19:25 justin_smith: arrdem: I am still laughing at the example I pasted in the refheap link above

19:25 arrdem: justin_smith: I missed it. repost?

19:25 * arrdem only joined his proxy about a minute ago

19:25 justin_smith: arrdem: https://www.refheap.com/90332 this is a valid usage of the loop macro

19:25 phao: justin_smith, Oh! THe 'and' tokens combine stuff together.

19:25 Now things are starting to make sense.

19:26 technomancy: it would make a lot more sense if it just used parens like regular lisp

19:26 arrdem: justin_smith: we're a lisp. fuckit. lets embed some bash.

19:26 ^ what technomancy said

19:26 phao: technomancy, I couldn't agree more =)

19:26 justin_smith: arrdem: hell, I still maintain it's closest living relative is COBOL

19:26 phao: technomancy, but maybe it's just a learning curve kind of thing, as in once you learn it, you maybe can be productive with it.

19:26 arrdem: justin_smith: "living"...

19:27 technomancy: clojure.core/for is the closest thing to a mini-language in that it supports :when and :let, but they're just a different syntax for things you already know

19:28 justin_smith: phao: but we can't easily compose new functionality by combining it with other tools

19:28 phao: justin_smith, I see.

19:28 arrdem: I guess my issue with this is while it's a legitimate macro it's almost entirely divorced from the syntactic style of the host language..

19:28 noonian: yeah, i had no idea for supported :when and :let for months and was doing it all in the body or filtering outside

19:29 arrdem: which aggravates what justin_smith is saying that it doesn't trivially or obviously compose

19:29 phao: justin_smith, CL has the notion of a sequence type too, if I'm not mistaken, can't the loop macro work with any sequence?

19:30 noonian: it just seems like its trying to do too much all so you can do it in a single form

19:30 justin_smith: phao: in one of the examples I quoted above, it was iterating on the keys / values of a hashtable

19:32 amalloy: oh boy, is it time to talk about LOOP again?

19:32 arrdem: no thanks

19:32 justin_smith: ~loop

19:32 clojurebot: I don't understand.

19:32 justin_smith: ~cl-loop

19:32 clojurebot: No entiendo

19:32 phao: hehehe

19:32 justin_smith: clearly, we need to rectify this situation

19:33 phao: justin_smith, put that link as the output for ~loop

19:33 justin_smith: clojurebot: loop |is| https://www.refheap.com/90332

19:33 clojurebot: In Ordnung

19:34 phao: hehehehe

19:34 rweir: is that really truly valid CL?

19:35 justin_smith: rweir: yeah

19:36 here is the formal description, which may be even more daunting http://www.lispworks.com/documentation/HyperSpec/Body/m_loop.htm

19:44 clop2: hi, new to clojure (from common lisp), going to port an app to get some experience; wondering, does clojure have any syntax mechanism for structure sharing input in its reader, like #1=... style reader macros in lisp?

19:46 amalloy: clop2: no. it's kinda hard to have such things anyway, in a language that is immutable and strict/eager

19:46 SegFaultAX: clop2: Clojure doesn't have reader macros, no.

19:47 clop2: ok thanks, so i guess i need to write a parser, that'll be a good project too

19:47 amalloy: SegFaultAX: he's not asking about user-supplied reader macros, but about one specific one that the CL reader has. clojure certainly has many prepackaged reader macros, like #{...}

19:47 SegFaultAX: amalloy: Do I need to specify "user-defined" there? I assume the "except for what Clojure does internally" is implied.

19:49 amalloy: SegFaultAX: if i include the "implied" part, then you haven't even attempted to answer the question. "clojure doesn't have user-supplied reader macros" is not an answer to "is there a #1= macro built in"

19:49 TEttinger: what does #1= do?

19:50 amalloy: TEttinger: it's for printing circular references

19:50 (and then reading them back in as still-circular)

19:50 TimMc: I think that's called sharp-notation in some JSON supersets.

19:50 clop2: right, or for simply sharing common subexpressions (that don't happen to be circular)

19:50 amalloy: more genrally, i guess, it's for capturing shared structure, of which circular references are a special case

19:51 TEttinger: you can change the behavior of fns like pr and prn pretty easily, though I don't know how you'd detect shared structure

19:52 justin_smith: TEttinger: but could you read in a way that made prn actually do the right thing?

19:52 amalloy: clop2: does CL really use that for non-circular lists? like, if i write (let ((x (cons 1 2))) (list x x)), i don't get a #1= notation

19:52 TEttinger: justin_smith, with read-eval, yes

19:53 justin_smith: ahh, of course, read-eval

19:53 clop2: amalloy: cl can be instructed to print with structure sharing if you bind *print-circle* to t, or custom printers can print it out in other cases

19:53 TEttinger: ,(print "#=(+ 1 1 1)")

19:53 clojurebot: #=(+ 1 1 1)

19:53 clop2: amalloy: typically it will only create #= abbreviations for circular objects, I think, but I'm not an expert

19:54 amalloy: actually even if i write (let ((x (cons 1 2))) (setf (cdr x) x) x) i don't get that pretty notation out of clisp; the interpreter just hangs

19:54 clop2: amalloy: but for reading back in, you can do, e.g., (+ #1=5 4 #1#) or similar

19:54 amalloy: but i can't figure out how to set print-circle

19:54 anyway, not really important

19:56 clop2: this should do it: (let ((*print-circle* t) (x (cons 1 2))) (setf (cdr x) x) (print x) nil)

19:56 TEttinger: hm, I can't remember if clojurebot allows read-eval

20:11 amalloy: so guys, i found a funny trick in my old 4clojure solutions. suppose you have 3 objects named x, y, and z, and you want to compute (f x) + (f y) - (f z), but you don't like repeating f. you'd rather use (map f [x y z]) or something like it, and then do the math on the resulting list

20:11 here is the solution i used, way back then: (- (apply - (map f [z x y])))

20:16 justin_smith: hah, nice

20:16 amalloy: for those following along at home, that converts the problem to -(f(z) - f(x) - f(y))

20:16 - has the funny property that the first item is given a different sign than the rest

20:21 TEttinger: ,(apply - [10 22 55])

20:21 clojurebot: -67

20:21 TEttinger: huh

20:22 justin_smith: ,(reduce - [10 22 55])

20:22 clojurebot: -67

20:22 TEttinger: ,(reduce - 0 [10 22 55])

20:22 clojurebot: -87

20:22 TEttinger: neat trick, amalloy

20:22 (inc amalloy)

20:23 lazybot is ded

20:23 amalloy: he's been having a rough time recently for some reason

20:23 arrdem: the bot is dead long live the bot

20:26 dbasch: here's a (stupid) gotcha. What do you expect t and second t to be? https://www.refheap.com/90336

20:27 justin_smith: well, locking 128 won't work

20:27 or won't really do what you expect at least

20:28 amalloy: yeah, don't lock integers. what kind of wacko thinks he deserves an exclusive lock on a mathematic ideal?

20:28 dbasch: amalloy: you can happily lock 127 or -128 though

20:28 justin_smith: well, at least for 127 you have a single instance

20:28 dbasch: or anything in between

20:28 amalloy: dbasch: sure, you get lucky with an implementation detail

20:29 i doubt the interning of Long objects between -128 and 127 is part of the jvm spec

20:29 (or the jls)

20:30 dbasch: amalloy: in fact, the doc for the oracle jvm says they "may cache values outside this range"

20:30 clop2: does clojure have any haskell/ml-like way to define simple types like, maybe-number ::= number | nil ?

20:30 amalloy: clop2: no, we don't have ADTs

20:30 Guest26510: ,(reduce -

20:30 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

20:31 Guest26510: err

20:31 dbasch: (locking 4 (println "http://www.imdb.com/title/tt1464540/&quot;))

20:31 johnnycage: ,(reduce - '())

20:31 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/->

20:31 johnnycage: can I supply a starting value for the accumulator?

20:31 amalloy: ,(doc reduce)

20:31 clojurebot: "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val i...

20:32 TEttinger: johnnycage, yes, ##(reduce + 10 [1 2 3])

20:32 lazybot: ⇒ 16

20:33 TEttinger: (inc amalloy)

20:33 lazybot: ⇒ 167

20:33 johnnycage: is that the same function? it uses optional argument, or?

20:33 overloaded function?

20:33 TEttinger: starting values for reduce are very very useful for reduce on strings

20:34 see in the docstring amalloy called up, ([f coll] [f val coll]) ?

20:34 johnnycage: yes

20:34 TEttinger: that means it can take [f coll] as two args, or [f val coll] as 3 args

20:34 val is the starting value

20:34 johnnycage: I realize this. I am just curious how is something like implemented

20:34 +that

20:34 dbasch: ,(reduce str "can " ["I " "supply " "a " "value?"])

20:34 clojurebot: "can I supply a value?"

20:35 TEttinger: ,(defn multi ([] "you gotta give me some args!") ([f coll]) (reduce f coll))

20:35 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Parameter declaration "reduce" should be a vector, compiling:(NO_SOURCE_FILE:0:0)>

20:35 TEttinger: ,(defn multi ([] "you gotta give me some args!") ([f coll] (reduce f coll)))

20:35 clojurebot: #'sandbox/multi

20:35 TEttinger: ,(multi)

20:35 clojurebot: "you gotta give me some args!"

20:36 TEttinger: ,(multi + [1 2 3])

20:36 clojurebot: 6

20:36 justin_smith: dbasch: why not apply str?

20:36 johnnycage: neat

20:37 dbasch: ,(apply str "they " ["were " "taking " "about " "reduce."]) ; justin_smith

20:37 clojurebot: "they were taking about reduce."

20:37 amalloy: yeah, i don't recommend ever using str as the function you're reducing

20:37 dbasch: talking that is

20:37 justin_smith: we have apply str, string/join, even reduce on StringBuilder if you have to go that way

20:37 amalloy: it should always be apply (or, better yet, something more suitable like clojure.string/join)

20:38 dbasch: yes, you don't want to be concatenating strings like crazy

20:38 TEttinger: johnnycage, that multiple argument list technique is used heavily by clojure's standard lib, but it hasn't come up too often for me in code I have written. still quite useful.

20:38 amalloy: justin_smith: not much point in reducing over a stringbuilder

20:38 might as well hammer on it in place with doseq

20:38 justin_smith: fair enough

20:42 and now that I check, yup, of course clojure.string/join is a loop with a StringBuilder in it

20:44 johnnycage: what is apply's relationship with reduce? can we just replace one with the other, always?

20:44 dbasch: johnnycage: no

20:44 johnnycage: tey seem to be interchangeable in many cases

20:44 they

20:44 justin_smith: johnnycage: well, many functions with varargs are implemented in terms of a two arg function + reduce, so apply invokes reduce internally

20:44 dbasch: johnnycage: apply simply converts a collection (or arguments plus a collection) into arguments

20:45 justin_smith: (in those cases, that is)

20:45 johnnycage: oh, apply just passes all the elements to the function

20:45 justin_smith: right

20:46 and if you look at the source to + for example, it uses the internal clojure.lang.Numbers.add which takes two args, and then uses reduce for the rest of the args

20:46 (reduce1 which is an optimized reduce in this case, but anyway...)

20:47 amalloy: i wonder: why is it called reduce1? it reminds me of foldl1 or something, which isn't right at all

20:49 justin_smith: odd, especially given that reduce* was not taken

20:50 and that would kind of make sense given things like fn* and let*

20:51 dbasch: amalloy: because it was June 11, so 1 was the digit of the day. https://github.com/clojure/clojure/commit/3f74c9ff6e9bf8e5e120129ea1c1c7e4719b4dcc

20:52 justin_smith: (inc dbasch)

20:52 lazybot: ⇒ 10

20:53 amalloy: hey, who was it who was telling me that it's easy to forgot where the return-type annotation goes? Bronsa? i just found evidence that rich forgets too: https://github.com/clojure/clojure/commit/e354b011 puts them in both places, like (defn ^Foo f ^Foo [x])

20:53 (the second Foo there is entirely ignored afaik)

20:53 justin_smith: yeah, I think dbasch was asking why the misplacement was not an error

20:54 it would logically indicate metadata on the params vactor, but how would you even access that...

20:54 dbasch: I think I disassembled both versions and saw no difference

20:54 amalloy: justin_smith: well, it's the correct place to put a primitive typehint

20:54 justin_smith: oh wow, OK

20:54 amalloy: but means nothing if you hint with an object type

20:55 (defn square ^long [^long x] (* x x)) avoids boxing

20:56 dbasch: the one I found had ^String

20:56 amalloy: right, those are wrong

21:03 johnnycage: is there a reduce equivalent that returns a list of all the intermediate results (the value of the accumulator) instead of just the final result?

21:03 justin_smith: reductions

21:03 amalloy: ,(doc reductiosn)

21:03 clojurebot: No entiendo

21:03 amalloy: boo

21:03 justin_smith: you misspelled it

21:03 amalloy: yeah

21:03 justin_smith: ,(doc reductions)

21:03 clojurebot: "([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."

21:04 johnnycage: nice thanks

21:04 amalloy: incidentally, has anyone ever used the first item in the value returned by reductions? i feel like i only ever call it as (rest (reductions ...))

21:06 well, never mind. i just searched all the code i have on the computer, and the one time i used it i didn't call rest

21:15 justin_smith: amalloy: one of mine was without using rest, the other only had reductions as a comment, and was an excersize blind-rewriting it from scratch

21:21 joobus: what's crackin' clojure clan?

21:25 justin_smith: workin on some 4clojure problems

21:25 amalloy: justin_smith: you are worse at spelling exercise than i am at spelling privelidge

21:26 justin_smith: hah

21:27 joobus: i'm working projecteuler problem 9 in clojure :)

21:28 justin_smith: are you writing them or doing them?

21:28 justin_smith: doing them, after I solve them all I will make some up

21:55 phao: Does Rich Hickey come in here?

21:55 xeqi: rarely

22:00 kenrestivo: bar

22:37 ~seen rhickey

22:37 clojurebot: Gabh mo leithscéal?

22:37 kenrestivo: ,seen rhickey

22:37 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: seen in this context, compiling:(NO_SOURCE_PATH:0:0)>

22:37 kenrestivo: lazybot: seen rhickey

22:37 lazybot: rhickey was last seen quitting 65 weeks and 1 day ago.

22:37 kenrestivo: phao: ^

22:46 kyun: How to use clojure file as script?

22:47 justin_smith: kyun: there is a lein plugin for it, or you can just reference the clojure jar and your script, but clojure tends to be awkward for scripting because the core takes a long time to load

22:47 brehaut: slowly

22:48 justin_smith: https://github.com/kumarshantanu/lein-exec lein-exec is probably easiest

22:49 kyun: Oh, I see, thanks.

22:51 I think it will faster to scala script:)

22:51 TEttinger: kyun, nope

22:51 jvm startup time is slow either way

22:52 there's stuff like drip that makes jvm startup time faster for clojure and maybe other languages

22:53 amalloy: TEttinger: most of the startup time is clojure's fault, not the jvm

22:54 building a bunch of vars, compiling your code, and so on

22:54 TEttinger: right, but scala's compiler is even slower if you just changed the script :)

22:57 kyun: Scala's type system is to too hard for me-_-

22:57 TEttinger: https://github.com/flatland/drip is drip, btw

22:58 kyun: http://tpolecat.github.io/assets/list.png

22:59 justin_smith: lol

23:00 kyun: Oh my god.

23:04 TEttinger: err, https://github.com/ninjudd/drip is newer

23:12 izirku: hi all! a noob question perhaps - when different libraries themselves depend on different versions of the same library, what are the implications?...

23:13 some even require different version of Clojure itself. Should one be concerned with it?

23:13 TEttinger: izirku, that is a common problem and a hard one to resolve

23:14 izirku: TEttinger: I'm aware somewhat of not using :aot :all, which supposed to help, but is there anything else? I tried to search the web with...

23:14 not much success on this. Coming from Common Lisp, this is something new to me.

23:14 TEttinger: which libs have different dependency versions?

23:15 it

23:16 it's possible you can fork one that needs an older version, update the version it depends on, upload your personal copy to clojars for now (submitting a pull request to the author for later), and depend on your clojars copy or a locally installed version until they are both up-to-date

23:17 izirku: TEttinger: for example lib-noir "0.8.9" depends on cheshire 5.3.1, which in turn depends on jackson-core 2.3.1 ...

23:17 TEttinger: that's probably a bad approach but I have done it

23:18 izirku: also lib-noir "0.8.9" depends on ring-middleware-format "0.4.0" and some more, which in the end depend on jackson-core "2.3.2"

23:18 xeqi: izirku: `lein deps :tree` should help you identify potential problems. Implications are the libraries erroring or half working at runtime

23:18 TEttinger: that's interesting, I wouldn't expect that lib-noir would have that problem

23:19 izirku: xeqi: that's exactly where I got the dependency information from

23:20 xeqi: I see the implications :(

23:21 TEttinger: hm, https://clojars.org/ring-middleware-format doesn't itself depend on jackson-core 2.3.2

23:21 izirku: TEttinger: I guess forking could work, but that's a lot of forks :)

23:23 TEttinger: no, not itself, but one of it's dependencies. here is a pastebin of my lein deps :tree http://paste.lisp.org/+32WW

23:25 xeqi: wow those extra parens are annoying. I thought I had fixed that

23:25 TEttinger: using the dep on ([lib-noir "0.8.9" :exclusions [com.fasterxml.jackson.core/jackson-core]]) should be good

23:25 xeqi: izirku: what lein version?

23:26 izirku: xeqi: Leiningen 2.4.2 on Java 1.8.0_11 Java HotSpot(TM) 64-Bit Server VM

23:26 xeqi: ah, that fix didn't come till later

23:30 izirku: xeqi: noted, updating now :)

23:30 mmitchel_: I'm having a problem using this library https://github.com/ring-clojure/ring-session-timeout --- it seems that a session logout, followed very quickly by another request (which updates the session value with a timeout) value, causes the session to continue living -- has anyone experienced this?

23:31 The underlying session storage is ring in-memory, which is using an atom

23:32 izirku: TEttinger: I did put the :exclude in, will work through the rest. Does the exclude basically tells a package to ignore dependency, ...

23:32 xeqi: mmitchel_: what is a "session logout" ?

23:32 izirku: TEttinger: and whatever else version is pulled will be used?

23:32 mmitchel_: I think the problem is that the delete happens in a swap!, and before it finishes, the timeout middleware gets access to the session data. Then the delete tries removes it, but then the timeout middleware finishes its work and re-populates the session data.

23:32 xeqi: a request handler that responds with a {:status 200 :session nil}

23:34 xeqi: izirku: correct

23:35 izirku: xeqi, TEttinger: thank you for your help, much appreciated!

23:39 xeqi: mmitchel_: are the requests overlapping?

23:41 mmitchel_: xeqi: yes they are

23:44 xeqi: mmitchel_: then I don't think it has to do with atoms/swap. More that both request get the session from the session store. Then whichever writes last "wins"

23:45 similar ideas, just at a level higher then the underlying session store

23:45 mmitchel_: xeqi: yeah, i'm not sure what to do here

23:49 xeqi: any suggestions?

23:50 xeqi: mmitchel_: what do you expect to happen to the side effecting parts of the second request?

23:50 * want to have happen

23:53 for example, overlapping "logout" and "delete project" requests

23:54 mmitchel_: xeqi: yeah, good question. I guess I'm hoping "delete" wins -- somewhow

23:55 but i guess that can only happen if the delete start, only happens when something else hasn't already got to it

23:56 so a blocking delete etc..

Logging service provided by n01se.net