#clojure log - Jan 19 2014

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

0:04 marcopolo`: ggherdov: the clj-webdriver is pretty nice. It's a layer on top of selenium

0:04 You can also use phantomjs as a webdriver for headless stuff

0:09 ddellacosta: ggherdov: I've done some testing with clj-webdriver, it works reasonably well but is still young. Lately I've been considering moving to something wholly removed from clojure however, as this is so nice to work with: http://sebuilder.github.io/se-builder/

0:10 ggherdov: for high-level acceptance tests it's pretty amazing. For everything else, I use clojure.test/clojurescript.test.

0:11 cark: is there some automated re-testing thing for clojurescript ?

0:11 ddellacosta: cark: what is re-testing?

0:12 dsrx: regexp-testing? :p

0:12 cark: i mean automated, when the code/compiled js changes

0:12 ddellacosta: cark: if you are using midje, autotest is built in. With clojure.test, you can use prism: https://github.com/aphyr/prism

0:12 cark: and that works with clojruescript ?

0:13 ddellacosta: cark: not sure about expectations, but maybe it has a similar mechanism. Re: clojurescript, I don't know--I haven't tried prism with clojurescript.

0:14 cark: i'll check it out

0:15 dsrx: cark: do you already have cljs tests, and you want to re-run them?

0:15 er, auto-run them when your src files change

0:15 marcopolo`: cark: if you are using clojurescript.test you can add your tests to your cljsbuild

0:16 cark: not really, but i'm starting to feel i need some tests, and would not do that with some automated way to do it

0:16 without*

0:16 i usually do unit test only for low level data structure code

0:16 "low level"

0:17 we're still talking clojure =P

0:17 ggherdov: thanks ddellacosta

0:17 ddellacosta: ggherdov: np

0:18 there is also https://github.com/reiddraper/simple-check which I haven't tried yet, I guess it is inspired by Haskell's quick-check.

0:18 er, QuickCheck

0:18 ggherdov: bookmarked :)

0:20 cark: marcopolo`: yes looks like cljsbuild can help with the building of tests, maybe a short library that reloads the js could be done quite quickly..thanks

0:23 marcopolo`: reloads?

0:23 ggherdov: marcopolo`: forgot to thank you for your reply above -- doing it now :)

0:23 cark: marcopolo`: i don't want to launch a browser each time the code changes, i want to see the result as fast as possible

0:23 marcopolo`: ggherdov: no worries :) you're welcome

0:26 cark: gotcha, I think it uses phantomjs

0:26 ddellacosta: se-builder is really cool! thanks for that

0:26 (inc ddellacosta)

0:26 lazybot: ⇒ 1

0:27 ddellacosta: marcopolo`: your welcome. :-) I really love it, it saves me so much time...

0:27 *you're

0:33 dsrx: hmmm i wonder if you can use karma with cljs

0:33 easily, I mean

0:34 marcopolo`: karma?

0:34 jeremyheiler: dsrx: you'd at the very least need to swap out the jdbc lib for a js lib

0:34 dsrx: errrr

0:35 i don't mean the clj library, i mean the js test runner :)

0:35 sorry, very confusing

0:35 jeremyheiler: oh, hah

0:37 marcopolo`: is there such thing as cljsbuild hooks? Like a command to run after a build?

0:37 dsrx: marcopolo`: it runs your tests in a bunch of targets (local or remote browsers) and aggregates your results in a CLI, so very handy for CI builds

0:37 or if you want to run tests on a mobile device for example

0:38 marcopolo`: hmmm, I'll look into it

0:44 egghead: dsrx: you can run arbitrary commands for your cljsbuild tests if you want

0:44 I was doing phantomjs for a while for example

0:45 https://github.com/emezeske/lein-cljsbuild/blob/master/doc/TESTING.md

0:46 dsrx: oh hm nice, thanks egghead

0:47 marcopolo`: can you have it always run tests after a compile

1:33 arrdem: is there a good library for running agents on other hosts?

1:33 I see technomancy's die-roboter, but that seems to be the only remotely capable thing

1:59 bitemyapp: arrdem: wryyyy

2:02 arrdem: bitemyapp: I realized what I had done only after hitting enter...

2:05 bitemyapp: "arrdem and agents": http://i.imgur.com/0OQRtBb.jpg

2:10 arrdem: bitemyapp: lolz

2:20 bitemyapp: oh MAN

2:20 arrdem: React.js is practically made for a typed language!

2:21 this is gonna be GREAT

2:21 * bitemyapp cackles madly

2:24 arrdem: bitemyapp: if it's any cosolation we lost the two games you missed

2:24 bitemyapp: tidehunter can just get out

2:25 bitemyapp: arrdem: tidehunter is good ban. Game is hard.

2:32 arrdem: evidently tonight is my night for exploring two year old libraries..

2:32 bitemyapp: arrdem: revise isn't two years old! You take that back!

2:33 arrdem: bitemyapp: I didn't start using that tonight now did I. that was last night

2:36 screwit. I'm just gonna run my own remote worker solution.

2:39 bitemyapp: arrdem: the rabbit hole is widening to accommodate your sanity.

2:39 arrdem: bitemyapp: <od>you're insane</od>

2:41 bitemyapp: Documentation for allowed element and attribute types isn't clickable in React.js documentation. MFW

2:42 However, when there is only a single child, this.props.children will be the single child component itself without the array wrapper. This saves an array allocation. -- Without sum types? you're braver than I thought guys.

2:48 arrdem: okay. do I go with an aleph http stream, or a raw TCP client/server...

2:50 bitemyapp: arrdem: http://avout.io/ http://blog.paralleluniverse.co/post/56519815799/distributed-actors-in-java-and-clojure

2:51 arrdem: https://github.com/amitrathore/swarmiji http://martinsprogrammingblog.blogspot.com/2012/05/distributed-actors-in-clojure.html

2:51 marcopolo`: can you have it always run tests after a compile

2:52 bitemyapp: marcopolo`: http://www.gnu.org/software/make/

2:52 marcopolo`: that was weird, that was something i typed a while ago

2:53 bitemyapp: marcopolo`: compile:\nlein uberjar\n\ntest: compile\nlein test

2:53 marcopolo`: but thanks for the super fast reply

2:53 bitemyapp: marcopolo`: `make test`

2:56 arrdem: bitemyapp: thanks for the links, I find none of these to be incrementally simpler than rolling my own atop aleph.

2:56 bitemyapp: arrdem: really? I figured avout would be pretty straight-forward.

2:56 OTOH, I guess some people would find zookeeper kinda hateful.

2:57 oh my god why am I writing JS willingly?

2:57 xuser: you know you like it

2:57 arrdem: I mean the problem I'm trying to solve is bloody simple: one host has a queue of tasks to be done, others poll looking for work. I could encode this with a multi-host atom (why bother) or I could just have a server streaming the next piece of work with aleph.

2:57 bitemyapp: xuser: no, I like *Fay*

2:58 xuser: I just like making toys for Fay.

2:58 arrdem: how many machines are you working with?

2:58 arrdem: bitemyapp: probably six or eight...

2:58 bitemyapp: I'm surprised it isn't more worth your time to figure out something faster on a single machine.

2:58 clojurebot: Huh?

2:59 bitemyapp: clojurebot: fay |is| awesome and makes frontend more fun.

2:59 clojurebot: In Ordnung

2:59 bitemyapp: ~fay

2:59 clojurebot: fay is awesome and makes frontend more fun.

2:59 bitemyapp: damn straight.

2:59 arrdem: lol

3:00 hum... if my bound is fetching data from the website... I could probably pipeline this some more on one host...

3:01 bitemyapp: saw some people on identi.ca wringing their hands over the renaming of the nodejs binary from node to nodejs. I was puzzled why anybody cared if the lives of node programmers were convenient or not. I can only assume it means node users don't understand how symlinks work.

3:01 arrdem: I didn't know that was your bound. I thought the db-client was choking via thread-pool.

3:02 arrdem: bitemyapp: if I'm using blocking writes, then my bound is that I can't do more than about 50 parallel page fetches before I get rate limited by the server.

3:02 bitemyapp: that then maxes me at 50 workers waiting on DB transactions so that I don't blow the pool.

3:02 bitemyapp: arrdem: you should be able to run a lot more threads concurrently than 50.

3:03 arrdem: bingo, if I can prefetch the web data.

3:03 which should be trivial...

3:04 bitemyapp: arrdem: so rejiggering it into a dataflow, then distributing?

3:04 I'm just thinking of the losses and unreliablity from talking to other servers and cringing.

3:06 arrdem: yeah fuckit I'll just have a queue of prefetched pages and a worker thread fetching monotonically fast as it can.

3:07 bitemyapp: arrdem: I would be sorely tempted to start firing off futures with a counter just to see how long it took before it broke.

3:08 arrdem: bitemyapp: since it'll entertain you, lets see if I can kill this thing with run-async again...

3:09 bitemyapp: yisss. death.

3:14 arrdem: bitemyapp: I started failing to fetch pages before I pushed over the write queue.

3:14 bitemyapp: arrdem: wait what.

3:14 I don't even

3:14 arrdem: you are having the hardest time I've ever seen anybody have with this.

3:15 arrdem: okay. so here's the now vs then.

3:15 now I have a threadpool of 50 workers.

3:15 bitemyapp: I'm actually kind of impressed, usually I'm the instability plague-bearer but it's a relief to know I've passed the curse onto somebody else.

3:15 arrdem: each one fetches its own HTML, parses it, destructures it and writes it to the db.

3:15 the rate at which these guys run is mainly bounded by writing back to the database: a bound which is removed if I do async writes

3:16 bitemyapp: arrdem: how large is the content?

3:16 arrdem: bitemyapp: this means that I can massively out-rate my source with this model

3:16 bitemyapp: but in this scenario, why would you begin to fail to fetch web pages?

3:16 arrdem: the host begins to ratelimit me with 503s

3:17 bitemyapp: arrdem: what's your I/O on the db-side?

3:18 arrdem: bitemyapp: not an issue. until I hit the datasource's rate wall I hit over 1k W/s

3:18 bitemyapp: arrdem: so the problem is you're going too fast and overloading the data source?

3:19 arrdem: bitemyapp: correct. originally I was extremely slow and serial in my access to the websource. now I'm parallel and really friggin fast.

3:19 bitemyapp: you keep seeming to change what the actual problem is so I can't really get a clear picture of what's holding you up at the moment.

3:19 okay.

3:19 so rate-throttle

3:19 arrdem: working on it...

3:19 bitemyapp: assuming you do so, do any problems remain?

3:19 arrdem: we'll have to find out the hard way..

3:22 dissipate: anyone know if Luminus (http://www.luminusweb.net/) is a good web framework?

3:23 bitemyapp: dissipate: it's not a framework per se, more of a project template and way to learn standard Clojure web dev.

3:25 dissipate: bitemyapp, standard Clojure web dev as in Ring and Compojure?

3:25 bitemyapp: dissipate: yes

3:25 dissipate: bitemyapp, i see, cool.

3:25 TEttinger: Caribou actually is a framework, right?

3:25 don't know if it's good, haven't used it myself

3:26 bitemyapp: framework'ish.

3:26 it has components.

3:35 logic_prog: I find it easier to use larger fonts (rather than high resolution fonts on a tiny screen). Now that the 17" mbp is no longer available, what is a good laptop to code on?

3:35 bitemyapp: logic_prog: dinkbook

3:35 logic_prog: cna't find it on google

3:35 bitemyapp: logic_prog: with noob-boob-tu installed

3:35 logic_prog: is this a joke ?

3:36 bitemyapp: logic_prog: don't make fun of me just because I have a code and a stuffed node.

3:36 logic_prog: if there was a distro named noob-boob-tu, I'd probably use it

3:36 bitemyapp: logic_prog: say it out loud, then all will make sense.

3:37 `cbp_: a thinkpad

3:37 hurry get them before they turn them into tablets too!

3:37 bitemyapp: logic_prog: yeah, that.

3:37 logic_prog: I don't see a 17" thinkbook

3:38 ddellacosta: TEttinger: read through a bunch of the docs now. Really seems like Rails built in Clojure.

3:38 logic_prog: ddellacosta: is this pedestal of halon ?

3:38 bitemyapp: ddellacosta: considering mr. smith works for a consultancy...

3:39 ddellacosta: logic_prog: what's halon?

3:39 logic_prog: halon = http://hoplon.io/

3:39 bitemyapp: logic_prog: good lord is that a stretched analogy. Don't ever do that again.

3:39 ddellacosta: bitemyapp: are you talking about this gent? https://github.com/noisesmith

3:39 bitemyapp: logic_prog: Orwell is spinning in his grave ya sadist.

3:40 ddellacosta: possibly? probably? justin_smith in IRC.

3:40 ddellacosta: bitemyapp: oh, justin_smith is associated with Caribou? Didn't know that!

3:40 clojurebot: Ack. Ack.

3:40 bitemyapp: ~justin_smith

3:40 clojurebot:

3:40 bitemyapp: ...

3:40 TEttinger: logic_prog, I have seen a bunch of QuadHD (better than 1080p) display laptops on techbargains lately

3:40 bitemyapp: ~justin_smith

3:40 clojurebot:

3:40 bitemyapp: ddellacosta: so I thought.

3:40 TEttinger: ahha

3:41 ddellacosta: ~bitemyapp

3:41 clojurebot: bitemyapp is unfuck your stack with monads!

3:41 ddellacosta: hahaha

3:41 ~ddellacosta

3:41 clojurebot: Titim gan éirí ort.

3:41 ddellacosta: what does that mean

3:42 bitemyapp: clojurebot: ddellacosta |showers| daily and thus avoids zen stink.

3:42 clojurebot: Alles klar

3:42 ddellacosta: huh, seems rather rude

3:42 bitemyapp: ddellacosta: it means, "beg your pardon?"

3:42 ddellacosta: ah

3:42 bitemyapp: ~ddellacosta

3:42 clojurebot: ddellacosta showers daily and thus avoids zen stink.

3:42 ddellacosta: I just looked it up here: http://www.ireland-information.com/irishphrases.htm

3:43 bitemyapp: why did you put |showers| between pipes like that?

3:43 bitemyapp: ddellacosta: oh, weird. usually it says "beg your pardon?" in Irish.

3:43 ddellacosta: that verbs it.

3:43 look.

3:43 ~ddellacosta

3:43 clojurebot: ddellacosta showers daily and thus avoids zen stink.

3:43 bitemyapp: so that it doesn't have to be "is"

3:43 ddellacosta: bitemyapp: ah, thanks

3:43 I wonder if it can handle non-Latin characters

3:44 arrdem: bitemyapp: rate limited to 5 gets per second.. holding 115 writes/sec with no apparent memory leaking...

3:44 ddellacosta: clojurebot: ddellacosta 疲れた

3:44 clojurebot: Titim gan éirí ort.

3:44 bitemyapp: ddellacosta: gotta provide a verb.

3:44 ddellacosta: ~ddellacosta

3:44 clojurebot: ddellacosta showers daily and thus avoids zen stink.

3:44 bitemyapp: ddellacosta: SOV could really fuck you here.

3:44 ddellacosta: no, it gave you an error again.

3:44 TEttinger: logic_prog: http://www.techbargains.com/news_displayItem.cfm/385841 is very similar to the one I'm on now, but I'm not a normal typist (I do what is basically a blind hunt-and-peck on memorized key positions), so the keyboard quality may be different for you

3:44 ddellacosta: clojurebot: ddellacosta is super 疲れた

3:44 clojurebot: Alles klar

3:44 ddellacosta: ~ddellacosta

3:44 clojurebot: ddellacosta showers daily and thus avoids zen stink.

3:44 ddellacosta: nope

3:45 so, what is confirmation that it got it?

3:45 TEttinger: it chooses a random one

3:45 logic_prog: TEttinger: I've tried an laptop like that before

3:45 bitemyapp: ddellacosta: in a foreign language.

3:45 logic_prog: I hate non-centered keyboards

3:45 TEttinger: ~TEttinger

3:45 clojurebot: Cool story bro.

3:45 bitemyapp: ddellacosta: you just need to know the responses.

3:45 logic_prog: the "number pad" on a laptop seems weird

3:45 ddellacosta: hmm.

3:45 bitemyapp: clojurebot: TEttinger |surprisingly| is not a Stasi spy.

3:45 clojurebot: Ik begrijp

3:45 bitemyapp: ^^ see.

3:45 TEttinger: clojurebot: TEttinger |writes| really hideous clojure

3:45 clojurebot: Ok.

3:46 bitemyapp: ~TEttinger

3:46 clojurebot: TEttinger writes really hideous clojure

3:46 bitemyapp: ~TEttinger

3:46 clojurebot: TEttinger writes really hideous clojure

3:46 ddellacosta: what

3:46 bitemyapp: ~TEttinger

3:46 clojurebot: TEttinger writes really hideous clojure

3:46 bitemyapp: ~TEttinger

3:46 clojurebot: TEttinger writes really hideous clojure

3:46 bitemyapp: damn you.

3:46 TEttinger: heehee

3:46 bitemyapp: ~TEttinger

3:46 clojurebot: TEttinger writes really hideous clojure

3:46 bitemyapp: clojurebot: TEttinger |surprisingly| is not a Stasi spy.

3:46 clojurebot: 'Sea, mhuise.

3:46 bitemyapp: ~TEttinger

3:46 clojurebot: TEttinger writes really hideous clojure

3:46 bitemyapp: ~TEttinger

3:46 clojurebot: TEttinger writes really hideous clojure

3:46 bitemyapp: I give up.

3:46 Sorry for the noise.

3:46 now I'm just grumpy it faulted with a false confirmation.

3:47 ddellacosta: haha

3:47 ah well.

3:47 TEttinger: what noise, that was only 16 nick pings

3:47 bitemyapp: ddellacosta: I've noticed searching for anything like "tired" in Japanese always brings up cute pictures.

3:47 ddellacosta: bitemyapp: seriously?

3:47 bitemyapp: ddellacosta: try it.

3:47 ddellacosta: I googled.

3:47 TEttinger: tired-chan

3:47 ddellacosta: bitemyapp: I would guess that, searching for most anything in Japanese brings up 1) cute pics, 2) porn, 3) cute porn

3:47 tired-chan, haha

3:47 bitemyapp: ddellacosta: makes sense.

3:48 ddellacosta: seriously, it's amazing what will bring up porn.

3:48 bitemyapp: TEttinger: I can do Katyusha in IRC pings if you like

3:48 * TEttinger mutes

3:48 logic_prog: clojurebot: logic_prog |is| awesome.

3:48 clojurebot: You don't have to tell me twice.

3:48 bitemyapp: ddellacosta: trying to look up rhyme nursery lyrics in Japanese must be really treacherous.

3:48 logic_prog: ~logic_prog

3:48 clojurebot: logic_prog is awesome.

3:48 bitemyapp: ~forget logic_prog is awesome.

3:48 clojurebot: In Ordnung

3:48 bitemyapp: ~logic_prog

3:49 clojurebot: logic_prog is awesome.

3:49 ddellacosta: bitemyapp: ha

3:49 bitemyapp: why do I even bother?

3:49 `cbp: u bad at this

3:49 logic_prog: ha

3:49 ddellacosta: clojurebot: clojurebot is broken

3:49 clojurebot: Roger.

3:49 arrdem: bitemyapp: I friggin wrote you an article on how to use forget

3:49 ddellacosta: ~clojurebot

3:49 arrdem: bitemyapp: y u fail so hard

3:49 clojurebot: clojurebot will become skynet

3:49 TEttinger: clojurebot: bitemyapp |licks| batteries.

3:49 clojurebot: 'Sea, mhuise.

3:49 ddellacosta: damnit

3:49 bitemyapp: ~bitemyapp

3:49 clojurebot: bitemyapp is it amuses me to mock other peoples' gods

3:49 bitemyapp: close enough.

3:49 ddellacosta: hahaha

3:49 logic_prog: clojurebot: logic_prog |is| so clojure much awesome such macro wow!

3:49 clojurebot: 'Sea, mhuise.

3:49 logic_prog: ~logic_prog

3:49 clojurebot: logic_prog is awesome.

3:50 TEttinger: haha this is like 2 screens of spam

3:50 ddellacosta: oh, so you always need the pipes, I failed to grasp that

3:50 clojurebot: ddellacosta |is| いない

3:50 clojurebot: You don't have to tell me twice.

3:50 ddellacosta: ~ddellacosta

3:50 bitemyapp: ~ddellacosta

3:50 clojurebot: ddellacosta is super 疲れた

3:50 ddellacosta showers daily and thus avoids zen stink.

3:50 ddellacosta: what

3:50 bitemyapp: perfect.

3:51 * bitemyapp cackles

3:51 ddellacosta: heh

3:51 arrdem: bitemyapp: cranked it up to 128 workers with the same 5/1s rate limit on gets... doing about 275 writes/sec stable...

3:51 logic_prog: clojurebot: logic_prog |so| clojure much awesome such macro wow!

3:51 clojurebot: 'Sea, mhuise.

3:51 logic_prog: ~logic_prog

3:51 bitemyapp: arrdem: "now you're thinking with pipes!"

3:51 clojurebot: logic_prog is so clojure much awesome such macro wow!

3:52 arrdem: bitemyapp: okay lets see if I can replicate that 400 write/second number..

3:52 bitemyapp: arrdem: I'm greatly enjoying the vicarious mad-science.

3:53 arrdem: bitemyapp: we're all mad here

3:53 bitemyapp: arrdem: oh...I can think of madder.

3:53 * bitemyapp glances askance at #agda

3:53 logic_prog: clojurebot: pi |is| 3.14159 26535 89793 23846 26433 83279 50288 41971 69399 37510 58209 74944 59230 78164 06286 20899 86280 34825 34211 70679 82148 08651 32823 06647 09384 46095 50582 23172 53594 08128 48111 74502 84102 70193 85211 05559 64462 29489 54930 38196 44288 10975 66593 34461 28475 64823 37867 83165 27120 19091 45648 56692 34603 48610 45432 66482 13393 60726 02491 41273 72458 70066 06315 58817 48815 20920 96282 92540 917

3:53 clojurebot: In Ordnung

3:53 logic_prog: ~pi

3:53 clojurebot: pi is 3.14159 26535 89793 23846 26433 83279 50288 41971 69399 37510 58209 74944 59230 78164 06286 20899 86280 34825 34211 70679 82148 08651 32823 06647 09384 46095 50582 23172 53594 08128 48111 74502 84102 70193 85211 05559 64462 29489 54930 38196 44288 10975 66593 34461 28475 64823 37867 83165 27120 19091 45648 56692 34603 48610 45432 66482 13393 60726 02491 41273 72458 70066 06315 58817 48815 20920 96282 92540 917

3:53 logic_prog: in case anyone ever needs to use pi

3:53 ddellacosta: um

3:54 arrdem: lolz?

3:54 `cbp: sorry but im a tau person

3:54 arrdem: bitemyapp: halving the wrate limit only bumped it up a little bit... better throw more workers at it..

3:55 bitemyapp: arrdem: you're not doing this by C-c'ing and lein run'ing over and over are you?

3:55 arrdem: awright. 256 threads.. show me what you're built of Awaited...

3:55 bitemyapp: nice round number.

3:56 arrdem: captain, we have 500 writes/second

3:56 arse I'm 503ing again.

3:56 bitemyapp: you made it mad.

3:56 arrdem: I should really re-design this around a queue which does incremental backoff on the rate limit..

3:57 but mad science is way more fun

3:57 bitemyapp: arrdem: how long is it going to take at 300/second?

3:57 back-pressure ist gut.

3:57 arrdem: bitemyapp: well... if nothing explodes I've already reached 2010 from 2008.

3:58 bitemyapp: so it should finish overnight.

4:01 bitemyapp: arrdem: http://i.imgur.com/lGGWYtE.jpg

4:01 arrdem: bitemyapp: thank you for the 3am doge

4:01 warms what I call a heart

4:03 bitemyapp: well I've managed to kill something...

4:03 not sure how to inspect the JVM internal contension however...

4:04 bitemyapp: arrdem: a profiler.

4:04 arrdem: yeah.... lemme switch back to synchronous writes and see if this goes away...

4:18 bitemyapp: http://i.imgur.com/xg7HaX8.jpg

4:18 I just lost it

4:19 bitemyapp: arrdem: laft.

4:19 aut lawd.

4:19 arrdem: also applicable: Haskell, Erlang.

4:20 arrdem: bitemyapp: heh. yeah it's definitely something with run-async.

4:21 ddellacosta: arrdem: yah, a functional language would have packed more punch there, but still, quite funny

4:22 bitemyapp: ddellacosta: agree.

4:25 arrdem: bitemyapp: RethinkDB wins forever. I just added a replica while writing and nothing broke.

4:29 bitemyapp: arrdem: :)

4:40 quizdr: Two threads walk into a bar. The barkeeper looks up and yells, "hey, I want don't any conditions race like time last!"

4:44 stirfoo: woohoo! 4 hours later I got glDrawElements to work

4:44 had to fish around the LWJGL source

4:44 quizdr: congrats stirfoo i know how messy gl can be

4:45 stirfoo: aye, but wrapping gl with clojure *is* kinda fun

4:46 cark: stirfoo: so what was the trouble ?

4:46 stirfoo: endiannessness for one, and I had to flip the buffer

4:46 cark: huh

4:46 are you on mac ?

4:47 stirfoo: byte ordering

4:47 linux

4:47 cark: strange

4:47 stirfoo: actually, no I didn't have to flip the buffer, but lwjgl seems to requre that, given some examples I found

4:48 https://github.com/LWJGL/lwjgl/blob/master/src/java/org/lwjgl/BufferUtils.java

4:49 that first createByteBuffer fn did the trick, I wasn't calling order

4:51 are float, double, etc sizes always fixed in Java? even for 32bit vs 64bit operating systems?

4:51 cark: i think so yes

4:53 i'm currently reviewing some old gl2 java code i have, i don't see any fliping or "native" anywhere

4:54 stirfoo: (.flip buf) or (.rewind buf)

4:55 cark: ohwell, that'll remain a mystery to me =)

4:55 stirfoo: I need to experiment with java.nio.*Buffer more

4:56 cark: you need to go to later opengl versions, there is so much oportunity for speed

4:57 domino14: i created a utils/vector_math.clj in my current directory

4:57 stirfoo: well, actually for rendering meshes, glDrawElements is pretty fast

4:57 domino14: (ns euler-144 (:require [utils.vector_math :refer [magnitude dot cos-theta euclidean-distance]]))

4:57 cark: stirfoo: but you'll have to construc your buffer each time

4:58 domino14: what is wrong with that? it tells me Exception No namespace: utils.vector_math clojure.core/refer (core.clj:3832)

4:58 stirfoo: cark: true

4:59 cark: stirfoo: with later versions you send your buffers (separated by use like texture coords or vertex position etc) to the gpu, then only update the ones that change each frame

4:59 domino14: what's your directory structure ?

4:59 domino14: i have a folder named utils and in it a file named vector_math.clj

5:00 and i'm in the same directory as the utils folder

5:00 stirfoo: - not _ ?

5:00 @ domino14

5:00 domino14: file names should have dashes too?

5:00 cark: your ns form should say vector-math

5:01 don't change the file name

5:01 stirfoo: module names have _, references to those have -

5:01 domino14: java.lang.Exception: No namespace: utils.vector-math

5:01 do i need to put anything special in my utils/vector_math.clj file?

5:02 cark: azre you using lein ?

5:02 i mean, how are you compiling ?

5:03 or launching the repl

5:05 domino14: got it, i needed to (ns utils.vector-math) in my vector_math.clj file

5:05 yes was using lein exec plugin

5:05 nite nite

5:05 cark: ahh :)

5:06 stirfoo: nite cark, maybe you can talk me out of the 90's with opengl =)

5:06 thanks for the suggestions

5:06 cark: stirfoo: gnight

5:38 alew: what's up with hoplon?

5:57 Glenjamin: just heard Rich Hickey pronounce "EDN" as "eden" instead of "E-D-N" - is that common?

6:05 lvh: alew: I don't know. I want to like it, I guess, but there's not enough docs for me to consider it :)

6:23 quizdr: why does (doc letfn) say it is a special form, when the source shows it as a macro?

6:25 Raynes: &(doc letfn)

6:25 lazybot: ⇒ "Macro ([fnspecs & body]); fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+) Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body."

6:26 quizdr: ,(doc letfn

6:26 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

6:26 quizdr: ,(doc letfn)

6:26 clojurebot: "([fnspecs & body]); fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+) Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body."

6:26 quizdr: hm on mine it shows it as a Special Form

6:26 Raynes: Eh, it's because they have different doc macros.

6:27 The source does not show it as a macro.

6:27 I mean, it does

6:27 But it's :special-form true

6:27 quizdr: so letfn is not a special form, it's a macro? the metadata is there to say it is a special form when it really isn't? why would that be?

6:28 Raynes: Because it translates directly to a special form.

6:28 That's the only reason I can think of/

6:28 quizdr: what is let* and letfn* and why are they not in the core API docs?

6:28 i see them all the time in source

6:28 Raynes: They

6:32 Damn keyboard

6:32 I'm at a terrible angle. :p

6:32 quizdr: ha i was trying to figure out what you meant

6:32 Raynes: quizdr: They are the actual special forms. If you look at the source for the macros, they're very simple wrappers around them.

6:32 You can't associate docs with a special form

6:32 So if the macros weren't there, there wouldn't be any documentation to say they are special forms, etc.

6:33 It makes sense to just pretend that the macros are special forms, because it makes no practical difference.

6:33 Macros without the special forms couldn't do what the special forms do. As such, they aren't just normal macros.

6:33 They're specifically the only way to do certain things

6:34 quizdr: are you referring to let* and letfn* now, or to letfn.

6:34 Raynes: They are quite special in that regard.

6:34 The macros are the leftfn, let, etc.

6:34 The special forms are letfn*, let*

6:34 quizdr: ah, ok.

6:35 so the docs for letfn would essentially be the same docs as for letfn*

6:35 Raynes: Yes. But you have no real reason to use letfn* directly

6:41 quizdr: and also no reason to use let* i'd image, right?

6:41 *imagine

6:50 i guess letfn is similar to common lisps "labels"

6:54 AeroNotix: how do I typespec something which is a generic type?

6:54 i.e. ArrayList<T> in java

6:58 cark: AeroNotix: you don't ... due to type erasure ArrayList<T> is just ArrayList

6:59 AeroNotix: that's what I was worried about

6:59 cark: why ? just use ArrayList and you're good

6:59 AeroNotix: well, I wanted mo' documentation really

7:00 khaled: o/

8:20 rurumate: ,#=(inc 1)

8:20 clojurebot: #<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>

8:28 rurumate: will (defn add5 [n] (+ #=(+ 4 1) n)) have better performance than (defn add5 [n] (+ (+ 4 1) n)) ?

8:28 corecode: benchmark it?

8:29 rurumate: corecode: benchmarks seem to show that the performance is the same, but I cannot benchmark every time I calculate a constant in my code

8:30 the question is, is the compiler smart enough to replace closed expressions with constants?

8:30 i.e. expressions with no free variables, like (+ 4 1)

8:32 funkotron: rurumate: how does the compiler know which expressions are closed?

8:33 hyPiRion: funkotron: by checking whether they have any free variables

8:34 rurumate: I think you effectively will get the same performance, due to JIT optimisation

8:36 rurumate: yes.. but it would be nice to be sure about these things. For instance, is it still true on openjdk? I was hoping the clojure compiler would just evaluate closed expressions

8:38 that's why I was trying =# but it seems its behaviour depends on the value of *read-eval*, which makes it less predictable

9:06 ddellacosta: is java.lang.Math/log the idiomatic way to do logarithmic calculations?

9:07 oh, I see that's the natural log

9:36 jonathanj: so the analyzed-patients function in this section seems to have an error: http://www.braveclojure.com/functional-programming/#2__Living_with_Immutable_Data_Structures

9:37 `analyzed?` is not defined anywhere

9:37 what should that code read instead?

9:40 oh, i think that's just some not-implemented-here function

9:40 insamniac: That's what I'm guessing after looking at it..

9:40 not a function you can just paste into your repl

9:42 jonathanj: looking at the Javascript example, what would be a reasonable implementation of `analyzed?`? (defn analyzed? [patient] (:analyzed patient))

9:42 perhaps?

10:32 Profpatsch: Is there something like cond for maps, taking only specified keys out of the map?

10:33 I tried (condp contains? the-map :foo "result" :bar "other result") but contains takes the arguments in the wrong order for that.

10:37 pmlarocque: (apply dissoc {:foo 1, :bar 2, :baz 3} [:foo :bar]) ?

10:37 dnolen: Profpatsch: just write a swap helper that flips the contains? argument order

10:38 (condp (swap contains?) the-map ...)

10:39 Profpatsch: Oh, right, I could do that.

10:39 #(contains %2 %1) ?

10:39 dnolen: Profpatsch: yep

10:39 Profpatsch: Man, this is high-level stuff…

10:39 Coming from Java and Python land.

10:40 A little elisp, but not too functional.

10:40 dnolen: Profpatsch: you could do it in Python, but being so functional is not generally considered idiomatic I think.

10:41 Profpatsch: I noticed half of my Python code was list expressions, so the question was: Why not write in a functional language in the first place? :)

10:43 Still, you can’t replace Python for Gtk3 stuff. And I don’t know Haskell yet.

10:44 And I don’t know if doing WIMP monad-style is such a great idea.

10:46 Is there any project that aims for a functional wrapper around the java bindings of Gtk?

11:08 So, this is the best I came up with: (condp #(get %2 %1) {:foo 42} :foo :>> identity) returns 42.

11:09 Is there an easier way to do it?

11:10 This is for side-effects.

11:12 Oh, condp is short circuiting, so it doesn’t make much sense. oO

11:12 Bronsa: Profpatsch: what about ##(select-keys {:a 1 :b 2 :c 3 :d 4} [:a :d])

11:12 lazybot: ⇒ {:d 4, :a 1}

11:14 Profpatsch: I guess that makes more sense, with a map afterwards. Yeah, thought in the wrong direction.

11:15 Bronsa: Profpatsch: if you want to execute side effects on specific keys on a map you could so something like

11:15 (mapv (fn [[k v]] (({:b println} k identity) v)) {:a 1 :b 2 :c 3})

11:15 (mapv (fn [[k v]] (({:b println} k identity) v)) {:a 1 :b 2 :c 3})a,

11:15 ,(mapv (fn [[k v]] (({:b println} k identity) v)) {:a 1 :b 2 :c 3})

11:15 clojurebot: 2\n[1 3 nil]

11:16 Bronsa: or something similar with a doseq

11:16 ,(doseq [[k v] {:a 1 :b 2 :c 3} :let [f ({:b println} k)] :when f] (f v))

11:16 clojurebot: 2\n

11:40 jita: is there any web framework in clojure which is equivalent to django in python ?

11:41 lvh: jita: If by that you mean "comes with everything" then no

11:41 ring is the standard thing, but it's fairly low level. people have built higher level things on top of that.

11:41 dnolen: jita: probably caribou, http://let-caribou.in

11:42 lvh: very few of them tell you how to do everything (templating, routing, orm...) as django does; no major ones I know of

11:42 dnolen: lvh: caribou does a lot of stuff, it's very Django/Rails-eseque

11:42 ambrosebs: Bronsa: I had a quick play with t.a.j yesterday. Stunning what you've done, very impressive.

11:42 jita: lvh: I am looking for rapid web development framework

11:42 dnolen: jita: it's not quite as fancy as Django, but that's a good thing IMO

11:43 jita: dnolen: i will have a look, thanks for suggestion

11:43 dnolen: jita: at some point Pedestal might offer a more complete solution too but it's in flux.

11:44 jita: ok thanks

11:44 Bronsa: ambrosebs: thanks! it's really close to a stable release

11:44 ambrosebs: Bronsa: great!

12:06 l1x: jita: Ring / composure gives you enough to get started there plenty of templating libs as well

12:07 and i like safari's spellchecker

12:08 jita: ok thanks

12:08 Can someone recommend me a good book for clojure too ?

12:16 Profpatsch: What’s the difference between put! and >!?

12:17 (let [c (chan)] (put! c 4) (go (.log js/console (<! c)))) does work as expected.

12:18 I’d expect (let … (go (>! c 4) (.log … (<! c))) to have the same effect, but it doesn’t! Why is that?

12:19 I just hope dnolen is still here. :)

12:20 dnolen: Profpatsch: that's not going to work. I suggest reading up on core.async a bit more before diving into it

12:20 Profpatsch: there's a good video from the Conj as well one that I did

12:20 Profpatsch: short story, >! <! are blocking operations

12:20 jita: O'Reilly book is good

12:21 Profpatsch: Okay, gonna do that. I did read all that stuff and watch your video, but I always make the mistake of not directly trying out what I heard. So I forget most of it again. ;(

12:21 You’re an entertaining speaker btw.

12:21 dnolen: Profpatsch: thx

12:21 jita: dnolen: is it better than "programming clojure"

12:21 dnolen: jita: IMO yes

12:22 noonian: that would work if each blocking op was in a different go block right?

12:22 dnolen: noonian: that is correct

12:22 noonian: thanks

12:23 jita: dnolen: thanks

12:31 Profpatsch: dnolen: @blocking operators: I got that, but why would (>! c 4) block the go thread? It puts a value on c and then <! immediately takes it again. So why would anything block?

12:31 dnolen: Profpatsch: what you just said is contradictory :)

12:32 Profpatsch: >! <! are blocking operations plain and simple. Everything falls out of that.

12:32 bbloom: Profpatsch: you can only put things in a buffer, if there is no buffer, somebody has to take it from you

12:32 Profpatsch: So when unbuffered >! and <! block until the sender and receiver are blocking together

12:33 Profpatsch: Ohhh, I get it. I somehow assumed that (chan) creates a buffer with one slot.

12:33 But of course it doesn’t.

12:33 noonian: execution never reaches the call to read because the call to put blocks

12:35 Profpatsch: Do blocking channels take any cycels btw? I guess they have to loop internally to see new input, right?

12:35 *cycles

12:35 * use any cicles. Ugh.

12:36 Okay, now I did a mistake in every correction. What’s going on with me‽

13:20 RickInAtlanta: I am reading the reasoned schemer right now, and in chapter 2 they have a function eqo. does anyone know the core.logic equivelant?

13:21 insamniac: I bet dnolen does!

13:22 I actually just bought that book too.

13:22 dnolen: RickInAtlanta: I don't think so, but easy enough to implement. I thought eqo was just unification anyhow

13:22 RickInAtlanta: ok, thanks. I will play with it some

13:22 insamniac: dnolen should get a cut from The Reasoned Schemer sales.

13:24 RickInAtlanta: I should have turned the page

13:24 (defn eqo (fn [x y] (== x y)))

13:26 ior3k: dnolen: sorry if someone has asked this of you already... do you use light table as your primary development environment?

13:32 s/of //. I knew there was something wrong with that...

13:32 dnolen: ior3k: no not yet, but it's pretty compelling. support for plugin development now is pretty rough, I think when those issues get resolved I think LT will really take off.

13:33 RickInAtlanta: dnolen: did you see Chris's tweets about the other language plugins being written

13:33 dnolen: RickInAtlanta: yes I follow ibdknox

13:34 RickInAtlanta: It was cool to see Don Syme's tween about F# support

13:35 ior3k: dnolen: thanks. It felt a bit rough to me, and seems to be single window centric, so I'll wait a bit more before taking another look

13:35 dnolen: ior3k: I use Emacs so single window doesn't really bother me much

13:36 RickInAtlanta: yes it was

13:36 ior3k: dnolen: I use emacs too, but I use multiple frames (tiling wm)

13:37 dnolen: ior3k: tabsets accomplish the same thing, but there's isn't vertical tabset support yet

13:37 in LT

13:37 ior3k: oh sorry multiple frames

13:37 ior3k: yeah got it

13:38 ior3k: dnolen: yeah sorry about the interchanging of terms :)

13:41 l1x: jita: there are 3 or 4 clojure books out there, i have read all of them, and each one is good for different things

13:42 jita: l1x: which one do you recommend for a beginner in functional language?

13:42 l1x: huh, great question

13:42 RickInAtlanta: thx again for help

13:42 gotta run

13:47 l1x: clojure is kind of two fold story, there is the Java/JVM part and there is the LISP part, if you want to learn how to LISP I would recommend to read http://mitpress.mit.edu/sicp/ if you learn how to utilize the JVM best from Clojure probably Programming Clojure (Halloway & Bedra), if you want to see how deep the rabbit hole goes with Clojure than you should

13:47 read "The Joy of Clojure"

13:48 there is the 3rd book, "Clojure Programming" that is not my favorite book, because the examples are kind of cryptic and hard to understand, but it covers everything, you can use it sort of like a reference book

13:49 Profpatsch: How would you do unique IDs?

13:50 bbloom: Profpatsch: depends on what you mean by "unique"

13:50 unique globally? per process? per thread?

13:51 Profpatsch: Ah, right. Easiest would be to use UUIDs, but there’s no function for it (at least not in cljs).

13:51 I thought something like an auto-incrementing value would suffice. But: atom, ref or something else?

13:52 bbloom: Profpatsch: uuid only makes sense if you need global uniqueness

13:52 if you're doing cljs, there is only really one thread anyway, so process unique == thread unique

13:52 i'd probably just use an atom with a number in it

13:52 Profpatsch: Well, since they are not very costly to generate, I tend to use them everywhere.

13:53 So (def ^:private *id-count* (atom))?

13:53 bbloom: Profpatsch: the *earmuffs* usually mean :dynamic

13:53 Profpatsch: the atom function takes an initial value argument

13:53 Profpatsch: Oh, right, the def is not changing, the atom is.

13:53 bbloom: but yeah, that's one solution

13:54 you can (swap! id-count inc) and use the return value from that

13:54 Profpatsch: Yep.

13:54 Thanks, got it.

14:35 arrdem: bitemyapp: this is why you don't let me do mad science.... I managed to push it to 1.1K writes/sec...

14:36 jita: Which IDE/text editor is mostly preferred for clojure development ?

14:37 arrdem: jita: emacs

14:38 jita: arrdem: can one do professional coding using a basic text editor like sublime text ?

14:38 bbloom: jita: choose whatever you're most comfortable with while learning the language. you don't want to be learning a language and an editor at the same time

14:39 arrdem: jita: bbloom gives good advice here. you can of course use another text editor. I mention Emacs only because it has in my experience the best REPL integration. it is by no means the only editor therewith however.

14:39 jita: bbloom: I am familiar with Sublime text and it has good support for python too, it has linter and syntax highlights for python, dont know about clojure though

14:39 Glenjamin: it can mostly highlight clojure

14:39 Profpatsch: jita: If you want to learn the language I very much advise you to use LightTable.

14:39 arrdem: jita: I didn't pick up Emacs until long after I had come to Clojure, so I cannot comment on learning both at once.

14:39 lvh: Emacs is pretty great as a basic text editor too, though; especially if you leave menu bars on

14:40 maybe paredit is kinda weird.

14:40 bbloom: jita: if you're used to what i'd call "modern graphical osx text editors" then you will probably find light table to be highly approachable & has great clojure support

14:40 jita: otherwise, i'd recommend just using what you know and copy/pasting in to your repl until you get the hang of the basics

14:41 jita: thanks a lot for suggestions, much appreciated. I will definitely look into LightTable

14:41 Profpatsch: jita: I am a heavy Vim and Emacs user and tried LightTable only a few days ago (after integrating Clojure into Emacs as good as possible) and it comletely blew me away.

14:42 jita: Profpatsch: downloading :)

14:42 Profpatsch: jita: bbloom The very best tool for learning Clojure quickly is the Instarepl in LightTable imho.

14:42 You don’t even have to bother pasting into a repl, it just shows the flow of data right beside your sexps.

14:43 jita: Profpatsch: will definitely check it out, thanks

14:44 Profpatsch: jita: Oh, and you’ll definitely want to keep this open in your browser: http://jafingerhut.github.io/cheatsheet-clj-1.3/cheatsheet-tiptip-cdocs-summary.html

14:45 jita: ok ty

14:45 Profpatsch: jita: Best served downloaded as a local file. ;)

14:45 cark: jita: by using a simple text editor with no repl support (or instarepl), you might miss out what's one of clojure main selling points

14:47 jita: I wonder if anyone tried this http://sublimerepl.readthedocs.org/en/latest/ ?

14:48 its mentioned here too http://dev.clojure.org/display/doc/Getting+Started+With+Sublime+Text+2

14:48 Notte: Hi, would anyone tell me why when i load this source file with (load-file ...) from repl, it loads just the last function, please ? http://hastebin.com/dolosawifi.lisp

14:49 jita: I am not sure how it would stack against LightTable though

14:49 cark: notte : i'm not sure if anyone ever uses load-file

14:50 Notte: cark: how should i load a code from a file within the repl?

14:50 cark: with require or use

14:51 so in this case you would type (require 'xi-ranker.core) , then change namespace to it in order to start playing with it

14:52 err i mean (require '(blah.blah))

14:52 Notte: cark: i was missing the change of namespace. Thank you so much :)

14:52 cark: =)

15:33 logic_prog: given a list, how do I get a list of all items in the list that appears atpeast twice ?

15:34 danneu: logic_prog: frequencies and filter?

15:34 logic_prog: damn, frequenies

15:34 that's what I was loking for

15:34 Profpatsch: Huh, where is the difference between (conj {:a 1} {:a 42 :b 1}) and (into {:a 1} {:a 42 :b 1})? oO

15:35 danneu: Profpatsch: id look at the source but i think into uses transients and is just a reduce of conjs

15:41 Profpatsch: danneu: Why does conj then behave like into for maps? vec: [2 4] -> [2 4 [1 3]] list: '(2 4) -> '((1 3) 2 4) map: {2 "a", 4 "b"} -> {1 "c" 2 "a" 3 "d" 4 "b"}

15:46 bbloom: Profpatsch: think of maps as sets of key value pairs

15:46 ,(conj {} [5 10 15]) ; this is nonsense

15:46 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Vector arg to map conj must be a pair>

15:47 Profpatsch: bbloom: Oh, right.

15:47 bbloom: Profpatsch: also worth noting, into is basically just (reduce conj to from)

15:47 Profpatsch: So it doesn’t matter which one I use for maps? I think into sounds more expressive.

15:48 Of course that reduce is another function call.

15:48 bbloom: into operates on a "from" collection

15:48 Wild_Cat: Profpatsch: I have strong doubts you'll notice the performance hit :p

15:49 bbloom: it's a different thing from conj or assoc which operate on to-be-added elements directly

15:49 what does "sounds more expressive" even mean?

15:50 Profpatsch: Well, it says exactly what I want to do. Merge these values into the other map.

15:50 bbloom: it's (into dest-coll src-coll) vs (conj dest-coll x y z)

15:50 Profpatsch: While with conj you have to first know that conj does that with maps (of course it’s obvious once you think hard ;) ).

15:51 bbloom: Profpatsch: if you want to operate on maps concretely, use assoc

15:51 conj is intentionally polymorphic

15:51 Profpatsch: But with assoc I first need the keys and values separately.

15:51 I already have them in another map.

15:52 So it’s either conj or into.

15:52 cark: bbloom: doesn't into use transients underneath ?

15:52 bbloom: cark: yes

15:52 cark: hence the "basically" qualifier

15:52 Profpatsch: you didn't say you had a particular use case, you asked for a comparison. can't expect me to read your mind :-)

15:52 cark: qo into is the best solution

15:52 so*

15:53 Profpatsch: if you have 2 maps, you can merge too

15:53 Profpatsch: bbloom: Of course. :)

15:54 cark: So there are three operations that do the same? oO

15:54 cark: they don't do the same think, only in the case of maps

15:54 thing*

15:54 Profpatsch: Yep.

15:54 cark: conj, adds an item to a collection

15:55 into adds multiple items to a collection, using transients and like conj is polymorphic

15:55 and merge is for maps

15:55 and sets maybe ...

15:55 hehe

15:55 bbloom: just maps

15:55 cark: ah ok =)

15:55 wasn't sure naymore

15:55 bbloom: merge also handles nil arguments and treats them as empty maps

15:56 Profpatsch: So merge is the best for maps.

15:56 bbloom: ,(merge nil {:x 1} nil {:y 2} nil {:x 3})

15:56 clojurebot: {:y 2, :x 3}

15:56 Profpatsch: ,(into {} {:x 1} nil)

15:56 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/into>

15:56 bbloom: into is not variadic

15:56 cark: Profpatsch: i think it should be, but last time i checked it was a fairly naive implementation

15:57 bbloom: yeah, merge's implementation does not take advantage of transients

15:57 cark: wasn't checking for smallest map before doing the merging, and didn't use transients

15:57 bbloom: into is idiomatic as well

15:57 cark: it shouldn't check for the smallest map b/c it assumes left-to-right overrides

15:57 cark: bbloom: ah indeed

15:57 Profpatsch: Fascinating. So there is still room for improvement in the core I see.

15:58 bbloom: Profpatsch: isn't that a fact of anything?

15:58 Profpatsch: Of course, but for some things more than for others. ;)

15:59 cark: Profpatsch: i think it comes down to the fact merge was implemented long before transients existed

15:59 pyrtsa: ,(into {} (concat {:x 1} nil))

15:59 clojurebot: {:x 1}

15:59 cark: also there a cost (O(1) but still) to converting to transient

15:59 pyrtsa: ,(into {} (concat {:x 1} nil {:y 2}))

15:59 clojurebot: {:x 1, :y 2}

16:00 cark: there is*

16:02 bbloom: cark: yeah, transients generally don't help below a certain number of conj! operations

16:02 probably somewhere < 15 or so

16:02 they probably even start to hurt further below that

16:02 haven't benchmarked it myself though, so not sure

16:04 cark: bbloom: so maybe it's for the best that merge is like it is

16:04 most of the time, maps are small

16:05 bbloom: cark: except for when they are big :-P

16:05 anyway, it's the transient overhead isn't worrying about, it's very small and constant

16:05 cark: bbloom: but there can't be as many since they're so big =)

16:05 bbloom: if the constant time is 6 hours, it's still a worry

16:06 bbloom: cark: the question is do you want to pay O(numMaps) transient cost or O(numElements) conj cost?

16:06 Profpatsch: cark: bbloom: You could always make the function variadic and use transients at x upwards

16:06 bbloom: Profpatsch: that won't help if you have ONE argument and it's a large collection to copy from

16:07 Notte: Why does this code give me an error? http://hastebin.com/gosurokaha.coffee

16:07 Profpatsch: bbloom: Or measure the size and use that to decide?

16:07 Notte: The file is readable

16:07 bbloom: Profpatsch: what if you have an uncounted source collection? like a lazy seq, which is the usual case

16:08 pyrtsa: Notte: Because map is lazy.

16:08 bbloom: Profpatsch: turns out, this shit is hard. so the simpler thing that is generally fast enough is the right decision

16:08 pyrtsa: Notte: Wrap it in a doall or use mapv instead.

16:08 bbloom: Profpatsch: if it's not fast enough, copy paste the source code & make it do what you need. but don't do that until your thing is working correctly

16:08 Profpatsch: bbloom: At least the map to append to must be realized.

16:08 cark: Profpatsch: if you have special needs, make a function and do it yourself, that's no rocket science anyways =)

16:08 pyrtsa: Laziness implies that the line-seq is consumed later than the with-open block closes.

16:08 Notte: pyrtsa: ok, thanks.

16:09 bbloom: Profpatsch: but if you need to realize it to count it, you need to hold on to it b/c you can't realize it again w/o side effects being an issue, so you need linear memory instead of constant memory

16:09 Profpatsch: bbloom: cark Nah, not anyway near that. I was just speculating about one could improve it.

16:09 *about how one

16:09 cark: Profpatsch: this discussion made me change my mind about the merge implementation, i think it is as it should be now, thanks both

16:10 pyrtsa: bbloom: Reminder that you don't have to consume the whole sequence to find out if its size is greater than a given threshold. ;)

16:10 Profpatsch: My respect for Rich is rising with everything I learn.

16:11 bbloom: pyrtsa: yes, this is true. but then you have to pay THAT constant cost, when you might as well have just paid the constant cost to produce the transient

16:11 pyrtsa: Sure.

16:11 bbloom: point is, dumb thing works & is generally fast enough: do that :-P

16:11 pyrtsa: And makes sense that both ways are available when the programmer knows which way to go.

16:11 Profpatsch: bbloom: But you don’t have to realize any values at all. You just have to count hash values.p

16:12 But yeah, until one has done lots of benchmarks there is no sense in improving it.

16:12 clojurebot: In Ordnung

16:12 bbloom: Profpatsch: i have no idea what you're talking about

16:13 Profpatsch: bbloom: About the existing map. Its size matters, too.

16:13 bbloom: in order to count (even partially count) a sequence (the common case in a pipeline) you need to realize the head N items of that sequence

16:13 Profpatsch: bbloom: I’d suspect that this map is way bigger than the one merged into it in most cases (with an entity-model you could have thousands of elements in it).

16:14 bitemyapp: arrdem: how'd you reach 1.1k?

16:14 arrdem: bitemyapp: I threw two more hosts at the problem.

16:14 Profpatsch: bbloom: But a map is a collection, not a sequence. ;)

16:14 bbloom: ,(coll? (seq [5 10 15]))

16:14 clojurebot: true

16:15 bbloom: Profpatsch: a sequence is a collection

16:15 Profpatsch: bbloom: I know, but merge only accepts maps as first argument.

16:15 bbloom: Profpatsch: oh, i see what you're getting at. you're saying that merge can assume the arguments are "counted?"

16:16 Profpatsch: but the issue is the count of the not-first arguments:

16:16 ,(merge {:x 1} (seq {:y 2 :z 3}))

16:16 clojurebot: {:y 2, :z 3, :x 1}

16:16 Profpatsch: bbloom: Since all args to merge have to be maps, I’d think they should be easily countable.

16:17 bbloom: Profpatsch: see above ^^ your assumption is incorrect

16:17 seqs are perfectly fine arguments to merge

16:17 Profpatsch: Oh, that’s fascinating. Then the docs are wrong.

16:17 Or at least not general. ;)

16:18 .(doc merge)

16:18 hiredman: yeah, that is weird, you used to have to apply merge

16:18 Profpatsch: ,(doc merge)

16:18 clojurebot: "([& maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping from the latter (left-to-right) will be the mapping in the result."

16:18 Profpatsch: Let’s git blame. :)

16:18 bbloom: it might be abusing an implementation detail to pass a seq instead of a map

16:18 but it's unlikely to change now

16:18 there are lots of things that use seqs of pairs and treats them like maps

16:20 hiredman: ah, that makes sense, of course merge is just calling seq on the passed in maps anyway

16:20 bbloom: yup

16:21 Profpatsch: (when (some identity maps)

16:21 (reduce1 #(conj (or %1 {}) %2) maps))

16:21 That’s merge.

16:22 The when is just to get the firsit non-nil value, right?

16:22 *first

16:43 sveri: so, du hast doch gesagt du kennst dich jetzt mit der selector syntax von enlive aus :D

16:43 hups, sry, wrong channel^^

16:46 bitemyapp: arrdem: scalin' >:)

17:00 daGrevis: hi! i have a list of numbers. i would like to get first numbers until multiplication of them is X. i dunno how could i say it functionally. i need to go through the list and in each step do (* x %) and check if it's X already. if so, stop the loop

17:01 this is what i have so far :( http://vpaste.net/0OjiF

17:01 TEttinger: daGrevis, reduced . hang on a sec

17:02 Mandar: hi

17:02 firefox keeps crashing, as soon as I launch a javascript heavy page

17:02 brehaut: Mandar: are you sure you are asking the question in the right channel?

17:02 Bronsa: Mandar: and.. what has that to do with clojure?

17:03 Mandar: brehaut, heh

17:03 thought i was on #gentoo

17:03 :D

17:03 brehaut: not quite ;)

17:03 Mandar: sorry guys!

17:03 brehaut: it happens. np

17:03 TEttinger: ,(reduce #(if (<= %1 100) (* %1 %2) (reduced %1)) 1 (range 1 1000))

17:03 clojurebot: 120

17:04 Bronsa: TEttinger not quite. he wants back the list of numbers

17:04 brehaut: (doc reduced)

17:04 clojurebot: "([x]); Wraps x in a way such that a reduce will terminate with the value x"

17:04 brehaut: nice

17:04 daGrevis: woah, thanks, TEttinger. give me some time to understnd it

17:04 Bronsa, TEttinger: ye, i need a list back with numbers that together * make up X

17:05 TEttinger: ohhhh like factors?

17:05 for 6, you mean 1, 2, 3 ?

17:05 (and 6)

17:06 daGrevis: ye exactly like factors :)

17:06 Bronsa: ,(reduce (fn [[m l] n] (if (<= m 100) [(* m n) (conj l n)] (reduced l))) [1 []] (range 1 100))

17:06 clojurebot: [1 2 3 4 5]

17:06 TEttinger: do the factors need to be prime?

17:06 Bronsa: if you want to use reduce/reduced

17:07 daGrevis: TEttinger, yes

17:07 im doing this https://projecteuler.net/problem=3

17:07 i have all primes of X and now I would like to get out prime factors

17:07 clojurebot: Gabh mo leithscéal?

17:08 TEttinger: you mean you've made a list of primes less than 600851475143 ?

17:08 * brehaut waves hands: something something 'for

17:09 * arrdem is surprised he hasn't killed the JVM

17:09 Bronsa: arrdem: I can do that for you if you want.

17:09 daGrevis: TEttinger, well i know it's not efficient.just trying to do something before optimization. currently im working with 13195

17:09 arrdem: Bronsa: with or without manual JVM bytecode generation...

17:09 AimHere: Ouch. I think a very quick course in number theory is in order

17:09 daGrevis: TEttinger, friend did this task in C++ with pure bruteforce and it run like 1sec

17:10 arrdem: daGrevis: just because brute force is viable doesn't mean we'll help you do it :D

17:10 AimHere: First off, consider taking only the primes up to and including Sqrt(X), because

17:11 bitemyapp: arrdem: amusingly, you might've had a better time (not necessarily faster) with something that behaved more like BEAM

17:11 AimHere: If you know that ab=x, and a<sqrt(x), then b> sqrt(x)

17:11 bitemyapp: arrdem: especially when you wanted to just send-off willy nilly.

17:11 Bronsa: arrdem: I lost count of the times I made the jvm crash while playing with jna/llvm

17:11 bitemyapp: that having been said, the unbounded mailboxes in Erlang are an exceedingly bad idea.

17:11 arrdem: Bronsa: haha yeah that isn't something I'm looking forwards too...

17:12 bitemyapp: playing with aleph some more trying to get a handle on the queue semantics...

17:13 daGrevis: AimHere, about sqrt - i can do / 2 to avoid looping throught half of a list http://vpaste.net/Ubo3o

17:13 bitemyapp: arrdem: I'm reading code I didn't write.

17:14 AimHere: daGrevis, sqrt(2) < 2 for all numbers that matter. Use that instead!

17:14 daGrevis: AimHere, is sqrt in core lib?

17:14 AimHere: Sorry sqrt(n) < n/2

17:14 arrdem: daGrevis: of course it is

17:14 AimHere: It's in Java.

17:14 Math/sqrt

17:15 ,(Math/sqrt 13195)

17:15 clojurebot: 114.86949116279744

17:15 daGrevis: cool

17:15 AimHere: It's not that cool. It's not first classy like most clojure functions

17:16 arrdem: AimHere: math.numeric-tower...

17:16 AimHere: ,(map Math/sqrt [1 2 3 4 5 6])

17:16 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to find static field: sqrt in class java.lang.Math, compiling:(NO_SOURCE_PATH:0:0)>

17:16 daGrevis: funny that i can use range with floats

17:17 ohh ye num-twr, but it's a 3rd party

17:17 lvh: too much crypto for me

17:17 I'm going "huh? what the heck is a *static* field? maybe it can't do it over integers, but ..."

17:18 then I realized: jvm.

17:18 AimHere: daGrevis, also, fundamental theorem of arithmetic would *really* help you out. If you find out that prime p|n, then to find the other primes that divide n, those are exactly the primes that divide n/p

17:19 daGrevis: AimHere, thanks, I'll look into it. ;)

17:23 sveri: hi, in the enlive tutorial (https://github.com/swannodette/enlive-tutorial/) the guy uses this syntax for the selector: "(def ^:dynamic *story-selector*...", why does he choose to make it dynamic? from my understanding a selector should not change during a request, any ideas?

17:28 bitemyapp: sveri: why are you doing the enlive tutorial?

17:28 sveri: bitemyapp: cause i want to use enlive?

17:28 bitemyapp: sveri: that was a given, what's your use-case?

17:29 marcopolo`: I think he's doing that because that tutorial is meant to be done in a repl, so you could change the selector and play around with it

17:29 sveri: bitemyapp: sry, i understand now, i am just picking a rest service and provide the data to some html, so during one request that wont change at my place

17:29 marcopolo`: if you didn't change the selector it would work just the same if it weren't dynamic

17:29 sveri: marcopolo`: that makes sense

17:29 i just was not sure if i missed something or misunderstood the dynamic attribute

17:30 bitemyapp: sveri: Perhaps https://github.com/raynes/laser/ would involve less time being utterly lost?

17:30 sveri: bitemyapp: so you would prefer laser over enlive?

17:31 bitemyapp: sveri: I'm a hypocrite, I don't prefer anything in this case, I'm just trying to save you some grief.

17:31 marcopolo`: You are creating html?

17:32 sveri: bitemyapp: ok, thank you then, i am just getting started together with a friend and we thought we go with enlive as it seems to be broadly used

17:32 marcopolo`: yea

17:32 bitemyapp: sveri: not really.

17:32 sveri: it just has good marketing.

17:32 sveri: bitemyapp: hehe

17:34 bitemyapp: ucb: http://www.youtube.com/watch?v=jTW1VsqiNV4

17:34 marcopolo`: sveri: I like enlive, but I've only used it for reading/parsing html

17:35 sveri: marcopolo`: well, as far as i read it works both ways

17:35 marcopolo`: but if you are you creating html, you might want to look at hiccup

17:35 https://github.com/weavejester/hiccup

17:35 haha let's overload you libraries!

17:35 sveri: :D

17:35 i seen that one to

17:36 but really, as a newbie in clojure land in general its hard to see the pros and cons of every lib and my feeling is i just have to go with one of them and see how it works

17:38 marcopolo`: yup!

17:39 sveri: does template reloading work with laser? thats one thing that bugs me currently with enlive

18:23 noprompt: dnolen: you around?

18:25 bitemyapp: noprompt: long time no see.

18:26 dnolen: noprompt: what's up?

18:26 noprompt: bitemyapp: the 100% pairing at the new gig has made it hard to be here during the day.

18:26 bitemyapp: noprompt: I hear that.

18:27 noprompt: could I interest you in some Fay and React.js tinkering?

18:27 noprompt: dnolen: i've run in to some weird behavior w/ "private" channels w/in components.

18:27 bitemyapp: noprompt: there's a CLJS meetup coming up

18:27 dnolen: noprompt: private?

18:27 noprompt: dnolen: i'm building out a generic table sorter with om.

18:27 dnolen: eh, maybe that's the wrong word for it.

18:28 dnolen: basically i have a component which creates a thead, whenever asc/desc buttons are clicked information is put on a channel which is passed in via opts in the parent component.

18:28 dnolen: the parent component then uses that information to sort the table.

18:29 dnolen: noprompt: what's the actual problem w/ the channels?

18:29 noprompt: dnolen: the problem happens when the table component gets swapped out say via a route change and a new "page" is rendered.

18:29 dnolen: the channel starts recieving an unstoppable flow of puts.

18:30 dnolen: and the browser locks up :(

18:30 bitemyapp: "unstoppable flow of puts"

18:30 noprompt: bitemyapp: not sure how else to describe it.

18:30 dnolen: noprompt: hmm, definitely would like to see a minimal example of this

18:30 bitemyapp: noprompt: just found it a funny mental image.

18:31 noprompt: dnolen: let me see if i can reduce my little demo here to something simple.

18:31 dnolen: i was planning to write a blog post about making reusable components like this.

18:32 dnolen: noprompt: that would help

18:32 noprompt: sounds cool

18:32 Om 0.2.0 just went out

18:32 noprompt: dnolen: i have the channel being created in IInitState and close!ed in IWillUnmount

18:32 dnolen: breaking changes for anyone using :opts

18:32 not replace by :state and :init-state, examples updated

18:33 s/not replace/now replaced

18:33 noprompt: dnolen: yeah, just noticed the last few commits.

18:33 dnolen: i check it everyday :)

18:33 dnolen: noprompt: heh, I really struggled on this one by I think this is right direction

18:33 noprompt: I hated that people could accidentally refer to stale opts

18:33 noprompt: also the fact that you couldn't set state from parent component

18:34 noprompt: dnolen: i started a new gig this week and so far the guys i've been pairing with are excited about it.

18:34 dnolen: noprompt: that's great!

18:34 noprompt: dnolen: most of them aren't big in to front end and it actually got them excited about building apps with cljs.

18:34 dnolen: noprompt: I'm pretty excited about it too, I think I can commit to documenting things now and writing real tutorials.

18:34 noprompt: next phase is the time management stuff

18:35 noprompt: dnolen: well i think i'm going to be sharing little nuggets like this moving forward. two guys said i should write up something.

18:36 dnolen: i sort of wanna "borrow" your latex looking blog theme.

18:36 AmLearning: : : rating 5. 0/5 - 54 votes [+] 54 likes [-] 0 dislikes : :

18:36 noprompt: dnolen: it's got that "academic" feel. :)

18:36 AmLearning: now days if ai even thin or feel threatened, i will brandish weapon "after yelling aloud"

18:36 noprompt: bitemyapp: i think we could get back on the haskell horse next week.

18:36 AmLearning: it's you're

18:36 noprompt: bitemyapp: had to get used to the new workday. starting at 7am, etc.

18:37 AmLearning: definition [1/1]: the short nickname for the word: tsundere. "tsun tsun" is used for cold/blunt/curt attitude, while "dere dere" is used when a person becomes embarrassed in front of his/her lover.

18:37 bitemyapp: noprompt: okie-dokie.

18:37 AmLearning: noprompt: there's a cljs meetup coming up

18:38 noprompt: bitemyapp: you going to clojure west?!

18:38 AmLearning: ! ud twat

18:38 bitemyapp: noprompt: I'm going to the CLJS meetup this month, I dunno about C/W

18:38 SparkySparkyBoom: AmLearning, are you a furry

18:38 noprompt: bitemyapp: c'mon!

18:38 AmLearning: SparkySparkyBoom, channel

18:38 SparkySparkyBoom: ?

18:38 noprompt: bitemyapp: it's practically in your backyard.

18:38 locks: what’s happening in here.

18:39 bitemyapp: locks: trulls.

18:39 arrdem: bitemyapp: the run finished overnight, but I managed to kill react with sharding settings. re-running...

18:39 bitemyapp: noprompt: yeah but, it's about Clojure.

18:39 arrdem: RethinkDB?

18:39 arrdem: what settings did it break under? Did you report to their github?

18:39 arrdem: bitemyapp: yeah I meant rethink.

18:39 noprompt: bitemyapp: it's also about friendship. ;)

18:40 arrdem: bitemyapp: I didn't because it's my fault that it broke.

18:40 bitemyapp: turns out syncing 1.8M records to a new shard totally locks up even my gaming box.. I think I got a kernel panick.

18:40 bitemyapp: arrdem: report it anyway

18:41 noprompt: that's the main incentive right now, but I'll end up using it as an opportunity to spread the joy of types.

18:41 noprompt: I'd probably spend most of the conference interested in anything Datomic related, teaching Haskell/Fay, and playing GO.

18:41 (baduk)

18:42 locks: what’s with clojure programmers and Go

18:42 noprompt: dnolen: got a new rig w/ a quad core I7 + 16GB ram, cljs compiles like laser beams. :D

18:43 locks: i don't play go.

18:43 bitemyapp: locks: it's not like I play Go well.

18:44 dnolen: noprompt: haha awesome :)

18:44 noprompt: dnolen: w/ source-maps builds are ~5s.

18:44 mcohen3: basic question for anyone with some core.async knowledge.....

18:45 locks: bitemyapp: how did you learn to play it?

18:45 bitemyapp: locks: losing

18:45 jasonpp: Started developing with Clojure and LightTable recently and noticed battery life on my new-ish Macbook Pro has dropped. Could JVM be responsible?

18:45 mcohen3: is it "thread safe" to reference vars in the outer (closure) scope from within a go block?

18:46 locks: bitemyapp: haha. did you play online? I don’t think there’s too many places where I can play go around here

18:46 bitemyapp: locks: yes.

18:47 jasonpp: I would guess yes, but science is always an option.

18:47 egghead: in cljs should I be using cljs.reader/read-string and prn-str on the server or is it better to do something else?

18:48 mcohen3: for example....https://gist.github.com/mcohen01/8512579

18:48 jasonpp: bitemyapp: Activity Monitor didn't really offer any answers

18:48 mcohen3: inside the go block i'm referencing url and foo, which are in scope prior to the go block

18:49 dnolen: noprompt: haha awesome

18:49 jasonpp: No significant CPU but RAM obviously quite high but I don't know if this accounts for (relative) battery drain

18:49 bitemyapp: jasonpp: not substantially.

18:49 mcohen3: does core.async take care of saving that whole closure scope state when it "parks" the thread?

18:49 noprompt: dnolen: well it seems like the problem is with close!ing the channel.

18:49 dnolen: if i don't close it during unmount everything is fine.

18:49 mcohen3: such that multiple threads will see the "correct" values of those vars inside the go block?

18:52 egghead: is it better to go `server edn -> client edn` or `server edn -> server json -> client json -> client edn`

18:53 marcopolo`: egghead: better to stay with edn

18:53 however I think edn might be a little slower than json, but you won't notice unless you are doing thousands of parsing

18:54 noprompt: dnolen: https://gist.github.com/noprompt/8512620

18:55 michaniskin: egghead: http://github.com/tailrecursion/cljson

18:55 noprompt: dnolen: do i not need to worry about close!ing the channel when the component unmounts?

18:56 bitemyapp: well, if you don't wanna go to clojure west that's cool. ;_;

18:56 egghead: oh cool thanks michaniskin

18:56 bitemyapp: noprompt: I do sorta. I just want to save the money for leaving this state even more.

18:57 or time, for that matter.

18:58 noprompt: bitemyapp: you're gonna move to a northern european country and join a type safe cult.

18:58 insamniac: lulz

18:58 bitemyapp: noprompt: I was thinking Austin or Seattle. Northern European usually implies Erlang.

18:59 noprompt: bitemyapp: given my taste in sweaters recently i'm could mistaken for a haskell programmer.

18:59 bitemyapp: although i have been busting out the math books more.

19:00 bitemyapp: noprompt: check out Awodey's Category Theory :)

19:01 noprompt: bitemyapp: i've been working through a probability book and an abstract algebra one in my free time. this weekend i was messing with parametric equations and doing fun stuff with curves.

19:01 bitemyapp: noprompt: the CT will tie into abstract algebra.

19:02 noprompt: bitemyapp: yeah, that's why i wanna get a handle on it before i look at CT any more.

19:02 bitemyapp: noprompt: no need.

19:03 noprompt: CT is pretty minimal in terms of prereqs

19:03 noprompt: bitemyapp: sure, but i'm not as interested in it as AA.

19:03 bitemyapp: noprompt: fair

19:04 noprompt: bitemyapp: in my experience with math it's always better to have a good foundation in subtopics before moving higher up the abstraction chain.

19:04 bitemyapp: plus there's a ton of stuff in AA that's useful.

19:04 dnolen: noprompt: sorry I gotta run

19:04 noprompt: you definitely have to be concerned about channel closing

19:05 noprompt: anyone listening needs to be ready for that.

19:05 noprompt: dnolen: alrighty. if you get a chance to run the code and give me feedback that'd be helpful. i don't wanna put a blog post out there with borked code.

19:08 wafflepilot: software = fun

19:09 TEttinger: gah http://clojuredocs.org/clojure_core/clojure.core/_dot_dot

19:10 patrickod: what's the most idiomatic of having multiple dependent if-lets in sequence? I'm writing a small web service that creates 2 dependent models from a request and if-let only supports one binding

19:10 is nesting them the best practice ?

19:11 noprompt: patrickod: i wouldn't worry about the idioms so much. if if-let isn't going to work in your case then don't use it.

19:12 patrickod: use whatever will make your code work will expressing your intent clearly.

19:12 *while expressing

19:12 patrickod: noprompt fair enough. given it's my first clojure project I just wondered what idioms existed if any for such things. this is a learning project not something serious :)

19:12 thanks!

19:12 alew: patrickod: I had a similar issue and came up with a macro with the help of a few people here

19:13 danneu: patrickod: yeah, sort of like when-let -- it'd be nice to have syntax for "when all of these bind, then do this".

19:13 alew: patrickod: It's like an inverted cond that also lets you have binding forms in it

19:13 but yeah you could just write a if-all-let

19:15 danneu: ,(-> 42)

19:15 clojurebot: 42

19:15 danneu: ,(->> 42)

19:15 clojurebot: 42

19:15 danneu: oh what

19:16 noprompt: patrickod: fwiw, in my experience it's best to focus on writing idiomatic code once you've gotten used to a new language. you'll be significantly less stressed though you'll probably write more verbose/ugly code. :)

19:16 patrickod: this is true. much less stressful when you just don't care

19:17 noprompt: danneu: how's it going?

19:17 danneu: i don't think we've ever spoken outside of GH issues.

19:18 danneu: noprompt: hey man. it's going well. i am probably garden's biggest user.

19:18 i want to freeze time so that i can extract my stuff back into github repos

19:18 noprompt: danneu: haha, thanks! that'd be awesome.

19:19 danneu: hey did you ever get a chance to check that lein-garden issue?

19:21 danneu: noprompt: i havent yet tried your update

19:22 noprompt: danneu: eh, that pluginn needs work. i think i jumped the gun promoting it. i got busy the past couple months and haven't been givin garden or the plugin enough attention.

19:22 danneu: there's a pile of things i want to improve.

19:22 danneu: ill give it a shot. i've been using my own loop where i hard-code the paths so i'll see if i can get it working

19:22 noprompt: danneu: keyframes, the compiler, colors; all need work.

19:23 danneu: the big thing i want is a compiler protocol which people can safely use.

19:23 danneu: yeah. me too. my compass port turned into two different projects. one is a library of helpers. the other is a compile/build tool.

19:23 noprompt: danneu: well i'm definitely open to any ideas you've got.

19:24 danneu: most of the "big" features have been handled.

19:26 danneu: a hiccup + garden codebase is pretty comical.

19:26 ryantm: ,5d2

19:26 noprompt: oh, it's so weird isn't it?

19:26 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 5d2>

19:26 brehaut: i prefer a 5e3 myself

19:26 noprompt: danneu: i built a little web app where i was sharing selectors between hiccup/garden. my mind was melting.

19:27 danneu: noprompt: the power is overwhelming for me unless i take breaks to square up my abstractions. but when i get it right, it's insane

19:28 noprompt: danneu: my feeling exactly. have you messed much w/ macros? that was the biggest mind blowing moment for me.

19:29 ryantm: ^,(+ 1 1)

19:29 danneu: noprompt: i'm pretty bad at them, but i try.

19:29 noprompt: danneu: the funny thing is i spent more time working on garden than actually using it seriously. when i finally got the chance it was an interesting experience.

19:30 danneu: i think i've inadvertently rewritten most of Twitter Bootstrap with garden though in my current proj

19:30 noprompt: danneu: oh man, you should definitely share that.

19:30 danneu: i'd link to the repo in the README.

19:30 danneu: the hard part is just that this stuff gets so coupled with my production code so it's a fulltime job just to extract things

19:31 noprompt: i hear ya.

19:31 bitemyapp: arrdem: doters?

19:32 noprompt: danneu: one thing that needs to happen is an api for client-side garden. right now it's just garden on the client, but it's much better to just manipulate the CSSOM directly.

19:32 haven't figured out how best to handle that.

19:34 danneu: noprompt: what kind of stuff would that allow you to do? i don't have much experience on the client-side.

19:36 noprompt: danneu: it'd just allow you to manipulate the CSSOM directly instead of generating strings and setting the style attribute of stuff directly.

19:36 danneu: so something like (update-rule! :.foo styles..)

19:38 danneu: what's nice about it is that you can be more declarative. ie. you don't have to say select these elements and set their style attribute to x.

19:39 danneu: you just update the stylesheet and everything is gravy.

19:41 danneu: noprompt: oh yeah, of course. you're just updating a datastructure.

19:41 arrdem: bitemyapp: maybe later. crunching on more homework and Awaited is 50% through the 2nd crawl run.

19:42 bitemyapp: I may hop on the texas server 8-10ish

19:42 or sooner if these retards keep dancing in the library..

19:44 marcopolo`: So here's something weird my -main fn sets up a go-loop, does work in it. In the go-loop goes on indefinetely, but when I run it with lein run it exits after a bit. Is there some JVM flag I should set?

19:50 mischov: marcopolo: -XX:+StopScrewingWithMe? :P

19:50 marcopolo`: haha

19:51 now when I do Thread/sleep in the main before exiting it does my go-routine work, so I'm pretty sure it thinks the main thread is done and exits.

19:52 arrdem: mischov: hah well played

19:53 bitemyapp: marcopolo`: fork a JVM keep-alive thread, provide a channel to it to kill it off when you're ready for the process to terminate.

19:53 marcopolo`: core.async "threads" are not JVM threads, it can't tell it's supposed to keep the lights on for somebody.

19:53 marcopolo`: yeah I figured that was the problem

19:53 bitemyapp: well you say that.

19:54 marcopolo`: what's a keep-alive thread?

19:54 bitemyapp: marcopolo`: it's not a reified thing. I incorporated the purpose of the thread into the noun.

19:54 arrdem: marcopolo`: a thread that just spins

19:55 bitemyapp: it wouldn't even spin, it's just going to park on a channel wait.

19:55 when it receives *anything* from that channel, it dies and takes your process down with it.

19:55 quizdr: if you take the nth element of a huge lazy sequence , i assume the reason it won't overflow the stack is because it is not holding onto references to the previous elements, even if they are needed to calclate nth, it is throwing them away, right?

19:56 marcopolo`: bitemyapp: gotcha, thanks

19:56 arrdem: quizdr: no... that would be a heap overflow

19:56 quizdr: a stack overflow is too many recursive function calls were made

19:56 quizdr: ok, but an overflow regardless, so it is throwing away the intermediate calculations to avoid this, right?

19:56 arrdem: quizdr: but yes, lazy sequences can potentially conserve memory by garbage collecting unused subseq.

19:57 quizdr: in which case, if you asked for nth again, it would need to calculate again, unless you memoize for that particular nth request?

19:57 arrdem: quizdr: no. that model only applies to stream accessed lazy sequences

19:58 quizdr: if you use nth on a lazy seq, everything up to the nth block is realized and cached.

19:58 quizdr: with no hope of garbage collection

19:58 quizdr: cached how? so you could use up the heap then?

19:58 arrdem: well.. the block where the nth element resides...

19:58 quizdr: correct. observe.

19:58 ,(doall (range))

19:58 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

19:59 jack_rabbit: heh

19:59 arrdem: quizdr: I just told the bot to fully compute an infinite sequence.

19:59 quizdr: then how is it possible to request some ridiculously large nth value from a sequence of infinite fibonacci numbers, for example, without using up the heap?

20:01 arrdem: quizdr: for a fibonacci sequence incrementally defined as a lazy list, computing the nth term requires fully computing the previous n terms, right?

20:02 quizdr: it's just that a lazy sequence can perform this computation in constant space.

20:02 quizdr: but if those n terms are cached, aren't they taking up heap space?

20:02 arrdem: ,(doc realized?)

20:02 clojurebot: "([x]); Returns true if a value has been produced for a promise, delay, future or lazy sequence."

20:03 danneu: How does noir.util.crypt/compare know what salt to use? https://github.com/noir-clojure/lib-noir/blob/master/src/noir/util/crypt.clj#L50

20:03 arrdem: quizdr: I'm actually not sure under what circumstances a lazy sequence will become realized/cached.

20:04 quizdr: in this case the sequence should not become realized because any reasonable fibonacci sequence definition will, thanks to being recursive, unroll into incrememental loop calculation form.

20:04 quizdr: so accessing the nth element here will not cause caching of the previous n.

20:05 quizdr: however if you have a lazy sequence of finite size, and traverse it in its entirety, then the lazy sequence will become fully realized and cached.

20:06 quizdr: does that distinction make sense to you?

20:08 quizdr: arrdem, consider this lazy fibb definition:

20:08 arrdem: quizdr: refheap paste please.

20:09 quizdr: ,(def fibb [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0N 1N])))

20:09 clojurebot: #<CompilerException java.lang.RuntimeException: Too many arguments to def, compiling:(NO_SOURCE_PATH:0:0)>

20:09 quizdr: ah

20:09 ,(def fibb [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0N 1N]))))

20:09 clojurebot: #<CompilerException java.lang.RuntimeException: Too many arguments to def, compiling:(NO_SOURCE_PATH:0:0)>

20:09 quizdr: copy paste madness

20:09 ,(defn fibb [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0N 1N])))

20:09 clojurebot: #'sandbox/fibb

20:10 quizdr: ,(def lots-o-fibs (take 1000000000 (fibo)))

20:10 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: fibo in this context, compiling:(NO_SOURCE_PATH:0:0)>

20:10 quizdr: (def lots-o-fibs (take 1000000000 (fibb)))

20:10 ,(def lots-o-fibs (take 1000000000 (fibb)))

20:10 clojurebot: #'sandbox/lots-o-fibs

20:10 quizdr: grr sorry

20:10 arrdem: ,(let [lst (fibb)] (println (nth 50 lst) (realized? lst))

20:10 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

20:10 quizdr: so when i do this:

20:10 ,(nth lots-o-fibs 100)

20:10 arrdem: ,(let [lst (fibb)] (println (nth 50 lst) (realized? lst)))

20:10 clojurebot: 354224848179261915075N

20:10 #<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Number>

20:11 arrdem: ,(let [lst (fibb)] (println (nth lst 59) (realized? lst)))

20:11 clojurebot: 956722026041N true\n

20:11 * arrdem drums his fingers

20:11 quizdr: it is saying it is realized, but only up to the 59th element, right?

20:12 ,(realized? lots-o-fibs)

20:12 clojurebot: true

20:12 arrdem: quizdr: I think so... however the 59 alignment is doubtful. map is a chunked lazy sequence, so it's more likely to have computed 64 terms and only shown the 59th.

20:13 quizdr: that's fine, but what I want to know is: are all those elements 0 - 59 or 64 consuming heap space? i wouldn't think so. so how can they be realized or cached?

20:13 ,(nth lots-o-fibs 1000)

20:13 clojurebot: 43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875N

20:14 quizdr: obviously, clojure is not keeping 1000 of these huge numbers in memory

20:14 yet it can extract the 1000th

20:14 arrdem: quizdr: if they have not been garbage collected (which they won't be so long as the head of the seq is referenced) they must be sucking up storage.

20:14 and yes it can keep 1000 huge numbers in memory...

20:14 quizdr: if they *are* garbage collected, then asking for them again means they are calculated again, even if they are already realized, right?

20:15 arrdem: they won't be, because the head of the sequence is retained.

20:15 hyPiRion: ,(last losts-of-fibs)

20:15 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: losts-of-fibs in this context, compiling:(NO_SOURCE_PATH:0:0)>

20:15 hyPiRion: ,(last lots-of-fibs)

20:15 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: lots-of-fibs in this context, compiling:(NO_SOURCE_PATH:0:0)>

20:15 arrdem: hyPiRion: lolz

20:15 * hyPiRion leaves

20:15 hyPiRion: ,(last lots-o-fibs)

20:15 arrdem: hyPiRion: stick around... you can probably answer this better than I can

20:15 quizdr: by "head" you mean the first 0 - 59 elements?

20:15 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

20:16 arrdem: quizdr: no, by head I mean the object constituting the "lazy" sequence.

20:16 this thing

20:16 ,lots-o-fibs

20:16 clojurebot: eval service is offline

20:16 arrdem: ah shit.

20:16 hyPiRion: arrdem: I think I just broke it

20:16 arrdem: hyPiRion: you or me, its dead either way :P

20:16 hyPiRion: anyway, realized? returns true if the next element in the lazy seq is realized

20:16 not the entire thing

20:17 arrdem: ,(next lots-o-fibs)

20:17 quizdr: ok, so explain to me how the system can not store the calculations for all those hundreds or thousands of results from 0 to n-1 and thus not use heap space, but also not have to recaculate them?

20:17 clojurebot: eval service is offline

20:18 arrdem: http://reactiongifs.me/wp-content/uploads/2013/08/shia-labeouf-magic-gif.gif

20:18 hyPiRion: quizdr: it did, that's why I tried to pick the last element in the list of all those fibs

20:18 arrdem: quizdr: it does store those. the lazy-sequence object contains a cache of the realized (computed) subsequence of the sequence.

20:19 quizdr: so when you say (nth seq 5000), it computes and stores the first 5000 and just returns the last one to you.

20:19 quizdr: this all obviously consumes heap space.

20:19 quizdr: i see. why is the heap overflow only happening when you request to view one of those that has been stored, rather than in the act of actually storing them to begin with?

20:19 hyPiRion: arrdem: well

20:20 arrdem: hyPiRion: mod some handwaving and seq internals which I need to learn..

20:20 quizdr: you cannot achieve a heap overflow re-accessing an element.

20:21 quizdr: what hyPiRion and I have demonstrated is accessing an element so far out the lazy sequence that computing the cache kills the JVM

20:21 gtrak: tpope: have you been working on a middleware for the jump-to-symbol?

20:21 hyPiRion: quizdr: the elements aren't generated unless they have to be used (e.g. by using next/rest)

20:21 quizdr: if you are correct, then when I request the 1000th fib, then 1000 fibs are stored in the heap somewhere. but if I try to do the same with an un-lazy sequence, you get memory overflow errors right away. whether it is lazy or not, 1000 of these numbers takes up the same amount of memory, right?

20:22 arrdem: hyPiRion: which in this case they have to be by definition of iterate...

20:22 quizdr: hyPiRion so you are saying the elements 0 - 999 are *not* being stored because they are not being requested, right?

20:22 arrdem: hyPiRion: so his (map first (iterate)) is totally going to exhibit this behavior because it's based on next.

20:23 hyPiRion: hmm

20:23 arrdem: ,(doc iterate)

20:23 clojurebot: "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"

20:23 arrdem: quizdr: how do you think iterate is implemented?

20:23 hyPiRion: quizdr: first off, storing 1000 elements takes roughly the same space for both a lazy and an eager seq

20:23 arrdem: quizdr: it feeds the last computed value into a lazy-seq expression for the next value.

20:24 hyPiRion: however, an eager seq will at some point have all the elements in the heap. This is not necessarily true for a lazy seq

20:24 quizdr: so a lazy seq could then "forget" some of those elements at some point?

20:24 hyPiRion: but that depends on whether or not you retain the head of the lazy seq, and how you generate said lazy seq

20:26 quizdr: so I retained the head when I did this: (def lots-o-fibs (take 1000000000 (fibb))) if I did not do that, then I might technically be able to access elements further out in the space without getting memory errors, since the prior elements would be immediate garbage collected, is that right? storing the head reduces how far out you can get stuff?

20:26 hyPiRion: quizdr: Consider a linked list. If I do (def a my-list), then (def a (rest my-list)), then the first element of my-list can be garbage collected

20:27 quizdr: yeah

20:27 S11001001: quizdr: that's accurate

20:27 quizdr: hyPiRion, ahh, so it really depends on how the head is stored in this case.

20:28 hyPiRion: quizdr: right. If you define lots-o-fibs as a function returning (take 1e10 (fibb)) instead, you'd generate a new list every time (and not retain its head)

20:28 quizdr: so the advantage of storing the head is that elements in the sequence are cached once they are calcualted, and you don't have to wait for those calcualtes again. the advantage of not storing the head is you can access nearly anything in the sequence even way far out, in ways you could not do when storing the head.

20:28 hyPiRion: quizdr: exactly

20:28 quizdr: in which case, you choose what you need, whether storing or not fits your needs

20:28 alew: when you hold onto the head, the gc can't touch anything in the lazy seq because you can get to any part of the lazy seq through the head

20:29 quizdr: so if time was not an issue, but you wanted to access nearly anything in an infinite sequence, storing the head is a bad idea.

20:29 hyPiRion: yup.

20:30 quizdr: wherease, if time is important and you frequently need the same elements over and over again, sacrificing the extent to which you can access inifinity is worth the benefit of retaining prior realizations

20:30 hyPiRion: quizdr: yeah, or you can eagerly compute the results if you know you need them anyway. I some cases, directly inserting the values into a vector may be beneficial for random access times

20:31 *In some cases

20:31 alew: you can still access farther out points of the lazy seq and have them be cached

20:31 if you retain the head of the lazy seq 1000 places in

20:32 bbloom: although if you need to retain that and do multiple ops on it later, maybe worth paying the cost to build a vector :-)

20:32 quizdr: very interesting stuff. so I should reasonably expect a stored lazy seq and an "eager" seq to flake out in memory around the same point in the sequence, since they are both storing their elements

20:36 S11001001: quizdr: the lazy representation typically has stacks more memory overhead per element, though chunks alleviate this when available.

20:40 quizdr: interesting. lazy sequences use more memory for their retained elements than eager sequences?

20:41 S11001001: quizdr: indeed

20:41 bbloom: quizdr: the implementations are quite approchable to read

20:42 quizdr: bbloom that's true

20:42 bbloom: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LazySeq.java

20:43 quizdr: so is the entire implementation of clojure open source? one could go and build clojure for use?

20:43 bbloom: lazy sequences are essentially cons cells, but each cell needs an extra possible function thunk field

20:43 vectors, for example, use 32-wide arrays and are much cheaper than cons cells per item

20:43 quizdr: that makes sense.

20:43 bbloom: quizdr: clojure is open source yes, i just linked you to it

20:44 quizdr: so one could technically build a version of clojure with reader macros, for example, by adding that functionality

20:44 mrhanky: is it possible to include jquery-migrate via foreign-libs in lein-cljsbuild?

20:45 S11001001: quizdr: eh, could you take it seriously if it wasn't? :)

20:46 quizdr: well i'd seen comments in the clojure mailing list about guys who wanted to add various things, and the consensus then being "no they won't be added." but I would think those guys could just do it for themselves. i hadn't realied till just now that the java implementation was also open source

20:46 i don't know much java so never thought to check on it

20:47 flamingnoms: is it normal for a nested list to be flattened when map'd if said list is a lazy sequence?

20:48 cark: mrhanky: you might want to check the :preamble option in compiler settings of cljsbuild

20:48 S11001001: quizdr: the cost/benefit analysis of forking clojure is more complicated than "do I have the skills to implement this?"

20:48 quizdr: i'd imagine it is

20:49 S11001001: quizdr: i.e. sure, you can implement reader macros, and then use them in your libraries. But who will use your libraries then?

20:49 anyway there are lots of bad ideas too, good to have principled maintenance

20:50 quizdr: reader macros for example would have a truly transformative power for live music coding via overtone, hence my mentioning them. not likely that pragmatic for other cases.

20:50 cark: there are many good use cases for reader macros

20:51 flamingnoms: such as making FORTRAN 95 valid lisp?

20:51 cark: actually we have quite a few of these appearing from time to time in standard clojure

20:51 most recently the #js reader macro was added to clojurescript, it is really a valuable addition

20:52 quizdr: cark, yes, but their criticism are well justified in most cases. they don't really add functionality to what you can *do* with your algorithms and those don't add power in that way. but for live music coding, where the speed in which you type affects the performance of your music (via the amazing clojure system "overtone"), they would be extraordinarily useful

20:52 anyway, i didn't mean to start a reader macro debate, sorry

20:52 cark: they do add expressive power

20:53 mrhanky: cark, is it just me or is there no documentation about this option?

20:53 cark: the same criticism is oftentimes applied to macros

20:53 eraserhd: Does anyone know of an existing Java or clojure implementation of editor-type buffers? E.g. like emacs buffers or vim buffers?

20:53 cark: mrhanky: ah possibly =P

20:53 mrhanky: that's bad :)

20:54 can you explain what this option does?

20:54 quizdr: regular macros truly extend the power of the language itself, while reader macros are primarily a convenience for your fingers

20:54 cark: mrhanky: in your cljs-build config do this :compiler {:output-to "main.js" :preamble ["js/gl-matrix-min.js"]}

20:54 mrhanky: and so on

20:55 mrhanky: it will add the javascript code at the beginning of your compiled cljs files, after compilation is done

20:56 quizdr: yet they're usefull enough to have many of these inside clojure

20:57 quizdr: #(), #', #{} ... and so on

20:58 sritchie: do you guys know if there's a way to track down unused clojure functins?

20:58 functions*?

21:00 mrhanky: cark, are you sure this works with :foreign-libs ?

21:01 cark: mrhanky: actually i don't know the first thing about :foreign-libs ...

21:01 mrhanky: actually i think foreign-libs is doing that process, before compilation

21:02 mrhanky: but then you need a library which is compatible with the closure copiler

21:02 compiler

21:02 don't quote me on that tho, i'm not sure

21:03 mrhanky: libs added with :foreign-libs do not need to be compatible with closure

21:04 cark: mrhanky: ahyes you're right, i remember trying to make that work, but never made it

21:05 mrhanky: for that gl-matrix.js thing, i eventually added it like i showed you, then made a cljs namespace to "import" everything

21:06 mrhanky: like so : (def mat2d (js* "mat2d")) (def clone (aget mat2d "clone")) ...etc...

21:06 mrhanky: not the most elegant, but it works =)

21:07 danneu: Datomic-free's 2-peer limit means that if I have a Prod and Staging server behind a load balancer and they connect to the same database, then I can't connect to Datomic from a `lein repl`, right?

21:10 dissipate: can someone tell me why it is worth it to pay for Datomic when there are tons of NoSQL and SQL databases out there for free? not trolling here, just curious.

21:10 mrcheeks: eraserhd: that could be just a JPanel with a CardLayout and what you need to do in there (editorkit, inputmap, etc.)..

21:12 quizdr: dissipate there are many commercial database options and many free database options. the question is highly dependent on your individual needs.

21:12 dissipate: quizdr, what is the main use case for Datomic?

21:12 bitemyapp: dissipate: OLTP

21:13 dissipate: you don't have to pay for Datomic.

21:13 dissipate: there aren't any other viable historical databases that I'm aware of, so there aren't the plethora of options you're making it out to be.

21:14 dissipate: bitemyapp, sounds like a good possible solution for a stock market application?

21:14 bitemyapp: that is way too broad of a question to answer.

21:14 There are a million and one things that can involve a database and the "stock market"

21:14 quizdr: dissipate you are not interpreting the word "historical" correctly. any database can store historical market data.

21:15 dissipate: bitemyapp, well, in a stock market app you need ACID

21:15 eraserhd: mrcheeks: I'm not interested in the graphical part, but the efficient storage, insertion, changing, and deletion.

21:15 bitemyapp: quizdr: to be fair, datomic works better with any sort of "arrow of time" queries.

21:15 dissipate: 1. No you don't 2. good thing Datomic is ACID

21:15 dissipate: quizdr, what do you mean by 'historical'?

21:15 bitemyapp: dissipate: you should be asking what *I* meant by historical.

21:15 arrdem: bitemyapp: ok I'm coffee burned. grabbing food and gonna hop on dotaz or something.

21:15 bitemyapp: arrdem: kk

21:15 dissipate: bitemyapp, what do *you* mean by historical?

21:22 mrcheeks: eraserhd: that you'll likely need to implement it yourself..

21:23 danneu: dissipate: i have a forum that uses datomic

21:24 history gives me a simple way to manage post edits. user can 'undo'. kinda cute

21:24 dissipate: danneu, and do you use the historical feature?

21:24 danneu: it also gives me "moderator logging".

21:24 dissipate: danneu, interesting

21:25 danneu: datomic is a pleasure to work with. and i can't imagine what else i'd use in clojure. sql strings? sql dsl and sometimes have to break out into sql strings?

21:26 the hard part for me is the unfamiliarity

21:26 dissipate: danneu, in short, what is the 'historic' feature of Datomic?

21:27 danneu: dissipate: i dont have much of a technical understanding. i just took a chance with datomic. but a practical example is that if you have a User and they edit their email 100 times, you have all that on record

21:28 or if you edit their username as a moderator, you can query for all of their historical usernames.

21:28 dissipate: danneu, very interesting. i'm going to have to investigate this some more.

21:28 danneu: that's just a topical example

21:29 xuser: dissipate: haven't use it but I think is just means that a original copy of the data is kept everytime is modified

21:30 dissipate: think persistent data structures

21:32 hyPiRion: dissipate: More interesting examples is the debugging possibilities. If someone tells you they had an issue with e.g. posting a reply at 10:40 am, you can recreate the situation by specifying that queries shall run as if it were 10:40 am.

21:42 arrdem: bitemyapp: rebooting

21:46 socksy: eraserhd: may be wrong, but perhaps something like a finger tree is what you're looking for?

22:11 eraserhd: socksy: It seems I want a rope rather than a finger tree.

22:12 We don't seem to have a clojure implementation around.

22:13 Well, a rope with some specific adaptation for reading files in blocks and finding things by line number.

22:14 hadronzoo: What is the best way to run clj/cljs integration tests? Use clojure.test and make cljs calls using cemerick/austin?

22:16 (I want to ensure that the clj and cljs versions of some functions produce identical values without hardcoding the results into the clj and cljs unit tests)

22:23 TEttinger: eraserhd, http://www.ibm.com/developerworks/library/j-ropes/ this should be usable from clojure, GPL licensed though

22:27 eraserhd: TEttinger: Cool, thanks!

22:27 At the moment, it seems like what I want is a core.rrb-vector of byte blocks. Still researching.

22:27 TEttinger: if you can read simple F#, http://fssnip.net/4e might be convertable

22:28 eraserhd: It seems like rrb-vector does all the rebalancing and tree-ing.

22:30 TEttinger: the F# one only implements append, no logic for insertion (necessary in my case).

22:31 TEttinger: ooooh I just found something

22:31 http://lua-users.org/wiki/SplayRopes

22:32 these can use a pure functional datatype, splay trees, internally

22:35 eraserhd: TEttinger: Ooh, neat!

22:37 TEttinger: also apparently they're very slow according to https://news.ycombinator.com/item?id=1370847

22:37 not sure if they're slower that stringbuilder

22:38 eraserhd: I don't know if they're slower, but I think for my editor use case, they should be faster.

22:38 The whole file is rarely traversed.

22:39 TEttinger: http://programmingpraxis.com/2013/01/22/splay-heaps/#comment-6799 splay heap here, not sure how different it is

22:39 eraserhd: Mostly the blocks of text in the editor window are accessed, so that should be O(1) after the first lookup.

22:40 TEttinger: (that one IS clojure)

22:43 eraserhd: TEttinger: splay ropes it is. That's a beautiful solution, it is.

22:44 TEttinger: heh, I think with all... 2 implementations, each unsuitable in different ways, mixing and matching should result in something at least. put in on github when you're done maybe?

22:44 I'd like to see it, and I bet it will be shorter than the lua impl

22:45 eraserhd: Yeah, I'll do it in a separate repo.

23:11 notsonerdysunny: is there clojure-toolbox.com like thing for clojurescript?

23:13 danielszmulewicz: https://github.com/shaunxcode/clojurescript-ecosystem/wiki/libraries

23:13 notsonerdysunny: I am new to clojurescript .. what are the alternatives I should consider for shoreleave before picking

23:13 danielszmulewicz: thanks let me check that

23:14 danielszmulewicz: notsonerdysunny: the new rage seems to be all about React. Try Om and Cloact.

23:15 technomancy: I don't know anything about clojurescript, but my guess is that it would depend on what you're trying to do?

23:16 notsonerdysunny: I have actually built a basic widget with cloact .. Now I needed to some communication with the server so was looking what is the right thing to do..

23:16 danielszmulewicz: Transfer edn with core.async?

23:16 notsonerdysunny: mind you I only javascript that clojurescript has taught me I am new to this browser programming thing

23:17 ok let me take a look

23:19 mischov: You might get some ideas googling "clojurescript xhr"

23:25 sreenath: hi

23:25 got a question about lein repl stand alone

23:26 How can I add jars to lein stand alone repl?

23:26 technomancy: sreenath: you can put them in :plugins, but that's not really what it's for

23:27 sreenath: plugins inside a project you mean

23:27 technomancy: oh, I mean in the :user profile

23:28 sreenath: oh OK.

23:28 WHat do you mean that's not really what its for?

23:28 technomancy: well :plugins is for plugins =)

23:29 ryantm: plugins are supposed to modify leiningen not inject code into your clojure env?

23:29 technomancy: it just happens that a standalone repl runs inside Leiningen's process, so anything you tell it is a plugin gets put on the classpath

23:29 sreenath: yes :). Looks like there is no simple way

23:29 technomancy: right; Leiningen is designed for use with projects. you can use it for other things, but that's not the original intention.

23:30 maybe the lein-try plugin would help for what you want though

23:30 haven't used it myself, but from what I heard it sounds similar

23:31 sreenath: Thanks. I have been playing around with repl for project euler problems. how can I use math dependencies

23:31 in repl without project

23:31 technomancy: the simplest thing to do is `lein new euler` and run in that

23:31 sreenath: I just want to use repl lein or the clojure one

23:31 OK

23:32 But I want to say one thing though. I can't understand why the math functions are not there in core

23:33 technomancy: http://p.hagelb.org/mystery.gif

23:33 sreenath: I mean they are available in other FP languages like Scala etc

23:34 ryantm: technomancy, did you see the GitHub pull req from davidegrayson improving lein help?

23:34 sreenath: Anyway Thanks technomancy

23:35 technomancy: ryantm: yeah; I hope to take a look tomorrow; actually need to sign off for tonight

23:35 ryantm: technomancy, great

23:38 egghead: hm, I have a question about cljs and packaging, you need a different html for dev/release so how is this managed?

23:38 for example a single js file vs multiple js files

23:38 I know cljsbuild can give me the different outputs, but how do projects deal with the different html?

23:52 flamingnoms: i'm confused about lazy sequences. When I map symbol to a lazy-sequence of strings from a file, they all turn to symbols. When I map keyword, only the first is a keyword.

23:52 ryantm: egghead, where is your html file coming from right now?

23:52 egghead: ryantm: static html served by ring

23:54 flamingnoms: nvm, its just the behavoir of keyword

23:55 ryantm: egghead, are you using wrap-resource to serve it?

23:56 egghead: ryantm: I am doing this: https://github.com/eggsby/warden/blob/master/src/clj/warden/handler.clj#L9

Logging service provided by n01se.net