#clojure log - Aug 27 2013

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

0:00 technomancy: wait, *that's* the letrec email?

0:00 hiredman: yes

0:00 so called because out of no where "we need letrec"

0:01 technomancy: clojurebot: letrec?

0:01 clojurebot: Pardon?

0:01 technomancy: clojurebot: letrec is <reply>"we need letrec" - Joe Armstrong (http://erlang.org/pipermail/erlang-questions/2011-May/058768.html)

0:01 clojurebot: Roger.

0:01 seangrov`: dnolen: Ok, think I got it... https://github.com/sgrove/clojurescript/commit/6eb9abbd685dbf0a6e0f6f048ac3bd5c840da97a

0:02 bbloom: I like your idea about splitting patches up, I'll try to towards that

0:03 bbloom: seangrov`: i view a good pull request as having having one or more clear, clean incremental steps, that tell a story about how a change impacts the program. thinking about that locally is helpful to my development process too. I often rebase patches as i work to make them small & clean & clear, so I understand what I've actually accomplished & how

0:05 seangrov`: Just did my first interactive rebase ever... always more to learn, it seems

0:05 It'll probably be like emacs though, very much worth it once I've figure it out

0:06 dnolen: tbaldridge: doesn't seem any slower, maybe even a bit faster?

0:11 tbaldridge: dnolen: well that's good to hear. I don't think it's possible that it's faster, but I'm glad it's not slower

0:12 dnolen: tbaldridge: definitely not slower at any of the benchmarks I was using before.

0:12 seangrov`: this looks good, let's get a patch on the ticket and I will give it a try locally

0:13 tbaldridge: dnolen: btw, on your "make no promises" post, sometimes the hit just goes bonkers and I get 100k msgs in ~50ms

0:13 *the jit

0:14 dnolen: tbaldridge: I suspect this is related some how to GC. Clicking on their of the two makes performance degrade after the first few runs.

0:14 s/their/either

0:14 tbaldridge: dnolen: interesting

0:15 dnolen: tbaldridge: but yeah I've seen ~50ms runtimes for core.async

0:16 seangrov`: dnolen: Sounds good, running the tests one last time to make sure I didn't break anything with the rebase, then I'll submit the patch and head home

0:18 Attach it to this? http://dev.clojure.org/jira/browse/CLJS-497

0:18 dnolen: tbaldridge: we should probably look a bit more closely at GC behavior as you've suggested.

0:19 tbaldridge: dnolen: any good suggestions for GC profilers for JS? Chrome Tools seemed a bit limited

0:20 dnolen: seangrov`: hrm, no let's make a new ticket, but please ref it from CLJS-497

0:21 seangrov`: also ref 381

0:22 tbaldridge: you might want to try Chrome Canary, they have some extra tools I think.

0:26 seangrov`: dnolen: Alright, I think this is good to go: http://dev.clojure.org/jira/browse/CLJS-576

0:26 dnolen: tbaldridge: yeah you can heap snapshots in Canary

0:26 seangrov`: Time to head out now

0:26 dnolen: seangrov`: excellent, many many thanks!

0:39 tbaldridge: yeah it does appear that core.async things are lingering around ... more investigation needed

0:40 tbaldridge: dnolen: agreed, and I can't get chrome to parse the snapshot without dieing

0:40 dnolen: tbaldridge: yeah pick a smaller N :) I'm testing w/ size 1000 on my blog.

0:41 tbaldridge: dnolen: although, come to think of it, we're probably running into GC on the channels in your blog post

0:44 dnolen: tbaldridge: it looks like the main issue is the tasks array in dispatch ns

0:45 tbaldridge: many things are getting retained because of that

0:45 tbaldridge: ah yeah, I didn't do the thing that cleans out the ring buffers.

0:45 one sec

0:47 dnolen: tbaldridge: aha! :)

0:47 tbaldridge: I was wondering length was zero :) but I forgot that it was a ring buffer not an array.

0:47 tbaldridge: dnolen: yeah, that commit should do it: https://github.com/clojure/core.async/commit/99e9155958491e632397f9b3dbdede84a419bee3

0:56 dnolen: so I'm still seeing a lot of GC work after that commit, but I just realized it's only on the first invocation of the tests. The task queue has to resize as it runs out of room, at some point it will be large enough and we won't resize it again.

0:59 dnolen: tbaldridge: that makes sense, I was more concerned about stuff lingering around

1:07 tbaldridge: ok I'm no longer seeing the retains through tasks here

1:07 tbaldridge: nice

1:26 * futile peeks around

1:31 callen: futile: hi!

1:31 futile: callen: hi

1:41 callen: you sounded excited

1:43 callen: is there something exciting?

1:43 callen: futile: I'm working on something pretty

1:43 futile: oh? can i see?

1:44 callen: if there's one thing I always thought Rubyists got right, it was putting spit-shine on something before shipping it. I'm making something that riffs off a detail of Rails.

1:44 Not yet. I can ping you when I ship it.

1:44 futile: ok

1:44 callen: I'm also working on something pretty right now.

1:45 callen: oh?

1:46 Here's an anti-pattern, I end up making fake projects to test/mock libraries I'm working on far too often.

1:46 I'm waiting for the day to come when I've made so many fake test projects that I don't have to make any new ones anymore.

1:46 futile: yeah, this: https://www.dropbox.com/s/msyq0nwfzhvbhjq/Screen%20Shot%202013-08-27%20at%2012.24.05%20AM.png

1:47 (because I'm not happy with iTunes lately)

1:47 callen: I don't use music stored on local drive anymore, for the most part.

1:47 it's all CD-ROMS and streaming music for me now.

1:47 futile: nobody does but me

1:47 callen: partly out of a desire to not pirate music.

1:47 futile: everyone uses spotify or pandora

1:48 so i suppose ill be the only user of this app.

1:48 callen: don't focus on having users, just on scratching an itch.

1:48 futile: but it's gonna be a damn good app even still.

1:48 callen: getting other people to use your thing is about ego, not utility.

1:48 futile: actually scratch that. it already is. im officially announcing 1.0

1:49 callen: btw are you talking about when you're actually working on the lib itself, you have to add tests to it?

1:49 callen: otherwise no comprendo

1:51 callen: I don't consider writing tests to be sufficient

1:51 I do functional/integration testing with mock projects in addition to unit tests.

1:52 I'm a bit fascist about automation and testing.

1:52 anyway, I'm griping about having to write mock projects.

1:52 futile: callen: hmm. I can kind of relate, since I've given up on large-scale unit testing and focus much more on integration testing at the highest scale.

1:53 callen: yeah that's partly why I do it.

1:53 futile: callen: but I've never had a project that required me to write mock projects. I guess depends on the project.

1:53 callen: I really just want to exercise the whole thing in expected patterns

1:53 not nit-pick at specific bits.

1:53 futile: Leiningen probably would need mock projects

1:53 Right. No need going at implementation details.

1:54 At work we have an entire test suite that's largely useless at testing reliability of anything, and makes it really hard to change anything, because it entirely tests implementation.

1:54 I think working on Zephyros taught me a lot about where abstraction lines should be, which would be useful for testing (except Zephyros has no tests).

1:55 callen: I think unit tests can be valuable, but they have to be written well and specify expectations that are meaningful.

1:57 futile: (expect = 2 (+ 1 1))

1:57 i see that a lot

1:57 well not really.

1:58 callen: what kind of project is this?

1:59 callen: just a logging thing.

1:59 futile: oh like lazybot?

2:00 callen: not at all, but there's a related project there on my to-do list.

2:01 futile: cool

2:01 i think my next project is a project management tool :)

2:01 ive written a window manager and a music player. language and text editor are too ambitions. project management tool is just the right size.

2:01 *ambitious

2:02 callen: what in the mother fuck?

2:02 either I bumped into a Leiningen bug, or after years of usage I've forgotten how to write a :dependencies vector.

2:02 ddellacosta: callen: ?

2:02 futile: most likely the latter

2:03 hi ddellacosta

2:03 ddellacosta: futile: howdy there.

2:03 callen: I nuked my ~/.m2, I'll report the error if this doesn't fix it.

2:03 ddellacosta: how goes it?

2:03 callen: and upgraded lein.

2:04 futile: ddellacosta: swell, thee?

2:04 ddellacosta: callen: yeah, if you're still having trouble after that post a refheap or something

2:04 futile: not too bad, not too bad. Think I'm finally over jetlag, which makes me happy.

2:04 callen: I'm staring at the clojars page for my dependency, I know I'm not totally crazy.

2:04 adlfknggrshklmryltmkfg

2:04 futile: ddellacosta: woohoo. i hope the cause of the jetlag was worthwhile?

2:04 callen: could it be that you're tired and need a break?

2:05 ddellacosta: futile: well, you know, gotta visit the motherland once in a while, I suppose. ;-)

2:05 futile: callen: sometimes i find that something doesnt make sense until doing something else for 30 mins (or 10 days, depending on the thing).

2:05 ddellacosta: where's that?

2:05 callen: who's up for fixing my stupid? https://www.refheap.com/18052

2:05 ddellacosta: futile: motherland = U.S. I live in Japan.

2:06 callen: looking now

2:06 futile: oh cool

2:06 callen: https://github.com/kevinjqiu/lumiere/blob/master/src/lumiere/lumiere.clj

2:06 ^^ it's right bloody there.

2:06 Retrieving lumiere/lumiere/1.0.0-SNAPSHOT/lumiere-1.0.0-20120301.024351-1.jar from clojars

2:06 I saw it download!

2:06 futile: hmm

2:07 callen: here I'll look inside the jar.

2:07 ddellacosta: callen: ah, hurm

2:07 callen: there's a lumiere.clj inside the lumiere 1.0.0-SNAPSHOT jar.

2:07 ...but the ns is lumiere, not lumiere.lumiere

2:07 ddellacosta: the frack

2:07 futile: my dumb guess is it's a double-word problem

2:07 callen: I might kill this man for writing a misleading README.

2:07 futile: lumiere vs lumiere/lumiere

2:07 ive seen that a lot

2:08 callen: not slash. dot.

2:08 futile: oh, looks like you figured it out already.

2:08 callen: that worked.

2:08 futile: i was talking about dirs

2:08 ddellacosta: what worked?

2:08 callen: I am going to send a PR stuffed with the fury of a thousand african hornets.

2:08 ddellacosta: I ripped open the jar and checked the NS

2:08 NS decl didn't match documentation, dude's careless.

2:08 brb, sending nastygram via github

2:08 ddellacosta: oh

2:08 haha

2:08 * ddellacosta makes popcorn

2:08 futile: callen: you catch more flies with honey than with vinegar

2:09 ddellacosta: futile is right, I shouldn't be encouraging this behavior

2:09 callen: futile: I describe my actions in hostile/violent terms for your amusement, I know how to get what I want - being nice.

2:09 futile: callen: try being extra nice about it, even though that seems backwards right now. tomorrow you'll be glad for it

2:09 callen: I'm very patient and pleasant on github. I only came close to slipping once, and that was with the homebrew people.

2:09 futile: callen: oh. well thats misleading.

2:09 callen: But they're territorial cunts.

2:09 fuck them.

2:09 took 15 days of volleyball to get a simple community-approved change implemented.

2:10 futile: ddellacosta: also i wrote a clojure port for https://github.com/sdegutis/zephyros

2:10 ddellacosta: callen: I recall something about installing clojure via home-brew, you and Raynes were onto something weren't you?

2:10 futile: *client

2:10 callen: ddellacosta: shit's gone yo. We nuked it.

2:10 they finally merged the PR.

2:10 futile: the fact that this project has > 500 stars makes me feel like maybe im not incompetent.

2:10 callen: if your homebrew is up to date and you try to install Clojure with it, it'll smack you in the face and tell you to use Leiningen.

2:10 ddellacosta: callen: gotcha, that's good

2:10 callen: futile: that's pretty impressive. you were clearly touching on something people care about :)

2:10 ddellacosta: futile: that's pretty cool

2:11 callen: ddellacosta: doing god's work and all that. Raynes and I were both tired of the derps rolling in with problems specific to not using Leiningen.

2:11 ddellacosta: I'll give it a shot one of these days, when I'm not being so lazy

2:11 futile: callen: window management in mac os x just isnt as good as it is in linux

2:11 ddellacosta: callen: good stuff, definitely. Should actually help folks in a concrete way

2:11 callen: https://github.com/kevinjqiu/lumiere/pull/2

2:11 patchwork: If I have a separate thread running, how do I route *stdin* to it?

2:11 callen: futile: I know that. I'm an XMonad user.

2:12 ddellacosta: futile: I gotta admit, I'm not nearly as motivated by it as I used to be (but to echo callen, the 500+ stars on the project shows a lot of folks are)

2:12 futile: (inc callen)

2:12 lazybot: ⇒ 8

2:12 callen: futile: I still use Macs though. dat hardware.

2:12 patchwork: It does not seem to be accepting my input

2:12 callen: patchwork: any thread should have the option of reading from System.in

2:12 ddellacosta: callen: nice.

2:13 futile: ddellacosta: i started getting optimistic about using it when i stopped looking at it as a full-fledged "take control of everything and ill do things your way" type of app, but more of an augmentation to my normal workflow with slight, modular additions

2:13 when i took that approach, it wasnt that scary.

2:13 callen: I hack on a Thinkpad running Linux and use a Mac at work and sometimes at home.

2:13 futile: or overwhelming/tedious/etc

2:13 seangrov`: ddellacosta: You going to make it out California way this time around?

2:13 ddellacosta: futile: that sounds like the right way to do it to me

2:13 callen: futile: can't make everything on a Mac work inside of that model anyway.

2:13 futile: callen: i tried so hard to get arch linux running smoothly on my mbp

2:13 ddellacosta: seangrov`: I already got back to Nippon man…sorry! ;-(

2:13 callen: ddellacosta: yeah you need to stop by California. I need to get you a few rounds. :)

2:14 seangrov`: Ah, well, no worries

2:14 futile: callen: but it was so hard to get Just Right™

2:14 callen: futile: s'not worth it.

2:14 yep.

2:14 futile: especially a retina

2:14 *my

2:14 ddellacosta: seangrov`: but, this was a total east coast thing, my wife's family came and met mine for the first time.

2:14 seangrov`: You have some clojure friends in the bay when you come back next time ;)

2:14 Very nice, that's a fun experience

2:14 patchwork: callen: Hmm… how do I trigger that? This is the first time I've messed with (Thread. #(..)) in clojure

2:14 probably I am doing this wrong

2:14 ddellacosta: seangrov`: Excellent, very excited by that. Cali is next up, in the next 6 months I'm hoping.

2:14 callen: now to write deep, deep evil with alter-var-root

2:14 * callen cackles

2:15 callen: patchwork: you shouldn't be using raw threads geenrally.

2:15 futile: oh, like hyperion

2:15 callen: generally*

2:15 patchwork: callen: I suspected as much

2:15 * futile is going to switch to Datomic at work

2:15 callen: futile: I'm testing a Clojure + Datomic project at work. Pretty excited. It'll be the first thing running Clojure at my company.

2:15 futile: finally got the boss's approval for "a spike" to see if its better/faster/etc

2:15 callen: woo

2:16 patchwork: callen: I have a thing in a (loop [..] …) I want to run in the background… but have it accept stdin and write to stdout. What is the right way to do that in clojure?

2:16 * ddellacosta is jealous of all the folks using Datomic at work

2:16 callen: there's no "approval" process. We're like an organized form of anarchy at my company so each person is given full control over their scope of influence.

2:16 futile: callen: what company?

2:16 callen: given that, all it took was selling the project owner on Clojure + Datomic, and he was already sold on Datomic (he's a hacker, not PM type)

2:17 futile: genetics company

2:17 futile: i applied at relevance and was politely rejected

2:17 callen: sounds scary

2:17 callen: i'd envy that level of control, if it were possible

2:17 patchwork: callen: genetics… bioinformatics? sequencing? bioengineering?

2:18 I am way into cell biology

2:18 make a bunch of models of chemotaxis etc

2:18 callen: patchwork: we do sequencing and bioinformatics. It's genetic sequencing applied to specific medicine.

2:18 futile: btw objc's ARC is really cool and i bet Java/Clojure could benefit from something like it

2:18 callen: I'm not a bioinformaticist. I'm a software generalist and product guy that is obsessed with databases and backend.

2:19 truth be told, I'm a failed-startup refugee (CTO) that found a nice company populated with cool people :)

2:19 patchwork: callen: pretty cool domain nonetheless

2:19 arubin: callen: Not related to the ThoughtWorks project using Clojure for cancer drug matching, is it?

2:19 patchwork: though in a way backend is backend I suppose

2:19 callen: futile: I'm actually a huge fan of ref-counting GC and scoped pointers.

2:20 patchwork: you'd be surprised how little I need to know about the bio parts to be useful.

2:20 futile: callen: you know that ARC is compile-time "GC" right?

2:20 patchwork: Yeah, data is data

2:20 callen: arubin: no, we're all internal. Datomic + Clojure was an internal decision. They were already curious about Datomic, I used that as leverage to get them to try out Clojure. They've been plagued with problems related to Python so it seemed a good alternative to try out.

2:20 futile: obj-c's implementation is. ref-counting is generally runtime.

2:21 Rust's implementation is compile-time for the various pointer types.

2:21 patchwork: Aha! well if they are using python then you have a lot of improvement to provide

2:21 callen: but anything that escapes to GC is runtime.

2:21 patchwork: it's a bio company - Python ghetto extraordinaire.

2:21 futile: callen: well objc had ref-counting before ARC, and it was pretty terrible. but ARC made it basically act like free GC at compile-time only

2:21 patchwork: I increased our system by an order of magnitude by switching to clojure from python

2:21 not to mention concurrency

2:21 callen: patchwork: increased...performance? not sure what you mean here.

2:21 patchwork: callen: Right : ) performance

2:22 callen: futile: a lot of obj-c is weird though, don't use it as a reference for how things like ref-counting behave in general.

2:22 futile: callen: oh

2:22 patchwork: Increased its general awesomeness as well

2:22 decreased the codebase

2:22 callen: patchwork: our scaling problems don't yet center around software, it's more around complexity management and production.

2:22 futile: callen: isn't objc's refcounting model simple and good?

2:23 patchwork: callen: I bet. Lot's of data shunting back and forth I imagine

2:23 futile: besides the manual-labor aspect of it

2:23 patchwork: Our system was dog slow

2:23 (well, once it got to a certain size of use)

2:24 futile: patchwork: wait, so you went from clojure to python, and that decreased the size and improved performance?

2:24 patchwork: that sounds backwards.

2:24 patchwork: futile: other way

2:24 futile: oh nice

2:24 patchwork: python—> clojure

2:24 futile: yay

2:24 callen: patchwork: so much fucking data comes out of those sequencers. it's ridiculous.

2:24 patchwork: Yeah, remarkable improvement actually

2:24 futile: im pretty sold on clojure being the new ruby/python

2:25 callen: patchwork: part of it is a social thing, I'd really like to get the Gospel of Immutability into the heads of everybody writing code at my company.

2:25 patchwork: futile: The only deal is it's not good for scripts!

2:25 callen: it's a little hard to make those lessons stick in a language like Python.

2:25 it's easier in languages like Java where you can make the whole class immutable and enforce it.

2:25 patchwork: callen: People have to burn themselves with concurrency to really understand why it matters

2:25 Then it is like a godsend

2:26 futile: patchwork: that doesnt feel true for me

2:26 patchwork: i love clojure's immutability only because its so much easier to reason about and write composable functions than it was in mutable-land (ruby/python)

2:27 patchwork: futile: I feel that is more just functional programming… but I guess clojure enforces that by being immutable

2:27 You CAN'T modify your map inside the function, so you figure out a different way to do it!

2:27 futile: well ignoring functional programming, the fact that everything i receive and pass around is immutable, that makes it so much easier to know what the code im writing is going to do

2:28 i guess its called referential transparency

2:28 its scary that rich was on the fence about immutability for a long time before he settled on it

2:28 patchwork: futile: That is functional programming. Always returning the same thing when given the same args and not changing any args that are passed in

2:28 futile: imagine mutable clojure!

2:28 patchwork: FP has too many definitions

2:28 patchwork: futile: Well there are atoms and refs : )

2:28 futile: Ah. That is my definition

2:29 callen: Are you sure he was on the fence? And Rich did a lot to make mutability easy/safe/efficient.

2:29 patchwork: The mathy one

2:29 futile: callen: i read him say so in something recently

2:29 some old interview or something

2:29 patchwork: Yeah if anything clojure provides sane ways to mutate stuff, rather than it just being the default implicit operation

2:29 You have to WANT to mutate something, and be explicit about it

2:30 futile: i know a guy who knows a guy

2:31 patchwork: These guys, always saying stuff

2:32 futile: patchwork: you dont by any chance listen to music via local files do you?

2:32 patchwork: futile: I listen to all kinds

2:32 futile: patchwork: most people listen to spotify or pandora, i figured i was the only one who listens to music files on my actual harddrive

2:33 (née sdd)

2:33 er, (i mean sdd)

2:33 patchwork: you on a mac?

2:33 patchwork: futile: yep

2:33 futile: PM me if you wanna try this app: https://www.dropbox.com/s/msyq0nwfzhvbhjq/Screen%20Shot%202013-08-27%20at%2012.24.05%20AM.png

2:33 and if you dont, i wont take offense.

2:34 patchwork: Is it yours?

2:34 futile: yep

2:34 been writing it in secret a couple weeks now

2:34 im too unhappy with itunes lately.

2:34 patchwork: one of the best things to listen to on the internet: http://www.park.nl/park_cms/public/index.php?thisarticle=118

2:34 I listened to it for 3 months straight one time

2:34 futile: whoa

2:34 callen: is there a variation on (time (...)) that returns the msecs as a number?

2:34 instead of kicking it to the output.

2:35 I'm trying to avoid writing a manual dilly.

2:35 futile: dilly, is that what they're called then?

2:35 callen: oh, with-out-str.

2:36 futile: but then you have to parse it, no?

2:36 well if the goal is to avoid stdout then that works

2:36 callen: yes, and it dumps the result, which is unacceptable.

2:36 Manual it is.

2:40 futile: welp, as soon as the new app icon comes in the email, ill call the app 1.0 and move on in life :)

2:40 (for 5 minutes until i discover a bug and release an emergency 1.0.1)

2:41 patchwork: futile: You have it up somewhere? on github?

2:42 futile: yep patchwork. one sec

2:42 patchwork: Okay, what is the best way to put an infinite (loop […] …) in its own thread and have it accept stdin and stdout?

2:42 in clojure?

2:43 I should know this, somehow it hasn't come up before

2:45 callen: welp. I've misunderstood c.j.j again. time to go plundering.

2:49 futile: patchwork: https://github.com/sdegutis/bahamut

2:49 oops hold on, link broken

2:49 fixed.

2:53 patchwork: ive used a (future) containing (while true...)

2:54 patchwork: in the clojure client for zephyros, granted it was reading from a tcp socket not stdin, but it should work still

2:54 ambroseb_: can I find the default dispatch value for some multimethod programatically?

2:56 futile: ambroseb_: you mean get it as a callable fn?

2:56 ambroseb_: I want (multimethod-default mm-var) => :default

2:57 futile: oh. i dunno.

2:57 ambroseb_: probably need to call the MultiFn directly.

2:58 well defaultDispatchVal on MultiFn is public, which is promising.

3:03 callen: http://i.imgur.com/gLV7nmt.png

3:03 how's that look for a SQL query logging library output?

3:04 futile: ^^

3:04 ddellacosta: ^^

3:04 futile: callen: fancy

3:04 callen: it's real too. that's actually hooking into c.j.j :)

3:04 alter-var-root ftwwwwww

3:04 futile: whoa

3:04 TEttinger: how big is the DB?

3:05 ddellacosta: callen: sorry, what are you asking me to evaluate? The 100 ms? Pretty snappy

3:05 callen: TEttinger: don't bike-shed my sqlite database or I will plonk you with a smelly fish.

3:05 futile: callen: does your hack depend on implementation details? :P

3:05 callen: ddellacosta: ...no! I'm writing a SQL query logging library.

3:05 ddellacosta: callen: oh, haha, sorry. Looks nice. :-)

3:05 TEttinger: callen, it is purdy

3:06 futile: callen: so, you just plug in your lib, and this gets output automatically to stdout?

3:06 callen: futile: (decorate!) -> boom magic.

3:06 futile: nice

3:06 callen: yeah baby. >:D

3:06 ddellacosta: callen: you gotta give me a pass, I was deep within test mock building meditation mode

3:06 callen: I'm all about the evil hacks.

3:06 ddellacosta: oh, sorry for disrupting :(

3:06 ddellacosta: callen: no, not at all! If I didn't want to look, I wouldn't. ;-)

3:07 in fact, I'm having trouble figuring out why some namespace changes aren't getting picked up…

3:07 * ddellacosta sighs

3:09 callen: hrm. I really do not like trawling c.j.j

3:09 futile: woot, 0.9 is official.

3:09 can a project ever officially be "done"?

3:09 callen: futile: yeah. happens all the time to Clojure libs.

3:09 futile: im tired of getting new feature requests. id like my other project to just be done, and everyone be happy with that.

3:10 callen: ah that makes sense then, libs vs apps

3:10 apps cant ever just be done, but libs usually are.

3:10 ddellacosta: callen: yeah, c.j.j has some…messy bits, methinks

3:10 futile: ddellacosta: why are you in japan?

3:10 that seems kind afar

3:10 *kinda far

3:11 ddellacosta: futile: long story, but short version is: wanted to experience living in another country and liked Japan. Then went off the deep end and married a Japanese woman. Not that I'm complaining. :-)

3:11 futile: heh

3:11 callen: ddellacosta: it also has a million and one entrypoints for queries.

3:12 that all get dispatched independently to the JDBC layer

3:12 so I've gotta override, decorate, time, and log multiple vars

3:12 all with different argument patterns and destructuring

3:12 futile: scary

3:12 callen: does your lib work with datomic?

3:12 ;)

3:12 callen: I'm going to end the night writing murder on the walls in blood.

3:12 ddellacosta: callen: you mean, all the different ways you can insert and update and whatnot? yeah, I've taken to using it my own special way, using my own special conventions. But I can imagine trying to intercept stuff could be messy.

3:12 callen: futile: it could, but there's probably not much point.

3:13 futile: callen: why are you going to write a group of crows on the walls?

3:13 callen: ddellacosta: the problem is the interception, yeah.

3:13 ddellacosta: there's no universal query executor fn as far as I can tell.

3:13 or if there is, the bastard is *buried*

3:14 ddellacosta: callen: based on my periodic cursory delvings into that codebase, that is my understanding as well.

3:14 * futile throws out http://en.wikipedia.org/wiki/A_Murder_of_Crows just to not sound weird

3:14 Raynes: callen: Goodness, callen. God's work? :p

3:14 callen: Raynes: why not?

3:15 Raynes: Too bad we couldn't stop the clojurescript formula.

3:15 ddellacosta: futile: dork. ;-)

3:15 callen: Raynes: speaking of god's work: http://i.imgur.com/gLV7nmt.png

3:15 ddellacosta: Raynes: they have a CLJS formula too!? wtf

3:15 callen: Raynes: pretty query logging lib :)

3:15 Raynes: Why the homebrew folks want to shit on our lawn immediately after picking up the turds they left behind before.

3:15 Eludes me.

3:15 callen: ddellacosta: dude. we fought that battle and lost it so we could win the war.

3:15 Raynes: David Nolen and Chas Emerick both contributed "wat no"s to that discussion and they still did it.

3:15 :(

3:16 ddellacosta: lame

3:16 but, not totally surprising

3:16 but lame

3:16 callen: two weeks of battling those bastards. *shakes head*

3:17 Raynes: is pretty, da?

3:17 Raynes: Yes, I am pretty.

3:17 * ddellacosta consoles callen and Raynes

3:17 futile: homebrew ftw

3:17 callen: Raynes: no mah lib :(

3:17 patchwork: futile: Looks like a labor of love

3:18 futile: patchwork: oh?

3:18 patchwork: i take it you tried it then

3:18 patchwork: also, is that the polite way of saying "this is not my style but obviously you like it"? :P

3:19 callen: omg this library is organized like a graph theoretic pathological case of connected nodes

3:19 WTF IS GOING ON

3:19 futile: hhaha

3:19 patchwork: futile: No, I recognize when a project is made because you want it specifically that way

3:21 ddellacosta: wtf, I can see vars in my namespace, and I have two tests defined w/deftest, but clojure.test keeps tell me "Ran 0 tests containing 0 assertions"

3:21 callen: look at this: https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L709-L735

3:21 just look at it.

3:22 why are update and insert using totally different functions?

3:22 there's no rhyme or reason to this, this is like a nihilist's trap for snaring programmers.

3:22 ddellacosta: callen: well, update seems nice enough to me

3:22 callen: ddellacosta: and if everything used execute! like update! does, we wouldn't have a problem :|

3:22 futile: patchwork: yeah im just tired of the Mac's "look and feel" changing every hour.

3:22 plus i dont even like the way it looks or feels

3:23 (if thats what you mean)

3:23 ddellacosta: callen: yeah, it's funny, 'cause my own personal convention w/c.j.j is to use c.j.j.s helpers with everything, and either query or execute! to actually run stuff

3:23 helpers = dsl

3:24 callen: ddellacosta: that's a really good idea, but I can't expect all my users to be that wise wrt design.

3:24 ddellacosta: callen: yeah. :-(

3:25 callen: I basically need every single test case in c.j.j to generate a pretty-pretty log line

3:25 I left my booze at work. I've made a huge mistake.

3:25 oh yeesh, it's midnight already. I'll wrap this up tomorrow.

3:25 futile: midnight?

3:25 2pm here

3:25 callen: I am not defeated...merely resting.

3:25 futile: callen: Ha

3:25 famous last words

3:25 * callen grumbles

3:26 futile: callen: do what ive done: stay up finishing it until 9am

3:26 and then take a 30 min nap

3:26 * futile is not quite sane though

3:26 callen: futile: I work for a living and I'm officially moving out of my apartment in the morning.

3:26 so...no.

3:26 futile: oh, where to?

3:26 callen: MV -> SF

3:26 like all young men my age end up doing.

3:27 futile: sigh

3:27 SF is gonna get overpopulated one of these days

3:28 callen: it already is. the rent is horrendous.

3:28 ddellacosta: seriously, why is clojure.test/run-tests not picking up my tests, but they are obviously loaded into my repl, and I can run them individually? I have never seen this ever

3:28 callen: like 3500 for a single bedroom apartment in SOMA

3:28 ddellacosta: typical lein repl?

3:28 ddellacosta: callen: yah

3:29 I feel like I'm going nuts

3:29 callen: ddellacosta: have you done a (use 'ns :reload-all) ?

3:29 ddellacosta: I mean, I went so far as to restart my repl

3:29 callen: (use '[clojure.tools.namespace.repl :only (refresh)])

3:29 oh shit.

3:29 you restarted your repl and it didn't pick up the tests?

3:29 ddellacosta: callen: I was using c.t.n.r, but my project is not clean enough, and it was barfing from weird java memory errors

3:29 futile: ddellacosta: accidental test selectors?

3:29 oh

3:30 ddellacosta: callen: no, it didn't. really freaking weird, right?

3:30 futile: what do you mean?

3:30 callen: ...yeah.

3:30 futile: dunno

3:30 callen: anyway, I need to go to bed. bye all :)

3:30 futile: bye

3:30 ddellacosta: callen: sleep well! good luck with the move. ;-)

3:30 futile: ddellacosta: its probably accidental test selectors

3:30 ddellacosta: futile: sorry, what does "test selector" mean?

3:30 futile: ddellacosta: dunno

3:30 ddellacosta: er, i mean, its a leiningen feature

3:30 ddellacosta: what

3:31 futile: ddellacosta: it filters out your tests or somethign

3:31 ddellacosta: ah, hrm

3:31 futile: sounds like it could be related.

3:31 check your project.clj for them

3:31 maybe someone else put it there and you didnt know the feature existed so it silently did its job too well

3:31 maybe.

3:32 ddellacosta: futile: well, I'll check into it, but it seems very strange

3:32 futile: k

3:32 ddellacosta: futile: and I think it's more likely I did something stupid, haha

3:32 futile: right.

3:32 select isnt broken.

3:33 http://pragmatictips.com/26

3:33 ddellacosta: never saw that, cool

3:33 yeah, exactly, that.

3:37 futile: what's a good freenode channel for asking advice on web ui libs?

3:38 Raynes: Javascript specific?

3:38 futile: I suppose everything compiles down to or uses JS.

3:38 But yeah, I mean dynamic widgets.

3:38 maybe jquery, maybe cappuccino.. dunno yet

3:39 Raynes: You could possibly ask in a Javascript channel, but stackoverflow might be a better choice.

3:39 futile: hmm, cant do SO

3:39 thanks

3:40 amalloy: can't ask on SO? whyever not?

3:40 Raynes: I imagine because his question doesn't have a clear answer.

3:40 SO will bite your head off if there is more than one definitive answer for a question.

3:41 futile: amalloy: never mind

3:43 ddellacosta: ahhaha I am so stupid, I wrote a fixture that never ran the function that was getting passed into it

3:43 that's why. d'oh

3:43 futile: :)

3:43 howd you solve it ddellacosta? binary search?

3:43 ddellacosta: times like these I wish I was pairing. ;-/

3:44 good 'ole comment out and then uncomment until it breaks

3:44 I suppose that is a form of binary search

3:44 futile: im not good at pairing. its always slower for me, not faster.

3:44 ddellacosta: futile: I find it is really person-specific for me. I've had horrible pairing experiences and excellent pairing experiences.

3:45 futile: ddellacosta: hmm

3:45 ddellacosta: it's not easy though. TDD comes naturally to me, pairing does not. If we're comparing agile/extreme programming practices.

3:46 but pairing is definitely excellent for this kind of situation: I just burned half an hour futzing about when someone else probably would have spotted it right away.

3:46 futile: ddellacosta: ive found that most of the time ive paired, my pair gets way too focused on unimportant details, which slows us down.. and we never get around to discussing the high-level important details because he/she usually thinks too implementation-specific

3:47 ddellacosta: futile: if that is happening consistently, then you need to be pro-active about making it a point of discussion yourself. The thing about pairing is that each pair has to take complete responsibility for any issues that arise, or else it doesn't work.

3:47 futile: which is why it's so hard--pairing is really a psychological challenge for many of us.

3:48 I know it has been for me at times!

3:48 futile: yeah

3:49 welp, time to go back to the building with broken windows and pretend like im making things better instead of worse

3:49 ddellacosta: futile: good luck. ;-)

3:51 futile: this is a good read http://www.codinghorror.com/blog/2005/06/the-broken-window-theory.html

4:18 patchwork: How do I pass an arg to a lein task? So: lein trampoline cljsbuild repl-listen :repl-listen-port 44444

4:18 That doesn't work

4:18 even though that is an option to the repl-listen task

4:18 (according to the code)

4:52 AWizzArd: Hello RegExperts. I have (re-seq #"\W(aa|bb|cc|xx|yy|zz)" " aa or bb/cc"), and this matches all the words I want to find, aa, bb and cc. However, I want to make sure that those words are not part of another word (i.e. substrings).

4:53 So, to protect it from finding ccc as a word I add ($|\W) at the end: (re-seq #"\W(aa|bb|cc|xx|yy|zz)($|\W)" " aa or bb/cc")

4:54 Unfortunately now cc does not get detected anymore, because of the \W. There is no non-alphanumeric char after cc.

4:54 The regexp engine seems to not try the $ instead, which follows the cc. Any ideas how I could make it match the cc at the end, without matching cc when it is a substring?

4:55 mpenet: ,(re-seq #"\baa\b|\bcc\b" "aaasdf aa bb asdf sdfbbb cc ccsdf")

4:55 clojurebot: ("aa" "cc")

4:57 mpenet: hmm doesn't work with the / example of yours, depending on if you want to include or exclude it, not sure

5:00 AWizzArd: The example is indeed the correct input. In my example above I want to detect words such as aa, bb, cc and so on, but only if on their left/right side is no alphanumeric char. The beginning and end of string are also fine.

5:02 amalloy: AWizzArd: don't use \W for this

5:02 the ($|\W) at the end of bb is consuming the / character, and so there's no \W for cc to start with

5:02 what you want is \b, a zero-width assertion

5:04 AWizzArd: I will try that.

5:08 mpenet and amalloy: good idea, the \b is working nicely.

5:10 mpenet: any core.async developer present atm?

5:16 ddellacosta: mpenet: what do want to ask?

5:17 how do I apply and to a collection of boolean values?

5:18 ah, google to the rescue

5:18 http://stackoverflow.com/questions/2891707/reduce-or-apply-using-logical-functions-in-clojure

5:18 Apage43: ddellacosta: Use every?.

5:19 mpenet: ddellacosta: about the current restrictions with the use of nil on channels: if there is an obvious reason for it's current status, if that's in discussion, and if it's the case what are the alternatives

5:20 ddellacosta: more context here: https://groups.google.com/forum/#!topic/clojure/pF9FEP7b77U

5:20 ddellacosta: mpenet: ah, yeah, saw that, which means you know as much as I do. Sorry. :-(

5:23 Is this the way to do this? ,(every? identity '(false true false false))

5:23 ,(every? identity '(false true false false))

5:23 clojurebot: false

5:23 ddellacosta: not sure what that second arg should be

5:23 Apage43: yup

5:23 identity works if you're just testing that the whole collection is truthy

5:24 ,(every? identity [true 1 "whee" :bucket])

5:24 clojurebot: true

5:24 ddellacosta: Apage43: yeah, that's it. What I wanted to do at first was (apply and [true false true false]) essentially.

5:45 silasdavis: in laser I'm trying to compose a base template defined with defdocument with other bits of transformed html

5:46 the defdocument takes some arguments so I can insert things that way, but in another place I wanted to transform the output of the defdocument by threading it into another document form

5:46 but to make this work it seems like I'd have to parse the original document as a string first, which seems wrong

5:47 i think I'm probably working at the wrong level - I tried playing with fragments, but also had errors using those as input to the document function. Does anyone know how I should be doing this?

5:58 NeedMoreDesu: Do you know that you can suddenly have stack overflow using chuncked lists?

5:59 I concatenated them many times randomly. Since it's lazy, it gives the result. But when you try to do something with it...

5:59 amalloy: NeedMoreDesu: well, chunkiness isn't relevant, it's the laziness

6:01 NeedMoreDesu: Why it is written that way you can have SO?

6:02 http://ideone.com/5EzIkJ

6:05 amalloy: http://stackoverflow.com/questions/2946764/recursive-function-causing-a-stack-overflow

6:10 _dw: hello. anyone here to clarify why (= bytearray1 bytearray2) always returns false? I thought it'd compare by content, not by identity. am I mistaken?

6:11 NeedMoreDesu: Thanks, that solves the riddle.

6:11 hyPiRion: _dw: Because it's a java array. Clojure runs .equal on the objects unless they are primitives/arrays, in which case they return true if they are identical

6:13 ,(import 'java.util.Arrays)

6:13 clojurebot: java.util.Arrays

6:13 francis_wolke: Has anyone done anything with lein-droid recently? I'm running into some undocumented issues while following along with the tutorial.

6:13 hyPiRion: ,(Arrays/equals ^bytes (into-array Byte/TYPE [1 2 3]) (into-array Byte/TYPE [1 2 3]))

6:13 clojurebot: true

6:13 _dw: thanks, hyPiRion. anything more "idiomatic" than (= (vec b1) (vec b2)?

6:13 hyPiRion: ^ _dw that's the most efficient one

6:13 _dw: thanks!

6:14 hyPiRion: If you can get rid of arrays in the first place that'd be more idiomatic, but of course there are cases when that's impossible :)

6:14 Just note the type hint, ^bytes.

6:14 _dw: I could cast them to vectors, should I prefer that?

6:15 hyPiRion: Well, it's certainly easier, and if performance is not an issue, sure thing

6:15 _dw: I see

6:16 noidi: To clarify hyPiRion's answer, `=` treats arrays just like other objects. It's Java's definition of `.equals` for arrays as an identity comparison that's causing the confusion.

6:16 silasdavis: Raynes, how should I go about composing fragments in laser?

6:16 noidi: http://stackoverflow.com/questions/8777257/equals-vs-arrays-equals-in-java

6:17 here's what `=` uses for comparisons https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Util.java#L24

6:18 _dw: Wasn't really aware it isn't a built-in type

6:18 This makes sense

6:41 ro_st: is it possible to give individual multimethod implementations their own doc strings? if so, how?

6:42 ambrosebs: ro_st: no, I just use comments.

6:42 ro_st: ok, thanks!

6:45 squidz: seangrov`: yesterday I asked about a problem I had translating some javascript into function clojurescript. Do you have time to help me?

6:47 seangrov`: here was the link http://jsfiddle.net/N4E5c/3/ where the first javascript function there is rather iterative and I can't think of how to translate it to functional clojure(script)

6:58 murtaza52: Hi can anyone help me understand what is the utility of go blocks without channels

6:58 I mean what is different in placing a piece of code in a go block, then outside it.

7:02 grandy_: Hi all,

7:03 I am new to clojure and unable to resolve this : http://pastebin.com/VCTeCBQv

7:07 ambrosebs: grandy_: what happens without the macro?

7:07 there is nothing wrong with the macro

7:08 grandy_: I mean this is a dummy macro i was trying to test..

7:08 in REPL seems to work fine

7:09 trying to understand the concept

7:09 ambrosebs: right, it's something else that's throwing the exception.

7:10 can you show more code?

7:59 noncom: is here anyone who tried clojuring with JMonkeyEngine3 ?

8:08 is there a way in clojurescript to pass a js function as a value? for example, can i store something like '.moveToTop in a map like (def m {:a '.moveToTop}) and then do ((:a m) someJsObject) ?

8:08 i had no fortune with that yet

8:10 scgilardi: you could try (def m {:a #(.moveToTop %)})

8:22 dark4eg_: Hello

8:23 Please help me. (s/replace "a b a" #"a|b" {"a" "1" "b" "2"}), #"a|b" - wtf? #"a|b" - сan I generate this structure programmatically?

8:25 jkkramer: dark4eg_: that would be a regular expression. see the re-pattern function

8:28 dark4eg_: jkkramer: thx. I have a list of keys map, i get to generate re-expression. where to dig?)

8:30 jkkramer: dark4eg_: the functions re-pattern, keys, clojure.string/join,java.util.regex.Pattern/quote may all come in handy

8:33 dark4eg_: jkkramer: thx

10:22 andrewmcveigh|wo: Did someone write a cljs port of clj-time yet? Can't find one on google.

10:25 rkneufeld: That'll be an interesting one.

10:25 stuartsierra: Yeah since clj-time is a thin wrapper around JODA-Time.

10:25 rkneufeld: My thought exactly. It'll be …fun, imitating an entire API.

10:25 andrewmcveigh|wo: Yeah, sure... I suppose I didn't really mean a "port"

10:26 rkneufeld: Something cross-platform would be great though

10:26 stuartsierra: Yeah, an actual pure-Clojure port of JODA

10:26 andrewmcveigh|wo: I think I heard some talk about doing it the other week/month. Now I could use it.

10:27 rkneufeld: That'd be a fun little project. If it isn't done by the time I'm done the Cookbook maybe I'll dig in there.

10:32 andrewmcveigh|wo: Doesn't seem like too much work to immitate clj-time API. Joda-Time on the other hand, not sure I'd like to bark up that tree!

10:33 Anderkent: rkneufeld: I don't think 'little' is the right adjective

10:33 stuartsierra: Not sure how you could do one without the other.

10:34 Anderkent: that depends on whether you just want clj-time/now, or all of it

10:34 glosoli: where can I find some sort of Clojure convention/idiomatic ways of doing things like accessing elements in map and so on

10:35 rkneufeld: Anderkent: that's all perspective. Working on the Cookbook is going to take the better part of a year. A few weeks of Friday time, evenings and weekends is "little" in comparison ;)

10:35 `cbp: glosoli: joy of clojure

10:36 andrewmcveigh|wo: Well, of course I only need a few bits of clj-time now, but it's not the first time I wish I had it in cljs.

10:36 `cbp: glosoli: or just read some opensource :P

10:36 Anderkent: glosoli: the clojure koans, maybe? https://github.com/functional-koans/clojure-koans

10:36 disclaimer: i haven't tried it

10:37 stuartsierra: glosoli: http://dev.clojure.org/display/community/Library+Coding+Standards

10:37 rkneufeld: andrewmcveigh: Another option is to develop a similar sets of API that are not drop-in equivalent to clj-time. Base the JS version off of something like http://momentjs.com/ and base the Clojure version on …X

10:37 glosoli: thanks ! :)

10:37 Anderkent: also, accessing stuff in map is `get-in`, just in case you want this particular answer not reading material

10:38 floatboth: Is there an easy way to buffer a lazy-seq? I have something like (map parse (line-seq lines)) and I want to store the parsed lines into Redis. To speed up Redis I/O, I want to use pipelining, but I don't want to pipeline the whole seq, I want to repeatedly take some items and send them

10:38 glosoli: Anderkent :The dev clojure links states it is keyword-first syntax to access items in object

10:38 rplaca: rkneufeld: dove into the pedestal tutorial yesterday (and continuing today). Really nice work. Thanks!

10:38 Anderkent: wrapping them in functions that abstract the map (i.e. (defn get-user-metadata [state user] (get-in state [:user user :private :metadata])) ) a bonus :)

10:38 glosoli: hmm interesting

10:38 rkneufeld: rplaca: that's all Brenton–I'm just the caretaker for that chunk of work ;)

10:38 Anderkent: glosoli: ah. Depends if it's a nested structure or basic modification. I think if it's the basic access that you ask about the clojure cheatsheet might be useful

10:38 rkneufeld: rplaca: But I'll pass it along

10:39 Anderkent: glosoli: http://clojure.org/cheatsheet

10:39 rplaca: rkneufeld: well to both of you then. please do pass it on to Brenton.

10:39 glosoli: hmm I have this one, I just found odd when someone told me that keyword-first syntax is idiomatic way of accessing items in maps, but seems they were right

10:39 rplaca: hoping to have some cool stuff to show you by conj time

10:40 Anderkent: glosoli: it usually is because it's shorter than (get map :keyword).

10:40 stuartsierra: glosoli: Keyword-first is idiomatic when you know, at the time of writing the code, what the keys are (e.g. a structured data type).

10:41 w|t: thanks

10:42 `cbp: it also prevents null pointer exceptions :P

10:42 glosoli: Anderkent: what I was used to doing was (obj :keyword).. but now I realise that's wrong

10:42 andrewmcveigh|wo: rkneufeld: Well, I think I'll implement what I need now, and see how deep that takes me ;-)

10:44 AWizzArd: In my profiles.clj I added the dep [org.clojure/core.typed "0.1.24"]. Now a “lein deps” gives me => java.util.zip.ZipException: error in opening zip file. Ideas?

10:45 squidz: whats the easiest way to test clojruescript

10:45 coventry: Have you tried removing that jar from ~/.m2 so that lein will download it again?

10:46 rkneufeld: squidz: IMO, code that is both valid Clojure and ClojureScript. Though that excludes an platform specific interop, to which I don't have a good answer.

10:46 AWizzArd: I removed the .jar from my ~/.m2 and tried it again. I also removed it from my local Artifactory.

10:47 Anderkent: AWizzArd: lein1 or lein2?

10:47 AWizzArd: lein2

10:47 Anderkent: last time I saw this message was someone using lein1 on a lein2 project.clj

10:47 hm.

10:47 squidz: hm, yeah unfortunately my code has some js interop so i'm not sure what the easiest way to test it would be

10:48 stuartsierra: squidz: cemerick ported clojure.test to ClojureScript, I think

10:48 Anderkent: AWizzArd: can you post the full stack trace somewhere? (refheap/gist)

10:49 also your profile/project file, if you can.

10:49 coventry: Maybe one of the other jars core.typed pulls in is corrupted. I would test this by moving ~/.m2 out of the way temporarily to do lein deps from a fresh start.

10:49 ambroseb_: ls

10:49 lazybot: boot data home media mnt opt src tmp usr var

10:49 ambroseb_: whoops. FWIW 0.1.24 seems to work for me.

10:50 but i didn't clear my full .m2, just that jar.

10:50 stuartsierra: haha

10:50 Anderkent: ambroseb_: I do that all the time too. Shame on ubuntu on not deriving window focus from where I'm looking

10:51 ambroseb_: :)

10:52 `cbp: xmonad clearly does that

10:52 in less than 1k lines of code~!

10:52 Anderkent: I blame Unity.

10:53 AWizzArd: Killed my .m2 dir, now it seems to work.

10:53 Must have been some corruption in there.

10:53 Thx

10:53 coventry: No worries.

11:09 squidz: ls -la

11:09 lazybot: bin dev mnt root sbin src srv swap tmp usr var

11:10 coventry: Any suggestions for a good java-for-clojure-programmers resource? Maybe something less focused on java the language, more about aspects of its internals, data structures and libraries which are useful in a clojure context?

11:11 glosoli: coventry: Like more about Core of Java and JVM

11:11 ?

11:14 coventry: Not exactly. For instance, I'm looking for somewhere I would learn that that java collections are weakly typed, characters are two bytes and "lein repl" starts java with optimization options which confuse criterium.

11:15 glosoli: coventry: hmm I would like such thing too

11:16 coventry: I have tried reading Core Java books, got through Volume I, was booring

11:18 gvickers: coventry: yea that would be very useful

11:22 Anderkent: coventry: not as far as I know, unfortunately

11:23 coventry: I might take a look at _Well-Grounded Java Developer_. It mentions polyglotism in the subtitle, and has a section on clojure, at least.

11:25 rurumate: Is it just me, or is something wrong with destructuring?

11:25 Anderkent: probably both

11:25 rurumate: (let [{a :a b :b :as m :or {a "a0" b "b0"}} {}] m) returns {}

11:26 (let [{a :a b :b :as m :or {a "a0" b "b0"}} {}] a) returns "a0"

11:26 stuartsierra: coventry: The original Sun Java Tutorials are good, in my opinion.

11:26 rurumate: seems inconsistent..

11:26 coventry: Thanks, stuartsierra.

11:27 Anderkent: rurumate: the :as form simply binds the original form to a new name

11:27 rurumate: Anderkent: so the :or has no effect on it?

11:28 Anderkent: Nothing in the destructuring form has any effect on it.

11:28 rurumate: Anderkent: grok

11:28 Anderkent: it's not 'construct these bindings and put them in a map as X', it's 'take original form, name it X, then destructure it'

11:30 Is there a more intuitive way of removing nils from a collection than (keep identity ...) ?

11:31 llasram: Anderkent: (remove nil? ...) ?

11:31 `cbp: (remove nil?)

11:31 hyPiRion: heh

11:32 llasram: Jinx!

11:32 seangrov`: squidz: Still around and looking for help?

11:32 I thought dnolen had given you some advice on it

11:32 hyPiRion: hrm

11:32 ,(keep identity [1 2 true false nil :quux])

11:32 clojurebot: (1 2 true false :quux)

11:33 seangrov`: Do you have a pre-existing cljs project I can fork and experiment with?

11:33 hyPiRion: oh, I thought it was the other way around. Serves me right

11:33 Anderkent: hyPiRion: keep only discards nils, it's not filter :)

11:34 or was that the 'other way around' bit? My bad.

11:34 seangrov`: Keep:"Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included."

11:34 ,(doc keep)

11:34 clojurebot: "([f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects."

11:34 seangrov`: botsnack

11:34 hyPiRion: Anderkent: yeah, I thought it just discarded false. I just forgot *what* it discarded

11:34 seangrov`: ~botsnack

11:34 clojurebot: botsnack is newline

11:34 seangrov`: Alright, no botsnack

11:35 hyPiRion: ~botsnack

11:35 clojurebot: botsnack is scoobysnack

11:35 hyPiRion: clojurebot: stupid

11:35 clojurebot: Excuse me?

11:35 llasram: Aww

11:35 Poor clojurebot

11:35 `cbp: clojurebot: botsnack

11:35 clojurebot: botsnack is forget botsnack

11:37 w|t: clojurebot, botsnack

11:37 clojurebot: botsnack is scoobysnack

11:38 hyPiRion: poor boy, he's gone mental

11:39 * seangrov` tears up, "He was my bot, I'll do it."

11:40 squidz: squidz: yeah I still need help. I may have not seen what dnolen said

11:40 here is the link again http://jsfiddle.net/N4E5c/3/

11:41 seangrov`: i meant that to you and not to me of course

11:41 seangrov`: What does it do from a high-level?

11:41 And you said you were using the strokes library, is your project on github so I don't have to setup a dummy project locally?

11:45 squidz: from a high level that function manipulates an array of maps so that that there are even numbers of maps for given fields

11:45 it shouldnt depend on strokes, I just need to somehow manipulate the data assuming it is not a javascript array of objects but instead a clojure array of maps

11:46 seangrov`: the exmple of the data is in the link i posted

11:47 the two commented entries in the data should be created by a clojure function. That function will instead fill in default values, or in our case the :value field in the map should be set to zero

11:50 seangrov`: Ok

11:56 TimMc: clojurebot, forget botsnack |is| forget botsnack

11:56 clojurebot: I forgot that botsnack is forget botsnack

11:56 TimMc: clojurebot, forget botsnack |is| newline

11:56 clojurebot: I forgot that botsnack is newline

11:58 seangrov`: squidz: Seems like this could be a much nicer example to work with

12:00 squidz: seangrov`: what example?

12:00 seangrov`: The example you gave, it's unclear where the interpolated data comes from

12:01 squidz: yeah that example isn't from me

12:01 seangrov`: Well, you're the one asking for help :P

12:02 How is the interpolated data calculated?

12:02 squidz: yeah soembody else had the problem in javascript and I have the problem in cljourescript. That is supposed to be the solution but I don't really see how I can translate that first javascript function to clojurescript

12:02 the value will always be zero

12:02 and there should be an equal number of dates for each group

12:02 coventry: Where are you stuck with the translation?

12:02 seangrov`: You said the two commented out rows should be added: //{key:'Group2',value:12,date:'04/23/12'},

12:03 squidz: no the values should be zero, sorry

12:03 just the dates should remain so that there are equal numbers of dates for each group

12:03 seangrov`: I see, ok

12:04 Should there be an equal number of dates, or should there be the same dates for every group?

12:05 squidz: all groups should have the same dates

12:05 seangrov`: Alright, that's not too bad

12:06 squidz: so if grp1 has two dates and grp2 two has one date, it is assumed that the one date is shared, and an adittional entry should be made for grp2 so that they again have the same dates

12:06 *an additional map should be made for grp1

12:06 seangrov`: Sure, btu if Group1 has two dates, and Group2 has two dates, and neither of them are the same, then they should both end up with 4

12:07 squidz: yes exactly

12:07 so that the maximum coverage of dates is provided

12:16 seangrov`: squidz: https://www.refheap.com/18069

12:17 Example output: https://www.refheap.com/18070

12:19 gfredericks: clojure.core/realized? with lazy seqs is kind of misleading

12:19 seangrov`: Seems to do the trick

12:19 gfredericks: to n00bs at least

12:21 dnolen: squidz: I solved this yesteday http://gist.github.com/swannodette/6355478

12:22 squidz: I'm not sure if dates will fall in the middle requiring padding around, I noticed that each pad entry must have a different day.

12:22 squidz: anyways I think this version is way easier to understand than the JS you posted yesterday ;)

12:22 seangrov`: Yeah, that js is crazy

12:24 squidz: dnolen: oh sorry I didn't see your reply I may have left the office right before you sent it

12:25 dnolen: squidz: i didn't send it since you weren't around

12:25 squidz: oh okay I see well thank you both for your help. I really wanted a clear idea on how I could do it in clojurescript and thanks to yall I have two good examples. That should be more than enough for me. Thank you both

12:26 when I saw that javascript my head was spinning for some reason. it was very iterative

12:27 thanks

12:30 dnolen: squidz: my head was spinning too

12:31 jtoy: are there size limitations with atoms?I am adding integers to an atom vector and it does with OOM when I only have 2k items on it,

12:34 or is this the wrong user case for an atom? Im just using it as a queue

12:35 amacdougall: Curious about this as well. In Joy of Clojure, they implemented a queue using Agents — is that the standard technique?

12:36 seangrov`: ,(count (let [queue (atom [])] (dotimes [n 3000] (swap! queue conj n)) queue))

12:36 clojurebot: #<UnsupportedOperationException java.lang.UnsupportedOperationException: count not supported on this type: Atom>

12:36 seangrov`: ,(count @(let [queue (atom [])] (dotimes [n 3000] (swap! queue conj n)) queue))

12:36 clojurebot: 3000

12:38 opqdonut: amacdougall: I guess standard would be to use a vector atom

12:40 Anderkent: opqdonut: you cannot safely pop from a vector atom

12:40 amacdougall: yes, agents are pretty much a perfect fit for a shared queue

12:42 jtoy: so use agent instead of atom for a queue? is that correct?

12:42 Anderkent: jtoy: how many threads are you running? if a lot, you might have many of them trying to update the same atom at the same time and thus keeping size-of-vector * number of threads in memory

12:42 jtoy: Anderkent: I have not changed any threads sizes, everything is default currently

12:43 Anderkent: jtoy: as in you're feeding it data from a single thread?

12:43 that shouldn't happen, are you sure it's not something else eating your memories?

12:43 jtoy: Anderkent: yes, i am feeding in data from the repl, just testing my code

12:43 im sure,

12:43 noncom: does anyone know, when requiring a namespace, does clojure look for the (ns) macro in the file's text, or does it simply try to execute the code inside the text file?

12:43 Anderkent: jtoy: ah. The repl keeps history for you, which possibly references objects that would otherwise be GCd?

12:44 jtoy: Anderkent: my code is this: (def users-queue (atom [])) ; (defn add-to-users-queue! [id] (reset! users-queue (conj @users-queue id))) ; then i call add-to-users-queue! ~ 3k times

12:44 Anderkent: I tried on a brand new repl

12:44 `cbp: there should be a when-seq-let macro :P

12:44 Anderkent: jtoy: as to your agents question, if you need pop then you can't use atoms - there's no way to do a 'read, modify, save' loop and extract a value from the middle of it unless you maually do a compare-and-set! loop

12:45 seangrov`: jtoy: Why reset! and not swap! ?

12:45 jtoy: this was the pop! i wrote: https://www.refheap.com/18071 didnt get to test it yet

12:45 Anderkent: jtoy: you can either use agents, if you don't mind being asynchronous, or refs and transactions

12:46 jtoy: seangrov`: i just started using agents, im still learnign the proper way

12:47 Anderkent: jtoy: both your functions are not thread safe. If something else modifies the queue inb etween your @queue and (reset!), you will overwrite that information

12:47 jtoy: also your code works for me: https://www.refheap.com/18073

12:48 coventry: Yes it works for me, too. Was thinking to run it on clojurebot, but didn't want to risk crashing him. :-)

12:48 jtoy: Anderkent: mine dies at 2016 every time :)

12:49 Anderkent: can you paste the repl output exactly? and are you possibly running some weird jvm options? (-xMx=2m :P)

12:49 opqdonut: Anderkent: do you mean that I can't both pop and return the popped element? yeah that's a problem.

12:50 Anderkent: opqdonut: yes, exactly. It's not a 'problem', it's a dealbreaker for a queue :P

12:50 technomancy: hugod: would it be crazy for criterium to try to check for tiered compilation and warn if it's off?

12:51 jtoy: I think i see why

12:51 hugod: technomancy: probably a good idea - should be simple enough to detect

12:52 jtoy: i changed for to doseq for inserting the ids

12:52 llasram: If you want a concurrent, non-persistent queue, just use the task-appropriate java.util.concurrent queue

12:52 That's what the Clojure standard library does itself

12:53 jtoy: llasram: how is it non persistent? arent all the clojure queues non persistent?

12:53 `cbp: clojure.lang.PersistentQueue is persistent

12:53 llasram: Right. I mean if you don't need the queue to be persistent

12:54 If you're just pushing items on and popping them off in some sort of producer/consumer model, the j.u.c queues are the way to go

12:55 Anderkent: I think it was more of a 'how would I go about doing this in clojure' question than a 'how do I get this problem solved' question

12:56 jtoy: so if I want to have a system where ids get added to different queues and consumers at certain time run jobs (based on some logic) what queue mechansim should I use? I dont really care if they are persistent

12:56 Anderkent: I mean sure j.u.c queues will probably do it, but that doesn't help one familiarize themselves with clojures concurrency primitives

12:57 llasram: Anderkent: Yeah, but you should use the right tool for the job. Clojure in part doesn't have things which duplicate what's in j.u.c because that stuff is already rock solid and awesome

12:57 Anderkent: jtoy: agent per consumer, +1 agent as a dispatching exchange that does the 'which consumer should handle this' logic then sends the message to consumers work queue

12:59 llasram: My vote is only use agents when the value of the agent itself is meaningful. agent == state + queue of updates to perform against it

13:00 If you just need a the queue part and there isn't meaningful state attached to the queue, then I think it's best to just use a queue

13:00 opqdonut: Anderkent: btw atoms work if you cheat a bit: https://gist.github.com/opqdonut/6355918

13:01 obviously retaining a reference to the element that was just popped is a slight problem, but it works

13:01 jtoy: I dont have state in the queue, but the consumer can only work at certain times so it needs to check whether it can run before pulling data from the queue

13:01 Anderkent: opqdonut: yeah, but that is generally messy

13:01 jtoy: oh, then agents arent what you want - the control is inverted for them: you're told when you have work, you don't poll for it

13:01 seems you just want refs and transactions

13:02 opqdonut: on a related note, ArrayBlockingQueue is fine for a quick hack

13:02 clj_newb_2345: is there a standard way to do keyword arguments for funciotions in clojure1.5.0, or is it still a bunch of ahcks from contrib?

13:02 jtoy: for the scheduling part is there recommended library? I was about to use quartz, but looking through the docs, it seems more complicated then i need

13:02 amacdougall: There's a way of destructuring that parses kwargs, right?

13:02 Anderkent: llasram: the problem with using j.u.c is that it might be fine if you just need a queue, but as soon as your state is larger than that, say you have a map in an atom where one of the keys is your work queue you get in so much trouble

13:02 jtoy: at-at looked fine when I browsed through it

13:03 llasram: Anderkent: Sure. Use the right tool for the job

13:03 jtoy: Anderkent: so then use atoms or juc? I try to stay away from java heavy stuff since I've never really programmer java before clojure

13:03 Anderkent: jtoy: neither. Use refs and (dosync) blocks.

13:03 ToBeReplaced: clj_newb_2345: see https://github.com/ToBeReplaced/mapply maybe

13:04 jtoy: ok

13:05 thanks all

13:05 Anderkent: ... except that these don't like being nested, so there's another possible problem.

13:05 (or rather, the nesting semantics are what you want 90% of the time, but when they aren't you can't do anything about it)

13:08 jtoy: just don't use knit for scheduling, it leaks threadpools like mad.

13:08 ambroseb_: amacdougall: it's the same syntax, but after &

13:11 Anderkent: amacdougall: so basically ([a b c & {:keys [key with-default] :or {with-default :foo}}] ), if an example makes it easier

13:12 (forgot the defn)

13:15 clj_newb_2345: clojure has number? -- does clojure not have "bool?" ?

13:15 i'm looking for a function that's basicallly like #(= (type %) java.lang.Boolean)

13:17 stuartsierra: clj_newb_2345: (instance? Boolean foo) is all there is

13:17 kohkane: clj_newb_2345: there are the true? and false? predicates

13:17 technomancy: #{true false}

13:18 anildigital: my map key has vector having string values.. now want to return the key of the map .. if values contain one of the string

13:18 how to do this in clojure

13:18 stuartsierra: technomancy: (#{true false} false) will return false

13:18 clj_newb_2345: staurtsierra, kohkane: noted, thanks

13:18 bbloom: stuartsierra: i have defn boolean? in a non-trivial number of programs :-)

13:18 technomancy: stuartsierra: heh; true

13:18 clj_newb_2345: technomancy : thanks-- ; staurtsierra: thanks++;

13:18 stuartsierra: :)

13:19 technomancy: clj_newb_2345: you misspelled inc and dec

13:19 clj_newb_2345: how long are you going to keep that nick anyway? =)

13:19 bbloom: (++ technomancy)

13:19 clj_newb_2345: technomancy: until I understand core.async, pedestal, and core.match

13:19 * technomancy nods

13:20 pjstadig: (1+ technomancy)

13:20 technomancy: oh you.

13:20 bbloom: (swap! technomancy update-in :karma inc)

13:20 dammit, i mean:

13:20 stuartsierra: heh

13:20 bbloom: (swap! technomancy update-in [:karma] inc)

13:20 technomancy: (incf bbloom)

13:20 stuartsierra: Those damn brackets. Gets me every time.

13:21 bbloom: stuartsierra: dur. shoulda used assoc

13:21 justin_smith: ,(contains? #{true false} false)

13:21 clojurebot: true

13:21 muhoo: (inc dec)

13:21 lazybot: ⇒ 1

13:22 bbloom: er my brain isn't working. not associ, update-in is what i want. why don't we have an update function w/o the -in part again?

13:22 stuartsierra: bbloom: Because.

13:22 TimMc: bbloom: ITYM (swap! karma update-in ["technomancy"] inc)

13:22 bbloom: TimMc: and now we see that data encapsulation is sometimes a good thing :-P

13:23 i wish it were 10X easier to create custom map types

13:23 TimMc: I don't think it's a good idea to have technomancy as a var.

13:23 bbloom: b/c i'd totally make a karma map w/ reverse indexes :-P

13:24 technomancy: surely technomancy gets so much karma we can justify the special case

13:24 er that was for TimMc, you guys get the idea

13:26 Anderkent: TimMc: (alter-var-root #'technomancy (constantly some-other-guy)) - identity theft at its prime

13:27 hyPiRion: Now just wait until he's collected by the garbage man

13:40 anildigital: This should have print "Win" right https://gist.github.com/anildigital/a7e1c8683a2605c638a5

13:41 rasmusto: anildigital: careful with contains?, it doesn't do what you think it does

13:41 anildigital: rasmusto: any alternative to contains?

13:42 rasmusto: anildigital: I'd use a set, but there might be another way

13:42 Anderkent: anildigital: make your vector a set and then query that: (cond ((set v) "WATCH OUT!") :won)

13:43 alternatively

13:43 (cond (some #{"WATCH OUT!"} v))

13:43 might be cheaper if your vector is really long

13:44 anildigital: also see http://stackoverflow.com/questions/3249334/test-whether-a-list-contains-a-specific-value-in-clojure for the answer and explanation of what contains? does

13:49 jtoy: I know this is horrible, but if i have an an atom vector, why does this return the same item instead 100 different items? (map (fn [x] (pop-users-queue!)) (take 100 (range)))

13:50 im interested to understand why it doent work

13:50 rasmusto: anildigital: long story short, contains? checks for existence of a key, in the case of a vector, its looking for indices that exist

13:50 anildigital: rasmusto: got it

13:52 user> (for [[k v] things] (cond ((set v) "WATCH OUT!") k))

13:52 (nil "Woah, chill out!" nil nil)

13:52 how to make it return just result .. woah .. one

13:54 llasram: jtoy: hard to say w/o seeing the implementation of `pop-users-queue!`

13:55 jtoy: llasram: https://www.refheap.com/18076 I tested it by running pop-users-queue! a couple of times and got different ids everytime myself

13:55 anildigital: https://gist.github.com/anildigital/33c8b4d18c277e76b394 should return string.. but is returning nil

13:55 how to make clojure return the matched result

13:55 instead of returning all the results

13:56 llasram: jtoy: First off, if you're going to use an atom, use `swap!`, not `reset!`

13:57 kohkane: anildigital: doseq returns nil irrespective of result

13:57 rasmusto: anildigital: you want it to return just "Woah, chill out!"?

13:57 anildigital: rasmusto: yes

13:57 jtoy: llasram: but swap! returns the value swapped in?

13:57 llasram: jtoy: Second, using pop w/ a vector means this would be a stack, not a queue

13:57 anildigital: rasmusto: i changed doseq to false but no much help

13:58 saolsen: are there any pubsub abstractions build on core.async yet that work in clojurescript?

13:58 rasmusto: anildigital: I'd recommend for instead of doseq, followed by a (first (filter (complement nil?) res))

13:58 llasram: jtoy: And... Yeah, actually. So you use `first` to get an item out of the vector, then use `pop`, which drops the last item (not the first)

13:58 That's why you're getting the same item every time

14:00 glosoli: is there some way in vim-fireplace to keep the Command Line for entering clojure code for evaluation always on (that cqc thing)?

14:00 llasram: But fundamentally, this implementation doesn't even begin to be concurrency safe. You need check-and-set semantics, which you can only do with `swap!` -- not with `deref`+`swap!` and definitely not with `deref`+`reset!`

14:01 jtoy: If this is all you're trying to do, then you definitely just want a j.u.c queue

14:02 jtoy: yes, that is all i need

14:02 looing up how to do that

14:03 llasram: jtoy: Look at the implementation of clojure.core/seque

14:03 It's a clojure.core function which uses a j.u.c LinkedBlockingQueue

14:05 jtoy: thx

14:05 llasram: Well, it's a bit funky. I'm not sure it shows off best practices. But at least it is an example

14:06 jtoy: llasram: is there a more idiomatic way to write this? (map (fn [x] (pop-users-queue!)) (take 100 (range)))

14:07 rasmusto: glosoli: it uses vim's command-line window, and I don't know that theres a way to make that "stick"

14:07 llasram: jtoy: (repeatedly 100 pop-users-queue!)

14:07 glosoli: rasmusto: eeeh ;/ damn all the editors

14:08 jtoy: cool, never saw repeatedly

14:08 rasmusto: glosoli: for persistant stuff like that, I just make a bunch of namespaces that I drop into .gitignore

14:08 glosoli: rasmusto: emacs broke me lol, I can stand it and now can't go back to VIm that easy ;/

14:09 rasmusto: glosoli: are you just missing the emacs integrated repl?

14:09 glosoli: rasmusto: yeah

14:09 rasmusto: glosoli: understood

14:10 glosoli: rasmusto: But while in Emacs I am missing decent Nerd Tree

14:10 rasmusto: glosoli: Nerd Tree is far from the killer feature of vim, you should stay with emacs IMO :)

14:11 glosoli: I like using some sort of fuzzy file/workspace search instead of actually browsing through file trees

14:12 glosoli: rasmusto: Hmm same here, dunno, I just thought about a need of something like proper nerd tree in Emacs and kept on killing myself with the idea, though I would barely use it for sure

14:12 cgag: nerdtree is definitely one of the things that keeps me from bothering with emacs

14:12 glosoli: you made me sad again lol

14:12 cgag: that plus the editing

14:13 glosoli: editing ?

14:13 rasmusto: cgag: evil-mode, and uninstall nerd-tree from you vim plugins, makes it easier to switch

14:13 anildigital: anyone on exercism? want to nitpick my solution http://exercism.io/submissions/521ce6cd97552d2d96000059

14:14 cgag: just the general lack of modal editing / the crazy key chords, evil isn't bad, but i haven't really felt any significant motivation to switch since I got kind of comfortable with fireplace

14:14 the lack of a real repl is kind of annoying though

14:14 glosoli: cgag: that's why I can't go back to vim lol

14:14 cgag: the problem with evil is you have to write vim-like bindings for all the plugins

14:14 rasmusto: cgag: I agree (with you fireplace point). I think multi-repl stuff could be useful in emacs

14:15 glosoli: rasmusto: hmm can't you do that already ?

14:15 rasmusto: glosoli: er, I meant that its something that's lacking in vim, and it would be a +1 for emacs

14:16 glosoli: rasmusto: I am not sure if there is multi nrepl coz I never tired myself, though I somehow concluded to it being that way

14:17 seancorfield: nrepl.el supports multiple repl sessions

14:18 i often have a local repl running and then at least one more repl into another process

14:20 glosoli: seancorfield: hmm sounds interesting

14:37 noncom: does anyone have experience clojuring with JMonkeyEngine3?

14:50 seangrov`: Wow, as far as I can tell my clojure app isn't doing anything, and yet it's consuming ~750% cpu

14:50 nDuff: seangrov`: ...well, if you have a reproducer...

14:50 seangrov`: I started it via nrepl-jack-in - any way to peek at what the hell it's doing to consume all the cpus?

14:50 nDuff: seangrov`: generally, btw, you'll want to use the same profiling tools you'd use for Java.

14:51 seangrov`: nDuff: It's likely that I've done something in the repl, I'm just not clear on what it would have been

14:52 noncom: try visualvm?

14:53 seangrov`: noncom: Thanks, I'll look it up

15:20 pandeiro: what is the difference between using ring's wrap-sessions with and without the middleware.session.cookie/cookie-store fn?

15:24 kohkane: pandeiro: Session information is usually stored locally and retrieved with the ring-session cookie key

15:25 panderio: If you specify the cookie-store then it's stored encrypted in a cookie on the users browser

15:25 pandeiro: kohkane: 'locally' in this case means on the server?

15:26 kohkane: pandeiro: Yes

15:26 pandeiro: kohkane: okay but even w/o cookie-store, a session cookie is saved on the browser. so the difference is encryption?

15:27 kohkane: pandeiro: There is only a ring-session key thats stored on the users browser that indexes session information map

15:27 pandeiro: With cookie-store the entire session map is stored on the users browser but its encrypted so that the user cant access it

15:28 callen: http://inchingforward.blogspot.com/2013/08/adventures-in-luminus.html

15:29 pandeiro: kohkane: ah so if i store arbitrary keys/vals in the response's :session, they will be present in the browser, but encrypted

15:30 kohkane: pandeiro: If you use cookie-store, yes. Otherwise, it'll be stored on the server in a map with the ring-session cookie of the users browser as the key

15:32 pandeiro: kohkane: ok so does using cookie store make it harder for someone to spoof a cookie from a different user's browser session? or not really, if they just copy it over verbatim?

15:35 kohkane: pandeiro: I'm NOT really sure, but I guess both methods have equal risk because if someone can just copy your ring-session cookie, they can copy your entire cookie store

15:35 pandeiro: right.. i am trying to understand the utility of cookie-store: it's basically a persistence mechanism, not a security one

15:35 kohkane: thanks for the explanations

15:36 Apage43: pandeiro: the purpose of cookie store is to store the data in the browser, rather than on the server

15:36 yeah

15:36 pandeiro: to combat cookie spoofing, something like nonces...

15:37 Apage43: if you're worried about eavesdroppers you should probably just be using SSL

15:39 pandeiro: Apage43: yeah actually i am using a third party service via oauth for the 'serious' parts... i am just trying to accelerate the oauth workflow as much as possible by caching the access tokens (wisely)

15:39 kohkane: pandeiro: cool

15:42 seangrov`: Is it not possible to use (comment ) and put arbitrary (non-valid clojure) text in?

15:42 tauntaun: Does clojure have a web framework as fully featured as Python's Django?

15:42 seangrov`: (comment Steps: 1. So this 2. Do that)

15:42 ,(comment Steps: 1. So this 2. Do that)

15:42 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: Steps:>

15:42 seangrov`: Ok, well, I guess that explains it

15:43 bbloom: seangrov`: comment is just a macro, it's not special

15:43 amalloy: seangrove: comment is just a macro; it has to be able to read the input form

15:43 bbloom: try (source comment)

15:43 TimMc: seangrov`: If you are careful about what you write, sure! https://gist.github.com/samn/5843422

15:43 Notice that he doesn't use a wide variety of punctuation.

15:44 bbloom: lol that seems like a terrible plan

15:44 amalloy: yeah, if you never misbalance parens, use semicolons, or try to talk about things like: lists, you're fine

15:44 TimMc: And forget about using the normal range of emoticons. :-(

15:45 amalloy: well okay, but we're looking for arguments *against* this plan

15:45 TimMc: seangrov`: Using #_ "blah blah blah" is generally superior.

15:46 amalloy: TimMc: c'mon, just put ;s in front of every line. it's not like editors make that hard

15:46 TimMc: No, everything must be data!

15:46 futile: welp

15:47 TimMc: Write everything in parse trees.

15:47 bbloom: http://www.haskell.org/haskellwiki/Literate_programming

15:47 pandeiro: keywordize every word

15:47 bbloom: who doesn't want their program inside a latex program?

15:49 stuartsierra: And another 2 programs to separate the code from the latex.

15:49 bbloom: or you can just write one program that does both at the same time & then write two more programs that call the first one and throw out half of the data

15:50 callen: seancorfield: Is there a universal function somewhere in c.j.j through which all queries/inserts/etc pass through?

15:51 * TimMc tries and fails to write a docstring '#{out of nested sets and symbols #{like this}} where the hashing produces the printout in correct order.

15:54 TimMc: &#{(println "of") do (do :z/h283r (println "order")) (do :b121 (println "out"))} <-- example I made a while ago

15:54 lazybot: ⇒ out of order nil

15:54 phiat: is there a better place to ask a noobish question? (list comprehensions/permutations/recur)

15:54 https://gist.github.com/phiat/532c72d7c88725b3fa3b

15:54 dnolen: phiat: all noob questions allowed just ask

15:55 futile: What's c.j.j.?

15:55 amalloy: phiat: that's a pretty good implementation

15:55 phiat: i don't understand how (disj (set things) head) works

15:55 amalloy: the (do) inside the for is unnecessary, and (= 1 (count things)) should be (not (next things))

15:56 phiat: i took this fn from kyle burton's blog

15:56 TimMc: futile: Probably clojure.java.jdbc

15:56 futile: oh

15:56 thanks

15:56 phiat: thanks

15:57 amalloy: actually, i take it back, it's not really that good because it's building O(N^2) sets of average size N/2 for no particular reason

15:57 squidz: ³how can I best change multiple map values given a vector of new values for example given the vector [5 5] update the values 1 and two. [{:value 1} {:value 2}]} -> (5 5) :-- [{:value 5} {:value 5}]

15:57 amalloy: anyway, phiat, (disj (set things) head) means: "build a set out of all the things, and remove head from it"

15:58 phiat: thanks amalloy, i'm not super interested in optimization, just learning how it does its magic

15:58 amalloy: well, it's not really *right* either, because it fails on lists with any duplicate elements

15:58 phiat: true, suppose that is given

15:59 bja: tauntaun: essentially no. It has libraries that get you there. But it's much more akin to using Flask than Django

15:59 squidz: i'm trying to modify a nested map so I may be asking the wrong question. the map looks like this: {:key 'a :values [{:value 1} {:value 2}]} 5 5 => {:key 'a :values [{:value 5} {:value 5}]}, where the second map is what i'm going for

16:00 given a vector of new vals to associtate, here [5 5]

16:01 tauntaun: bja: thanks

16:03 Apage43: ,(let [m {:key :whatever :values []} new-vals [5 5]] (assoc-in m [:values] (mapv (partial hash-map :value) new-vals)))

16:03 clojurebot: {:key :whatever, :values [{:value 5} {:value 5}]}

16:03 Apage43: er, no need for assoc-in there

16:03 seancorfield: callen: no, no universal function... do-prepared-stmt is close i think

16:04 Apage43: just (assoc m :values …) since its only one key dee

16:05 squidz: thanks ill give it a try

16:06 lyn_: ,(doc mapv)

16:06 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]); Returns a vector consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

16:06 Apage43: like map, not lazy, returns a vector

16:06 squidz: works like a charm thanks

16:07 lyn_: nice, been bitten by maps laziness

16:07 squidz: never used mapv before, looks likve it could have save me some troubles if I would have had it in mind

16:14 callen: seancorfield: interdasting. I tried that, didn't get very far. Also couldn't extract the SQL because things were already buried in helper fns.

16:14 seancorfield: in order to write a nice SQL query logging library, am I just going to have to play fn whack-a-mole with c.j.j or what?

16:14 hugod: technomancy: do you have a good link with an explanation of lein's use of TieredStopAtLevel?

16:14 callen: please tell me I have a better option than that - but if I don't, is there a list of the fns I should wrap in order to catch all queries/actions against the database?

16:19 asteve: how can I get more of the stack trace from a lein compile error?

16:19 I'm getting a "Don't know how to create ISeq from: clojure.lang.Keyword" error but I don't know where to look in the file for the call

16:20 hyPiRion: asteve: Is that during compile time or runtime? In either case, you should get a line number

16:20 asteve: hyPiRion: compile time

16:21 hyPiRion: Then it's because a keywords is used where a seq/vector is expected

16:21 ,(let :keyword what)

16:21 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: let requires a vector for its binding in sandbox:>

16:21 hyPiRion: like that, just somewhere else apparently

16:23 phiat: amolloy: I'm still not wrapping my head '(no pun) around how the (disj (set things) head) returns anything but the head, seeing that head is bound to things...

16:23 https://gist.github.com/phiat/532c72d7c88725b3fa3b

16:25 TimMc: What would be the consequences of replacing all deref calls in a dosync block with ensure calls?

16:25 callen: TimMc: sounds like a good opportunity to do some ?!SCIENCE!?

16:26 TimMc: I don't think the experiemtnal method is particularly appropriate for studying concurrency correctness. :-P

16:26 phiat: amalloy: I'm still not wrapping my head '(no pun) around how the (disj (set things) head) returns anything but the head, seeing that head is bound to things...

16:26 TimMc: It seems to me that any time you deref a ref in a dosync, you *probably* want to ensure it somewhere in the dosync as well.

16:28 Basically, I'm wondering if anyone can come up with a countering use-case.

16:28 technomancy: hugod: I don't think there's a good link; it was just something I heard jruby had a lot of success using

16:28 maybe https://weblogs.java.net/blog/forax/archive/2010/09/04/tiered-compilation

16:29 phiat: I'm trying to get a basic fn to return permutations on a set. doesnt need to be efficient, nor account for duplicates

16:29 futile: you guys are way smarter than me

16:29 and im very glad for that

16:30 phiat: without the entire math.combinatronics...

16:30 stuartsierra: TimMc: There are lots of cases where you may want to read multiple refs in the same transaction, consistently, but you don't care if they have changed by the end of the transaction.

16:30 amalloy: phiat: head isn't bound to things, it's bound to each successive item in things, in a loop

16:30 noncom: futile: yes, sometimes i read this irc and feel sooo glad for that...

16:30 callen: technomancy: that's pretty impressive. :)

16:30 noncom: pure happiness i say

16:31 technomancy: callen: eh?

16:31 callen: noncom: until you're on the sharp end of amalloy's idiot stick, sure.

16:31 futile: noncom: http://bit.ly/1dkKyXm

16:31 callen: technomancy: tiered compilation

16:32 amalloy: callen: you're accusing me of being hostile?

16:32 callen: technomancy: nifty stuff, I didn't know it existed beyond seeing it in some Leiningen stuff.

16:32 technomancy: oh, it's an OK link, but it doesn't discuss the StopAtLevel aspect specifically

16:32 callen: amalloy: not really accusing, just gently prodding you :)

16:32 hyPiRion: amalloy: I thought that was a compliment

16:32 technomancy: callen: beware the -X[...] args

16:32 noncom: futile: haha, both.

16:32 technomancy: callen: have you tried my ocaml code yet?

16:32 futile: So after my project management tool, my next project is gonna be an IDE for Clojure in Clojure.

16:33 * futile is on a roll with OSS

16:33 callen: technomancy: grenchman?

16:33 technomancy: callen: aye

16:33 callen: not yet, I need to.

16:33 noncom: futile: what was your project management tool? i missed that..

16:33 callen: in fact, I have use for it right now.

16:34 phiat: amalloy: thanks! lightbulb!

16:34 technomancy: callen: let me know what you think if you do

16:34 futile: noncom: Oh just that I plan to write a tool that replaces the dilapidated one we're using for work.

16:34 callen: technomancy: opam is nifty. OPAM is just from the last couple years right?

16:35 squidz: futile: how would it be different than the IDEs out right now? Would the clojure in clojure change anything?

16:35 noncom: futile: i see... and what about the ide? are you gonna go in steps of clooj?

16:35 technomancy: callen: maybe even just year, singular

16:35 callen: technomancy: I wonder why people suddenly cared. Very grateful for it anyway.

16:35 technomancy: callen: sponsored by Jane Street, it sounds like

16:35 callen: maybe they had a good year :)

16:36 technomancy: heh

16:36 callen: if you do get a chance to look at the codebase itself I'd be interested in hearing thoughts from someone who knows what decent OCaml looks like

16:37 so far I'm in the single-digits of days of experience

16:37 callen: I am far from an authority on that.

16:37 technomancy: double-digits at least? =)

16:37 callen: I was just a refugee that used it for awhile before and after Haskell.

16:38 to write utilities, mostly.

16:39 well at least Minsky's finally doubling down on the community.

16:41 ToxicFrog: Minsky?

16:42 callen: ToxicFrog: Jane Street (founder?), OCaml luminary/advocate.

16:43 ToxicFrog: OCaml is basically type systems and FP done right and pleasantly so. Nifty language for producing binaries.

16:44 ToxicFrog: Aah.

16:47 futile: squidz: It would do all the things I want it to.

16:48 squidz: I admit that's kind of vague. But if I had doubted this intuition before, I wouldn't have come up with Zephyros or Bahamut. And I'm super glad I did both.

16:48 squidz: (see https://github.com/sdegutis/zephyros and https://github.com/sdegutis/bahamut)

16:48 noncom: probably not.

16:48 squidz: Apage43: the example you gave me works when the maps only contain one key but when there are others it overwrites everything. {:value 1} -> {:value 5}, but {:value 1 :date 1} -> {:value 5} so the second key and val are ignored

16:49 Apage43: Ah

16:49 futile: squidz: also I think Clojure is the best language for it because of all the available Clojure libraries for inspecting/manipulating Clojure projects.

16:50 Apage43: I didn't understand what you were trying to do

16:50 squidz: futile: your github link is broken

16:50 futile: squidz: the second one? Your irc client might just be including the closing-parenthesis.

16:51 noncom: futile: nice things zephyros and bahamut! although i am a windows user, i see they are cool. and also you listen to tool music, that ensures you making cool software

16:51 s4muel: maynard++

16:51 futile: noncom: haha. well I normally would argue against that measurement, but heck I'll take what credibility I can get.

16:51 s4muel: rather (inc maynard) here.

16:51 squidz: Apage43: do you know if there is a way to do it when my maps are structured like that?

16:51 noncom: ehehe :)

16:51 (inc maynard)

16:51 lazybot: ⇒ 1

16:52 noncom: $seen maynard

16:52 lazybot: I have never seen maynard.

16:52 noncom: :(

16:52 futile: lazybot: you should, he's a great singer

16:52 noncom: bad for you bot

16:52 squidz: futile: ah i pasted them both as one url, didnt realize that it is two

16:52 futile: squidz: heh

16:52 Apage43: Squidz I'd use reduce and assoc-in

16:52 noncom: so an idea about a cool ide sounds cool

16:52 actually i think that ides are stuck in past

16:53 TimMc: stuartsierra: The situations you're thinking of, do they also involve writing to another ref? If all you're doing is reading refs, then sure, you never need ensure.

16:53 futile: Most IDEs seem to have features I don't want and lack features I want.

16:53 noncom: what you think about emacs?

16:53 what does not suit you with it?

16:54 futile: I've been using emacs for a few months in Clojure. It's lacking in some areas.

16:54 stuartsierra: TimMc: Sure, say you want to read two related counters to update a third which will be used for analytics or UI display or something.

16:54 Apage43: (reduce (fn [m idx] (assoc-in [:values idx] (v idx))) m (range (count v)))

16:54 squidz: futile: have you seen deuce? https://github.com/hraberg/deuce

16:54 noncom: i dont use emacs, but ppl say it is 100% customizable (and i agree from what i know). what is intersting is that you find it somewhat limiting

16:54 Apage43: Where m is your map and v is the vector of values

16:54 futile: Sure, it's open source and I could fix the problems by trying to fix other people's code. But I've learned to discern when a rewrite is in order or not, and in emacs's case it is.

16:55 squidz: Apage43: let me give it a try

16:55 Apage43: Typing on phone so i haven't tested that

16:55 squidz: Apage43: ill try it out for you

16:55 futile: squidz: I looked briefly at it and emulating emacs is not the right goal. Emacs was written in the 80s when things were much different, and has not evolved as gracefully as it should have.

16:56 asteve: how can I get a full stack trace at compile time?

16:56 I would like this piece: " ... 26 more"

16:56 futile: Granted, many people here will disagree. Just like many people use Slate instead of Zephyros. But many people have moved from Slate to Zephyros. So I have confidence now that I know what I'm saying.

16:56 stuartsierra: asteve: You're not really missing anything. those are just duplicated stack frames in the "caused by" chain of the exception.

16:57 mgaare: futile: what in particular do you want to see in emacs

16:57 hyPiRion: proper concurrency for a start

16:57 asteve: stuartsierra: ok how can I narrow down where in my file is causing this exception "Don't know how to create ISeq from: clojure.lang.Keyword" ?

16:57 futile: mgaare: well for one thing, ido-mode will omit results when I type "viewcode" but show them if I type "view/code" even though I have fuzzy matching on. That's a pretty detrimental bug.

16:57 stuartsierra: asteve: Look at the file. :)

16:57 squidz: the reason I like emacs is because you only have to learn emacs and you have a pretty good IDE for pretty much any language

16:58 Apage43: Squidz there should be a m after assoc-in

16:58 noncom: futile: that is very good. i know that feeling and its base. one thing i can say: keep pushing, i hope to see it someday..

16:58 asteve: stuartsierra: it is quite massive, I actually commented out two blocks of code that involved keyword and the exception was still thrown

16:58 stuartsierra: asteve: Sorry, nothing to be done but keep narrowing it down.

16:59 squidz: Apage43: right ill add it in

16:59 TimMc: stuartsierra: Ah, I see -- you may be computing a lagging view.

16:59 Thanks, that's helpful.

16:59 stuartsierra: You're welcome.

17:00 There are probably better examples I haven't thought of.

17:00 squidz: Apage43: it works! awesome thanks

17:00 Apage43: Neat!

17:01 futile: technomancy: you didn't add chicken scheme to the mix in your comparison, do you have thoughts on it?

17:01 technomancy: futile: eh?

17:01 you mean my blog post?

17:01 futile: yea

17:01 technomancy: I did actually include chicken scheme?

17:02 * futile sighs

17:02 futile: oops.

17:02 technomancy: sorry for the noise

17:02 technomancy: heh; np

17:06 squidz: Apage43: oh wait, no it doesnt, the dates still arent there

17:06 asteve: what json dep do you guys use?

17:08 technomancy: cheshire!

17:08 stuartsierra: All of them, transitively!

17:10 asteve: interesting

17:11 stuartsierra: it appears you write json.clj for clojure/data.json

17:11 stuartsierra: asteve: Yes, I wrote and, to my everlasting regret, maintain data.json.

17:11 dakrone: stuartsierra: hah

17:12 why regret?

17:12 asteve: stuartsierra: well, I'm getting "Don't know how to create ISeq from: clojure.lang.Keyword" while using data.json

17:12 stuartsierra: data.json is like the beautiful child who grows up into an angry, surly teenager who wrecks your car.

17:12 technomancy: actually I still use clj-json; I find it gives a warmer, more vibrant sound

17:12 llasram: (inc technomancy)

17:12 lazybot: ⇒ 72

17:13 stuartsierra: asteve: can you be more specific? "Using" covers a lot of ground. :)

17:13 dnolen: stuartsierra: fwiw, I don't have any problems w/ data.json at the moment

17:13 stuartsierra: dnolen: You're the first. ;)

17:13 futile: stuartsierra: what's wrong with data.json?

17:13 hyPiRion: futile: the fact that he has to maintain it, I suppose?

17:13 futile: hyPiRion: but is that all?

17:13 stuartsierra: JSON parsers are the ultimate bike shed project. They're simple enough that anybody can write one, so everybody has ideas about how to do it.

17:13 asteve: stuartsierra: right, http://pastie.org/8275157

17:14 technomancy: futile: getting yelled at by michael kishlin maybe?

17:14 futile: stuartsierra: seems like the easiest route would be to delegate the internal work to clj-json

17:14 that's what I'd do if I had to write a json parser today

17:15 just delegate to clj-json or data.json

17:15 I mean, if I had to parse some json

17:15 .

17:15 ztellman: brb writing two dozen paper-thin wrappers around other popular clojure libraries

17:15 stuartsierra: Like Cheshire delegates to a Java library.

17:16 asteve: stuartsierra: I see mention of :key-fn in the docs and I wasn't sure if that's required

17:16 stuartsierra: ztellman: :)

17:16 asteve: So what's the issue, exactly? Compile-time exception? Run-time exception?

17:16 futile: ztellman: yes, that was the joke.

17:16 asteve: stuartsierra: compile time

17:16 futile: :/

17:17 stuartsierra: asteve: If it's a compile-time error it almost certainly has nothing to do with data.json.

17:17 ztellman: futile: s/joke/brilliant idea/g

17:18 futile: quick someone slap me with a dose of humility

17:20 asteve: hmm

17:20 fighting clojure stack traces and exceptions is hell

17:21 pbostrom: https://www.refheap.com/18077 Part 1: I want to execute some side effects inside of a dosync block, this is how I would do it right? Part 2: Is it dumb to use an agent to store a closure like this, and should I use some more appropriate data structure?

17:21 stuartsierra: asteve: That code snippet compiles fine for me, with appropriate (ns … (:require …))

17:22 asteve: stuartsierra: ya, I guess that's good news

17:22 futile: Hey guys, what would be a better route for IPC? To communicate over a single socket, or to spin up a process per request/response and talk via its stdin/stdout?

17:22 asteve: (:require (clojure.data.json :as json)), looks kosher?

17:22 squidz: Apage43: I figured out that we need to add the path like [:values idx :value] and then it works

17:22 stuartsierra: asteve: No. (ns … (:require [clojure.data.json :as json]))

17:23 A "libspec" must be a vector.

17:23 hyPiRion: "must"

17:24 asteve: stuartsierra: is this a change from 1.3?

17:24 stuartsierra: asteve: No, it was always that way.

17:25 Lists are for prefixes.

17:26 lyn_: pbostrom that code looks odd to me. why do you need agents if all you're doing is side effects?

17:27 pbostrom: lyn_: inside of a dosync block, I also want to alter the ref under certain conditions

17:28 lyn_: dosync block would retry side effects if I don't use an agent

17:28 asteve: stuartsierra: thanks for the assistance

17:28 stuartsierra: asteve: You're welcome.

17:28 asteve: has http://richhickey.github.io/clojure-contrib/generic.math-functions-api.html been replaced by something in 1.5.1?

17:29 stuartsierra: asteve: That's an out-of-date URL.

17:29 clojure.github.io has latest API docs

17:30 callen: technomancy: why not cheshire?

17:30 asteve: hmm, where has log gone?

17:31 lyn_: pbostrom ah, cool technique then!

17:31 technomancy: callen: too mainstream

17:31 stuartsierra: ha

17:32 schmir: hmmm. I'm using a wrapper around tika and it's working fine when used via lein repl/lein run. but if I build an uberjar, I cannot extract text anymore. that is the extracted text is always the empty string. what could be the cause for that behaviour?

17:32 technomancy: http://wondermark.com/262/

17:32 pbostrom: lyn_: admittedly, it looks odd to me too, just confirming this is considered a best practice for this kinda thing

17:32 lyn_: pbostrom are you sure none of the side effects will be retried?

17:36 stuartsierra: asteve: You may also want to refer to http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

17:36 asteve: stuartsierra: I'm currently upgrading from 1.2 to 1.5.1, that is very useful thanks

17:37 pbostrom: lyn_: I've read that in various Clojure books I believe, but it doesn't appear to be in the docstrings for agent, send, or dosync

17:38 brehaut: technomancy: that wondermark is amazing

17:38 technomancy: brehaut: some of the early ones are hit-or-miss, but that one is solid

17:38 callen: technomancy: anybody that was an Aerosmith fan back in the day knows that pain.

17:40 brehaut: technomancy: this early hit-or-miss nature may be why i didnt think i enjoyed wondermark

17:41 callen: stuartsierra: I like how we're still suffering from clojure.contrib

17:41 technomancy: we are?

17:42 callen: technomancy: or at least the slow-pokes are :)

17:42 stuartsierra: callen: You like it because you didn't have to manage Maven+Hudson.

17:43 callen: http://i.imgflip.com/38uac.jpg

17:43 Bronsa: lol

17:43 stuartsierra: We need one of those FAQ bots like they have in #bash.

17:44 callen: we kinda have that.

17:44 you can teach the bots things.

17:44 just teach it what contrib is.

17:44 stuartsierra: clojurebot: contrib

17:44 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

17:45 callen: skip the teaching part. it already knows.

17:45 stuartsierra: Fine, but link is now http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

17:45 (There's a link at the old location)

17:45 callen: I forgot the syntax for teaching the bot :)

17:45 hyPiRion: clojurebot: forget contrib

17:45 stuartsierra: me too

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

17:45 hyPiRion: hrm

17:45 callen: clojurebot: contrib

17:45 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

17:45 callen: hyPiRion: gg

17:46 hyPiRion: callen: yeah, I know. I forgot the syntax for making the bot forget

17:46 brehaut: only hiredman remembers

17:46 bruceadams: clojurebot: help

17:46 clojurebot: Nobody can help with "X doesn't work". Please provide context: what you did, what you hoped would happen, and what happened instead. A stack trace is especially helpful, if applicable.

17:46 stuartsierra: hah

17:46 hyPiRion: clojurebot: how do I make you forget stuff?

17:46 clojurebot: Gabh mo leithscéal?

17:46 brehaut: bruceadams: the only documentation for clojurebot's syntax is the fn-parse rules

17:47 stuartsierra: It's more fun to just shout at the bot.

17:48 pjstadig: clojurebot: forget contrib |is|<reply>Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

17:48 clojurebot: I forgot that contrib is <reply>Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

17:48 pjstadig: ~contrib

17:48 clojurebot: Pardon?

17:48 brehaut: (inc pjstadig)

17:48 lazybot: ⇒ 5

17:48 pjstadig: clojurebot: contrib is <reply>Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

17:48 clojurebot: Roger.

17:48 pjstadig: ~contrib

17:48 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

17:49 callen: pjstadig: thank you...

17:49 pjstadig: np

17:49 callen: pjstadig: how do you take advantage of the reply markup to aim it at somebody?

17:49 ~contrib pjstadig

17:49 clojurebot: Titim gan éirí ort.

17:49 pjstadig: oh i don't know if that's possible

17:49 hiredman would have to answer that one

17:50 callen: balls. Aiming is nice for getting somebody's attention sometimes.

17:50 pjstadig: thanks for helping out :)

17:50 pjstadig: i think you can use <name> or something but i don't know if the factoids can take parameters

17:50 i think <name> might be the person addressing clojurebot

17:51 brehaut: pjstadig: isnt it the thing that suppresses 'X is' at the start ?

17:51 oh wait ignore me

17:51 pjstadig: brehaut: yeah that's what <reply> does

17:51 hiredman: #who

17:51 clojurebot: whoami is <reply>#who

17:51 clojurebot: You don't have to tell me twice.

17:51 hiredman: ~whoami

17:51 clojurebot: hiredman

17:51 dnolen: seangrov`: have you verified that the keyword optimization doesn't mess w/ incremental compilation?

17:52 futile: What's the best way to execute a shell task in Clojure?

17:52 ozzloy: http://hl7api.sourceforge.net/v24/apidocs/index.html shows the class ADT_A01, but i get a class not found exception with this code: https://www.refheap.com/18081 am i doing imports wrong?

17:53 rasmusto: futile: http://clojuredocs.org/clojure_core/clojure.java.shell/sh

17:53 futile: rasmusto: Is it safe to execute that in a background thread (maybe multiple in parallel)?

17:54 ozzloy: also, where does lein put the downloaded jar? i want to try to compile the java version of this: http://hl7api.sourceforge.net/xref/ca/uhn/hl7v2/examples/CreateAMessage.html

17:54 callen: technomancy: well grenchman is installed but I'm only on 2.3.2 and haven't installed from git master in ages.

17:54 rasmusto: futile: I use it with pmap, so probably :)

17:54 callen: back to looking at the code.

17:54 futile: rasmusto: yay :)

17:54 technomancy: callen: yeah, found a really stupid lein bug like two days after 2.3.2 came out

17:58 hyPiRion: callen: `git clone leiningen; cd leiningen/leiningen-core; lein bootstrap; cd ..; ln -s $PWD/bin/lein ~/bin/lein-master`

17:59 technomancy: hub clone technomancy/leiningen

18:00 callen: hub is so nice *_*

18:00 squidz: when using clojure i am getting a lot of results like '([1 2]) when I actually want [1 2]. I suppose it may have something to do with laziness? I can use first to get the result inside the list, but this seems like a hack. is there a better way to do it?

18:00 callen: hyPiRion: thanks :)

18:01 technomancy: squidz: you can destructure it out

18:01 rasmusto: squidz: it could be how you're generating the result, do you have an example?

18:02 justin_smith: sounds like you are using sequence operations on individual elements

18:02 squidz: am getting the results from a reduce

18:02 aaelony: simple question here… what's the best way to convert a date string like "2013-08-01" to milliseconds from epoch? I'm looking at clj-time.coerce/from-string but the docs are unclear

18:02 http://clj-time.github.io/clj-time/doc/clj-time.coerce.html#var-from-string

18:02 callen: technomancy: welp. that's faster.

18:02 justin_smith: squidz: the function called inside reduce has full control of the output of reduce

18:03 technomancy: callen: tried :eval-in :nrepl?

18:03 callen: technomancy: about to

18:03 aaelony: first, are you using 0.6.0?

18:03 technomancy: you will squee with joy

18:03 aaelony: i think so

18:03 squidz: the result of reduce is a map which i want to combine with another map. So I am using (vector m1 m2) is then returning ([m1 m2])

18:03 callen: aaelony: well double check your project.clj, because the advice I'm about to give you is based on the new clj-time API

18:04 aaelony: when you say epoch, did it come from an interval or a bare date?

18:04 aaelony: sorry, it's [clj-time "0.5.1"]

18:04 but I can change that

18:04 justin_smith: squidz: why the hell is vector returning a vector inside a list? that makes zero sense

18:04 callen: aaelony: you probably want to upgrade and fix any deprecated code.

18:05 aaelony: callen: I just want something that incanter knows how to use as a time series

18:05 squidz: justin_smith: yeah then I console.log that vector out together with prn-str

18:05 aaelony: callen: that's fine, but I need a simple example

18:05 callen: aaelony: interval or bare date?

18:05 justin_smith: squidz: if you want a map out of reduce, use (into {} (reduce ...))

18:05 callen: aaelony: interval is (in-millis ...)

18:06 justin_smith: squidz: it could be you are making a map with only one entry

18:06 aaelony: callen: Input is a string like so: "2013-08-01" and output would be the value in milliseconds from epoch

18:06 callen: no interval

18:06 callen: okay. pretty sure that exists, uno momento.

18:06 aaelony: my brains are a little scrambled because I refactored the API and epoch/unix millis was some of the stuff I changed.

18:06 aaelony: but that's also why using the latest version is relevant.

18:07 because some of the epoch stuff didn't exist before my PR

18:07 aaelony: callen: cool… i see.

18:07 justin_smith: squidz: err... wait, you can make a reduce return a map, if for some reason a seq of entries is more convenient, then use the into trick above instead

18:07 aaelony: callen: basically something that would do this (http://jakemccrary.com/blog/2010/02/21/plotting-time-series-data-with-incanter/) in a currently appropriate way

18:07 squidz: justin_smith: here is my code https://www.refheap.com/18083

18:08 aaelony: callen: is there still a to-ms function

18:08 squidz: the bottom of that function is what is supposed to return the vector

18:08 justin_smith: squidz: ,(reduce (fn [m [k v]] (assoc m k v)) {} (partition 2 (range 8)))

18:08 callen: aaelony: you probably want to-long, it converts the object to the number of milliseconds since unix epoch from the date object provided.

18:08 justin_smith: ,(reduce (fn [m [k v]] (assoc m k v)) {} (partition 2 (range 8)))

18:08 clojurebot: {6 7, 4 5, 2 3, 0 1}

18:09 jzelinskie: that's a nice bot

18:09 callen: aaelony: user=> (coerce/to-long (time/now))

18:09 1377639995556

18:10 aaelony: callen: perfect! thanks :)

18:10 callen: (timec/to-long "2013-08-01") ==> 1375315200000

18:11 justin_smith: ,(.getTime (java.util.Date.))

18:11 clojurebot: 1377640105272

18:11 callen: aaelony: excellent. cheers :)

18:11 justin_smith: less libs

18:11 callen: justin_smith: the reason for clj-time is the protocols handle auto-projecting across type relationships for various possible inputs.

18:12 aaelony: justin_smith: that doesn't work with a date string though

18:12 callen: justin_smith: that's the automagic that turns his string into what he needs.

18:12 aaelony: justin_smith: e.g. (.getTime "2013-08-01") fails

18:12 callen: justin_smith: normally I'd agree with you, but look more carefully at the example. :)

18:12 aaelony: callen, justin_smith: big thanks nevertheless. What's a good way to provide these examples to the API docs?

18:13 callen: aaelony: sorry, provide these examples?

18:13 aaelony: (I know I'll forget and need to look it up in the future)

18:13 callen: aaelony: do you want to contribute to clj-time's documentation or do you mean something else?

18:13 aaelony: callen: (timec/to-long "2013-08-01") ==> 1375315200000

18:13 callen: aaelony: right, but I'm asking you where you want it to live.

18:13 I can find a home for it if you want.

18:14 aaelony: callen: ah, well google founjd me this… http://clj-time.github.io/clj-time/doc/clj-time.coerce.html#var-from-string so maybe there?

18:14 callen: aaelony: nuh uh, that's auto generated. I'll put it in the readme, I know where it should go.

18:14 aaelony: callen: sweet

18:14 callen: thanks again

18:16 justin_smith: squidz: double check that you are actually binding super to a hashmap and not a vector?

18:17 squidz: style wise, I suggest more functions, that are small, and simple, and easy to verify as being correct in a repl or unit test

18:17 squidz: yeah i thought the same about more smaller functions, thanks for the tips

18:17 callen: technomancy: keeps closing the socket and dying on me :(

18:21 technomancy: callen: which socket?

18:22 grench->lein or lein->project?

18:30 dobry-den: So Github recognizes CoffeeScript but considers ClojureScript to be JavaScript. :(

18:31 Cruel world

18:32 futile: aww

18:32 dnolen: dobry-den: hmm really?

18:32 futile: dobry-den: to be fair, its actually just javascript files and clojure files

18:32 :)

18:33 dnolen: dobry-den: in what context are you talking about? GitHub has identified .cljs for a while now. Though I think they just lump with Clojure. ClojureScript repo says 97% Clojure.

18:38 cgag: if you check in your compiled javascript it's probably giving your project credit for 20k lines of javascript

18:40 futile: If I spin up an external process via clojure.java.shell/sh, write to it, read to it, and shut it down, about a dozen times per second, is that going to be slow? Would it be significantly slower than opening up a unix socket and sending/receiving the same amount of messages on the same socket in the same time frame?

18:43 ucb: what sql library do you recommend? I've only looked at clojureql so far

18:43 justin_smith: in swank repl buffers in emacs, hitting tab inside a string would path-complete filenames - how hard would it be to make nrepl do this? is it just an option I need to turn on?

18:43 TakeV: One has to define a protocol in order to give a deftype functions, right? You can't just define functions that aren't in a protocol you specify?

18:45 callen: I need an alfred plugin that lets me quickly bring up github repos.

18:46 aaelony: https://github.com/clj-time/clj-time#clj-timecoerce

18:48 feck it, alias.

18:48 er, function.

18:57 dobry-den: dnolen: you're right. interestingly despite removing my .js build file, it still reported Javascript 99.6% for days until just now when I made an 'update README' commit

18:57 now it reflects Clojure 99.6%

18:58 `cbp: mmm why does (round (/ 5 3)) return a BigInt in clojure.numeric-tower

18:59 dobry-den: dnolen: man, i ended up getting my app to a working state using your core.async snippet as inspiration (the start/stop/scrub app). this is great

19:00 `cbp: does anyone have non-nuts round lying around? =P

19:03 oh ##(type (.numerator (/ 5 3)))

19:03 lazybot: ⇒ java.math.BigInteger

19:03 `cbp: well..

19:03 hyPiRion: that's not what round does though

19:04 `cbp: hyPiRion: round does (quote (.numerator..) (.denominator..))

19:04 hyPiRion: quot, yeah.

19:04 `cbp: hyPiRion: I mean thats what floor and round uses floor

19:04 yeah quot =P

19:05 hyPiRion: ah, right

19:05 `cbp: that's what floor does*

19:07 callen: technomancy: Exception in thread "nREPL-worker-0" java.net.SocketException: Socket closed

19:07 oh you know what, it was closing after that exception before, but it seems to be okay now.

19:07 weird.

19:11 hyPiRion: callen: That's probably technomancy/leiningen#1288. I suspect it is because REPLy/Leiningen thinks the connection is still open.

19:11 lazybot: lein repl crashes whenever shut down -- https://github.com/technomancy/leiningen/issues/1288 is open

19:13 ozzloy: in case anyone was wondering, hapi is broken into several libs and i didn't include all the ones necessary for the thing i tried earlier

19:13 oh woops, i'm in scroll back

19:17 technomancy: callen: there are still several nasty edge cases and ways to get it wedged

19:18 but it sounds like restarting fixed it?

19:18 callen: technomancy: aye, it did.

19:18 technomancy: cools

19:18 callen: technomancy: I'm working on something that does involve doing `lein run` over and over, so this came at a good time.

19:19 something even faster would be cooler still, but that's my fault for relying on :main to test this library.

19:19 technomancy: callen: cool; so you won't be bitten by the stdin issues

19:19 callen: I should just move to tests so it's instantaneous.

19:19 technomancy: nah this is just my SQL logging library.

19:19 I just run queries and see colored output, that's all.

19:19 technomancy: callen: re: "something faster" is that orthogonal to Leiningen/Grenchman?

19:20 callen: aye, it'd mean moving from :main to writing tests and using (refresh) and (run-tests) in a REPL.

19:20 technomancy: I mean, with :eval-in :nrepl, does the tooling introduce any overhead still?

19:21 callen: I see - grench eval '(:status (my.web/app {:uri "/"}))' - what do you mean by :eval-in :nrepl?

19:21 hyPiRion: callen: that's :eval-in :nrepl.

19:22 technomancy: callen: by default `grench eval ...` will skip starting a new lein jvm, but it will start a project JVM

19:22 you can set :eval-in :nrepl to jump straight from lein's resident JVM to a running project JVM

19:22 callen: sadly I have to go to a meeting, I'll tinker with it after I get settled in my airbnb room tonight.

19:23 technomancy: k

19:33 aaelony: callen: that's awesome, thanks :)

19:44 mihneadb: hi, I'm having trouble with some big collections, out of heap. I'm not handling them correctly

19:45 https://www.refheap.com/18087

19:45 (basically I want to walk a directory structure and download some many files)

19:45 could someone please help me with the looping part?

19:45 amalloy: mihneadb: don't def a top-level var to hold a lazy sequence. keep it locally-bound only

19:46 mihneadb: amalloy: could you also tell me why, please?

19:46 amalloy: because it can't get GCed ever, if you hold a pointer to the start of it: you threaten to reuse the sequence

19:47 mihneadb: aha

19:47 but in my case that is not the problem, right?

19:47 amalloy: now here, it doesn't look like inbound-dirs is very large, so that's probably not a problem

19:47 it's just the only thing that leapt out at me as a memory issue

19:47 mihneadb: ah, ok

19:47 amalloy: problem is the space is pretty big

19:47 I mean.. the search space

19:48 but doseq does not retain the head of the seq, so I'm confused

19:48 any ideas?

19:49 amalloy: you're holding a single file all in memory at once; if any one file is very large that would be a problem

19:49 mihneadb: amalloy: you mean when I'm saving it to disk?

19:49 amalloy: yes

19:49 otherwise, nothing jumps out at me and i'm afraid i don't have time to look harder

19:49 konr`: How can I catch assertions that fail?

19:50 mihneadb: amalloy: ok, thanks. it downloads a few files just fine it seems

19:50 so it shouldn't be that

19:50 amalloy: fwiw it seems to have crashed at the 2nd step of the inner doseq

19:51 konr`: ... (catch Throwable e ...

19:52 brehaut: mihneadb: minor style thing, and maybe i am mistaken, but i think your two doseq's can be flattened into one. more minor style thing: aliasing str to join is a bit gross. a typical 'join (such as the one in clojure.string) function has different semantics to str

19:53 mihneadb: brehaut: thanks, I had no idea

19:53 brehaut: how could I do the two doseqs in just one?

19:53 brehaut: (doseq [as foos b as] (do-whatever b))

19:53 seangrov`: dnolen: No, I'm pretty unclear on how incremental compilation works (I've never had it work for me in a year of using cljs fulltime), but from my understanding it should work

19:53 mihneadb: brehaut: thanks!

19:54 this kind of is my first real clojure program.. so any hint helps

19:54 brehaut: ,(for [a [[1 2 3] [4 5 6]] b a] (inc b))

19:54 clojurebot: (2 3 4 5 6 ...)

19:54 seangrov`: We write out a contants_table.js to a file (in the specified :outputdir), and that file will only change if there's a new constant added to the table, which should only be for new keywords if the incremental compilation is run in the same continual process

19:55 mihneadb: brehaut: but in my case I have to call a function

19:55 brehaut: ,(for [a (range 3) b (range a)] b)

19:55 clojurebot: (0 0 1)

19:55 brehaut: ha

19:56 mihneadb: nice

19:56 thanks

19:56 brehaut: any idea what's causing my memory problem?

19:56 brehaut: i think amalloy's guess is the most likely

19:57 mihneadb: brehaut: size of the file?

19:57 brehaut: sucking everything into a byte-array and then spitting that out is not really the best way to go about it

19:57 mihneadb: brehaut: it downloads the stuff in the first encountered folder fine, it crashes when it reaches the 2nd. if I only have one file in memory at a time, this doesn't seem to be the problem

19:57 nevertheless, how should I go about that download?

19:58 brehaut: well, its the middle of my work day, so i dont really have time to go and spelunke your program

19:59 srruby: I'm using gvim. I like to often re-indent the file using gg=G However it is very slow. Any ideas how to speed it up?

19:59 mihneadb: brehaut: ok, thanks for the doseq tips

20:02 dnolen: seangrov`: basically the constant table should always be emitted, I'll verify

20:03 seangrov`: That may be the problem I was getting, it was complaining that there was no .repl/constants_table.js every now and then (though working most of the time)

20:06 coventry: Could someone please tell me the right way to say "(seq dm)" in this macro? <https://www.refheap.com/18088> I'm not sure I understand the error message, either. What's with the map wrapping 'dispatch' in '{:instance dispatch}'?

20:08 amalloy: coventry: you can't write this macro this way. it's depending on the "runtime" value of dispatch, but generating code at compile time

20:08 ie, defdispatch only sees the symbol 'dispatch, not a map with the keys 1 and 2

20:09 (defdispatch foo {1 :foo 2 :bar}) would work fine

20:10 coventry: Oh, I need the dreaded double backtick?

20:11 Thank you.

20:11 amalloy: what. on

20:11 no

20:11 seangrov`: hah

20:11 amalloy: you simply cannot write a macro that takes your input and produces your desired output

20:12 (modulo the use of eval, which is evil and not a good solution)

20:13 mihneadb: amalloy: I set -Xmx1g and it 'works', but it's definitely hogging memory, its memory usage is just increasing. one file won't be larger than ~1 MB, and it is my impression that I'm holding only one in memory at a time

20:13 coventry: Thanks, I will think about it some more.

20:15 seangrov`: coventry: If the dispatch won't change at runtime, you can just pass it directly to your macro

20:15 e.g. (defdispatch foo {1 :foo 2 :bar})

20:16 amalloy: seangrov`: sure, but that's not really much better than just writing (defn foo [x] (case 1 :foo 2 :bar nil))

20:16 i'd prefer the latter, personally

20:17 seangrov`: amalloy: Never miss a chance to use macros

20:18 callen: Axis of Eval

20:18 Over-reliance on eval is the sign of a weak mind.

20:18 ddellacosta: I want to set the log level for a 3rd party Java lib (which uses log4j/slf4j), on the level of granularity of "just my tests," and not sure how to go about it--is there a simple programmatic way to do this? </java moron>

20:19 would rather avoid properties files, but if that is best practice even for Clojure will do it.

20:21 wow, I just killed the conversation on #clojure with that one.

20:22 Raynes: ddellacosta: Just give up and use properties files.

20:22 * ddellacosta looks awkwardly at his feet as people cough nervously

20:22 callen: ddellacosta: hrm. good question. Most Clojure libraries/apps I've seen use properties files in their resources to add a filter for any logline not coming from your tests

20:23 ddellacosta: and then the log handler in the tests has a special prefix or something.

20:23 Raynes: If you try to make Java logging libraries do what you want, you're going to end up bloody and naked in the fetal position in the corner of a dark room.

20:23 callen: ddellacosta: that's more speaking to a pattern than defining what I think is truly an optimal solution though. If you find something better, speak up.

20:23 also, Raynes is right.

20:23 ddellacosta: Raynes, callen: yah, I may be resigned to that. Honestly not sure the best way to handle it. Any experiences with clj-logging-config?

20:23 Raynes: heh

20:24 callen: haven't used that lib, let me know how it goes >:)

20:24 ddellacosta: alrighty then, there but for the grace of god go I

20:33 coventry: amalloy, seangrov`: Are compile-time evals a bad choice for this kind of thing, too?

20:35 ddellacosta: that's hilarious--I added the clj-logging-config lib, ran set-logger! in my test setup, and now it's added logging messages telling me it is setting the log level, but doesn't seem to be making anything else quieter. *sigh*

20:40 callen: ddellacosta: if you look at the code for clj-logging-config, you might at least get an idea of the intent behind how it *should* work and how you might be able to reproduce what you want manually.

20:41 ddellacosta: callen: yes, you're absolutely right, I'm being lazy because this is not what I should be spending time on. I have to make the choice as to whether to really dig into it and learn how it works, or skip this for now and suffer through the noise. Choices, choices

20:42 callen: ddellacosta: I understand the desire to skip past the bits that don't directly contribute to the actual goal, but sometimes wiping the slate clean and reapproaching with an open zen mind and a desire to learn takes less time than thrashing.

20:42 modulo yak shaving :)

20:43 ddellacosta: callen: haha. Yep, all true and good points.

20:43 callen: ddellacosta: and I meant it when I said I wanted to hear how it went, because this is something I've bumped into but side-stepped before. There may come a day when I cannot judo my way past the problem and anything you learn could be valuable.

20:43 I'm working a logging library right now, although it doesn't currently touch any Java infrastructure.

20:44 ddellacosta: callen: alright, now you're giving me work to do! ;-)

20:44 callen: I just want to know how your problem resolves in the end, that's all.

20:44 ddellacosta: callen: seriously though, I've been putting this off for a while, so point taken and I think I'll dig into it. Here we go, will report back!

20:52 mihneadb: what's the 'idiomatic' way to download a file via http?

20:52 I found multiple ways on SO :s

20:57 technomancy: mihneadb: if you can, use slurp

20:58 otherwise maybe a line-seq on clojure.java.io/reader

20:58 otherwise clj-http

20:58 mihneadb: technomancy: would slurp work ok with binary files too?

20:58 technomancy: oh, no.

20:58 mihneadb: technomancy: I'm trying to write a scraper that downloads some logs that are gzipped text files

20:59 I'm having memory trouble

20:59 (tried with clj-http)

20:59 technomancy: clojure.io.java/input-stream might work though

20:59 mihneadb: technomancy: I don't find how to use it in the docs

20:59 technomancy: if it's memory trouble then you need to just stream it lazily

21:00 mihneadb: technomancy: so the files themselves are no bigger than 1MB from what I've seen, but I think my program is 'leaking'

21:00 technomancy: https://www.refheap.com/18089

21:01 callen: people in here that make private vars, please raise your hands.

21:01 in libraries.

21:01 technomancy: callen: obvs?

21:02 callen: technomancy: I want them to raise their hands so I can cut them off.

21:02 keep 'em high people.

21:02 I'm side-stepping it in the usual way, but I'm still mad.

21:02 technomancy: yeah, being able to change implementation details without breaking all your downstream consumers is such a waste of time

21:03 people should just get used to the fact that software changes, you know?

21:03 coventry: callen: How do you sidestep it? I am running into that problem.

21:03 callen: technomancy: fair point, but I'm already deep in alter-var-root land.

21:03 implementation details are sort of the point in my case :)

21:03 technomancy: well, at least you won't be surprised when a new version breaks your code then

21:04 callen: technomancy: again, sorta expected.

21:04 technomancy: it's a SQL logging library, nothing I can do about it. tracking c.j.j is the point.

21:04 I'll have version lists with their corresponding c.j.j/korma versions in the README

21:07 muhoo: i generally run away screaming from things that are opinionatedly stateful.

21:07 mihneadb: technomancy: can I open the URL as inputstream and then use io/copy to download it to a local file?

21:07 technomancy: mihneadb: yeah, that should work

21:07 should be buffered

21:07 just be sure to use with-open

21:08 callen: muhoo: it's not about state, it's just that there's no way to write a SQL logging library without deeply integrating it into the library you're logging.

21:08 mihneadb: technomancy: with-open just for the input stream, for the output I can pass in (io/file my-path) to copy, right?

21:08 callen: muhoo: and it's not "stateful", the alter-var-root is for run-once decoration of behavior AOP style, not for ongoing stateful mutation.

21:09 it's not my fault Clojure hasn't figured out how to do metaobject protocol stuff yet.

21:09 there were established patterns for this in Common Lisp, here in the land of clj, I have to hack it up with alter-var-root.

21:09 when somebody has an alternative, I'd love to hear it.

21:10 mihneadb: technomancy: like https://www.refheap.com/18090

21:10 ?

21:14 swarthy: Is it possible to set 'let' bindings around multiple arity function definitions?

21:14 hyPiRion: swarthy: sure thing

21:14 not different arities though, but the function itself

21:14 swarthy: I see, I have a var that I would like in all the arities within the function. I must be trying to do something wrong, I'll try something else.

21:16 hyPiRion: well, (let [val :the-val] (defn foo [a b] (str val a b))) should work fine

21:16 swarthy: Is that considered in bad taste? I'm fairly new to clojure.

21:18 `cbp: closures are never bad taste

21:22 hyPiRion: relatively. One can do (def ^:private val :the-val) before the defn instead to achieve the same result (except it'll be visible for all other functions in the namespace too)

21:22 swarthy: I see, thanks for you input hyPiRion.

21:22 your*

21:22 hyPiRion: np

21:22 justin_smith: at least in cl, function definitions inside let are the normal way to make private data, especially if multiple definitions need that same binding but others should not see it

21:22 but I tend to see suspicion about def / defn that is not at the top level in clojure (maybe just because it is so often misused by people just starting)

21:22 swarthy: justin_smith: could you elaborate on that last point?

21:22 `cbp`: you could do (def f (let '

21:22 oops

21:22 justin_smith: swarthy: people use def inside a function because they don't know how to use let for example

21:22 `cbp`: (def f (let [..] (fn ..)))

21:23 justin_smith: but defining something inside a let is pretty much the oposite

21:23 callen: `cbp`: well, "never". Don't say that. I'll take it as a challenge to be an asshole and do something monstrous.

21:23 But closures are often in good taste :)

21:23 swarthy: justin_smith: excellent thank you.

21:23 justin_smith: one issue is that if the let has side effects, you then have side effects at load time

21:23 so really you need something like (defn init [] (let [] ... (defn ...))) or else loading the file is not idempotent

21:24 unless you are certain nothing inside the let has side effects

21:24 that case of course calls for calling (init) before using the namespace

21:24 non-idempotent namespace load is evil

21:25 futile: the jvm doesn't fit into the unix philosophy of things that play well-ish together

21:25 justin_smith: unix is just designed with everything implementing the same protocol

21:25 swarthy: justin_smith: you have kind of lost me lol.

21:25 justin_smith: on that last part

21:25 callen: justin_smith: don't...don't use the words unix and design in the same sentence.

21:25 justin_smith: hah

21:25 callen: justin_smith: it's misleading and sets people up for disappointment.

21:26 it grew like a tumor.

21:26 I say that despite rather liking unix, but lets be honest.

21:26 justin_smith: swarthy: regarding why non-idempotent namespace load is evil?

21:26 swarthy: yeah, or rather how to avoid it.

21:27 justin_smith: when loading a namespace has side effects, you get weird bugs, it is almost guaranteed

21:27 swarthy: what kind of side effect would be common

21:27 again, I'm very new to clj and java

21:27 justin_smith: any code that is affected by the order it is evaluated and not just the content of its arguments should be explicitly called in an init function of some sort

21:27 so if you are setting the contents of an atom

21:28 or updating it

21:28 or creating a file

21:28 or reading it

21:28 etc.

21:28 swarthy: Okay, what about the case where the ns has a 'top level' function that reads a file but only after being called and with some args, not bound with a def, etc?

21:28 justin_smith: defonce helps with that as well

21:28 swarthy: is that still a smell

21:29 justin_smith: swarthy: that is fine, you just don't want code outside a function that has side effects that happen at load time

21:30 but someone who has been burnt by those bugs before will slow down and look twice at top level forms that are not definitions

21:30 swarthy: I see thank you, very educational.

21:30 justin_smith: so that can affect readability

21:32 np, I'm just someone who made mistakes so knows what not to do now

21:32 (and dealt with others' mistakes, etc.)

21:34 mihneadb: what's the best way to parallelize a doseq expression?

21:34 callen: swarthy: maintaining idempotent namespace loading is advisable in Python too.

21:35 swarthy: this isn't just specific to Clojure.

21:35 coventry: Hmm, the twelth google result for "point lein to source-code for a library" was "Let me google that for you".

21:35 callen: coventry: ouch.

21:35 swarthy: I see thank you callen.

21:36 coventry: callen: I'm not hurt, personally. :-)

21:38 TimMc: mihneadb: So this would be a case where the bulk of the work is in the body of the doseq, not in the sequence generation itself? (Otherwise it definitely can't be parallelized in the general case.)

21:38 mihneadb: TimMc: yes, I want to run the body in parallel

21:38 I'm thinking of switching to pmap

21:38 + dorun

21:38 TimMc: would something else be better?

21:38 TimMc: pmap is apparently trouble

21:39 mihneadb: :) why?

21:39 TimMc: I'm not sure, it's just the common wisdom of the channel.

21:39 I don't do much with performance-sensitive concurrency, so I haven't listened too closely.

21:40 cgag: pmap's worked ok for me in the past

21:40 mihneadb: I see

21:40 I'm basically trying to donwload a bunch of logs and I figure I can download independent folders in parallel

21:41 cgag: maybe this is a use case for core.async?

21:41 mihneadb: cgag: does core.async spin off different threads?

21:41 cgag: create a bunch of go-blocks putting results in a channel?

21:42 mihneadb: I'll have to read about it

21:42 thanks!

21:42 (for the record pmap seems to work)

21:42 TimMc: I haven't seen anything useful in a quick search of http://clojure-log.n01se.net/, let's try the bot:

21:42 ~pmap

21:42 clojurebot: pmap is not what you want

21:42 cgag: yeah the go blocks are basically realy light weight threads as i understand it, multiplexed onto a smaller thread pool

21:43 mihneadb: cgag: nice, thanks

21:43 TimMc: I don't know why I thought that would be useful. :-P

21:43 mihneadb: I'll definitely check it out

21:43 clojurebot: ++

21:43 clojurebot: Excuse me?

21:44 cgag: mihneadb: i'm just throwing this out there, i don't really know for sure

21:44 mihneadb: right

21:45 thanks anyway :) might be what I need

21:45 TimMc: From 3 years ago: "amalloy: rplevy: the main issue is that pmap needs to be given a smallish number of large tasks in order to be useful, because it spawns a thread for each task"

21:45 That may no longer be true, though. Perhaps it uses threadpools.

21:46 cgag: i was pretty confident it does use a thread pool

21:46 of #cores + 2

21:46 futile: Anyone wanna help me come up with a really simple-to-use-from-the-client-side IPC technique?

21:47 TimMc: futile: Well, first you generate a WSDL, and then...

21:47 futile: ahhhh!!!

21:47 ruunnnn!!!!

21:47 oh sorry

21:47 TimMc: Oh, wrong channel. I thought I was in #lovecraftian-horrors-for-programmers

21:47 futile: :D

21:48 egghead: futile: you could use the zeromq async thingy for ~inter process communication~

21:49 https://github.com/lynaghk/zmq-async if all you really need is for two processes to pass messages between one another that looks like a fun way to do it

21:49 s/two//

21:50 TimMc: mihneadb: So yeah, it looks like pmap is reasonable if each task is relatively heavyweight.

21:50 mihneadb: TimMc: I see

21:50 thanks

21:50 I read that it used thread pools as well

21:51 cgag: would it be a terrible idea to just create a ton of futures?

21:51 mihneadb: I don't know

21:52 davertron: I'm running into an issue with :advanced compilation with clojurescript: I'm using google maps, so I pass a function as a callback to its event handling. The event object that gets passed to the function has a LatLng property with lat() and lng() method calls, but these method calls get munged by the advanced compilation. How do I tell the closure compiler not to munge these?

21:53 TimMc: cgag: Then you'd have to do all the coordination yourself. :-P

21:53 mihneadb: The source agrees.

21:53 mihneadb: :)

21:55 TimMc: Wait... it *does* call future.

21:55 cgag: what coordination? just spawn them all and map deref over them

21:55 dobry-den: davertron: i can't answer your question but i'd look here: http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html and https://github.com/emezeske/lein-cljsbuild/blob/master/sample.project.clj

21:55 TimMc: cgag: I don't think that gets you parallelization.

21:56 callen: SQL query logging library. Do I print arguments as well as the queries, or just the queries?

21:57 cgag: it would, i'm just not sure if it would create an absurd number of threads

21:58 creating a bunch of go-blocks feels right, but i'm not sure how you wait on them all to finish though

21:58 also i guess it wouldn't work if you need to get the results in a specific order

21:58 callen: cgag: by waiting on them to finish sending things through channels and then close the channels?

21:59 davertron: dobry-den: Thanks, I've read that first link and i'm using an extern, but unfortunately this is a callback that receives an object with specific methods on it, so there's no way to declare that object in the extern (that I know of). The sample.project.clj doesn't really provide anything beyond what I'm currently doing

21:59 callen: cgag: I'm pretty sure coordinating things with core.async centers around channels.

21:59 TimMc: cgag: Ah, so you're thinking (map deref (doall (map spawn-future xs))) ?

22:00 cgag: i imagined having one channel that each block would push its result into

22:00 TimMc: yeah

22:00 TimMc: it feels like a bad idea but i'm not sure why or if it actually is

22:01 TimMc: It would suck for a large (count xs).

22:01 cgag: doesn't it use a thread pool though?

22:01 TimMc: I thought that future used a thread pool, but the doc doesn't mention that...

22:02 mihneadb: TimMc: I'll bother you with one more question

22:02 I'm having trouble with lein uberjar

22:02 as in.. I get java.lang.NoClassDefFoundError when I try to run the jar

22:02 TimMc: You need some AOT up in there.

22:02 mihneadb: I did add (:gen-class :main true) to the core ns

22:02 TimMc: ahead of time? what?

22:03 TimMc: Just a (:gen-class) is fine, but yeah, you need to tell lein to compile that ns Ahead Of Time as well.

22:03 egghead: are you guys implementing pmap

22:03 mihneadb: TimMc: how do I do that/

22:03 TimMc: So that's :aot [my.core.ns] in your project map.

22:03 mihneadb: oh

22:03 ok

22:03 ty

22:04 TimMc: That will AOT all your namespaces transitively, so I wrote lein-otf if you want to restrict it to a little stub loader class.

22:04 mihneadb: TimMc: thanks. seems to have worked

22:04 it's enough for my current knowledge/reqs

22:04 TimMc: (Useful if you need to avoid AOT for some reason.)

22:07 mihneadb: TimMc: ok, all works. Would you mind taking a look and offering some style suggestions maybe?

22:08 `cbp`: i use (->> coll (map #(future..)) (doall) (map deref) (doall)) so much i feel there should be a macro for it or something :P

22:08 TimMc: I can't tonight, but someone else may be able to if you put it up on a pastebin (refheap or gist are preferred.)

22:10 `cbp: futures use the same threadpool as agents

22:11 mihneadb: TimMc: ok, thanks

22:11 style advice welcome - https://www.refheap.com/18091

22:20 * devn sits down and begins hammering out a SASS library for clojure

22:21 TimMc: devn: ITYM "JAJJ".

22:21 devn: compass is so nice for writing cross-browser CSS

22:21 really wish the ruby dep wasn't necessary

22:27 dnolen: seangrov`: tweaking your patch, there's a lot of related stuff that needs fixing, and the changes are bad for the REPL, needs be addressed. Still thanks for laying down the ground work this is the easy stuff.

22:31 callen: `cbp: write the macro, then submit a PR to flatland/useful.

22:40 seangrov`: Uhg, the dreaded Caused by: java.lang.RuntimeException: Unmatched delimiter: )

22:40 But in which file...

22:41 amalloy: seangrov`: look higher in the stacktrace

22:41 the exception message includes the file/line it was reading, think

22:42 seangrov`: Ah, yes, the file, but not the line

22:42 But that's enough for now, I suppose

22:42 I feel like it should be somewhat possible for the cljs compiler to give a hint about the location

22:42 amalloy: oh, the cljs compiler

22:43 perhaps that's why you don't get a line number; i'm reasonably sure the clj-jvm compiler includes it for mismatched delimiers

22:44 `cbp: I wonder which branch should i use, theres no readme or contribute :P

22:45 develop i guess

22:45 dnolen: seangrov`: we can fix this now - tools.reader can do this

22:45 seangrov`: if tools.reader tells us where reading failed we should print it

22:45 seangrov`: dnolen: That's what I was thinking

22:46 I can look into doing that, should be a few lines or less of change, right?

22:48 amalloy: `cbp: i don't want that macro anyway; useful already has too many bad functions for walking through collections on multiple threads

22:49 `cbp: aw =P

22:49 time to start compiling my own utils lib

22:50 amalloy: an activity i encourage, although i gather some people frown on it

22:51 `cbp: what do they have against it?

22:52 amalloy: well, https://groups.google.com/forum/#!topic/clojure/WuS31RSiz_A is one stance

23:20 Acio: where can i find the valid function name characters?

23:21 dnolen: OK breaking ClojureScript change around keywords - http://github.com/clojure/clojurescript/commit/2e8b32aa28399c69500e511377b1841a6679c9f2

23:21 that cleans up a lot of messes that have lying around for 2 years

23:21 please test this branch

23:21 seangrov` and others

23:23 it does seem to work lein cljsbuild just fine, I'll have to save performance testing and similar things for tomorrow.

23:23 bbloom: dnolen: oh boy oh boy oh boy :-)

23:23 dnolen: sooo close to composite constants too!

23:23 dnolen: bbloom: very, just a few more tweaks

23:57 seangrov`: dnolen: Will check tonight or tomorrow

23:59 bbloom: how evil is it on the JVM to dynamically create lots of types at runtime?

23:59 i know this is a question that will make you say "wtf do you want to do that for?"

23:59 Raynes: bbloom: wtf do you want to do that for?

23:59 bbloom: *sigh*

Logging service provided by n01se.net