#clojure logs

2012-12-21

00:00amalloyi don't know clojure's do-notation, but in haskell you can do it like: do {x <- return value; return (function x)}
00:01sgeo_In clojure.algo.monads at least, domonad puts an implied return around the last expression
00:01sgeo_So a bit like a list/monad comprehension
00:31muhoofrozenlock: is cljs-in-cljs a real thing?
00:31ghadishayban&(let [^{this should really throw an exception} foo 42] foo)
00:31lazybot⇒ 42
00:31ghadishaybanhilarious
00:32muhoometadata on a vector?
00:32ghadishayban&(let [foo ^{this should really throw an exception as well} []] foo)
00:32lazybot⇒ []
00:32TimMcThat's... surprising.
00:32bbloom&(let [foo ^{this should really throw an exception as well} []] (meta foo))
00:32lazybot⇒ nil
00:32ghadishaybansee my comments on CLJ-1136
00:33ghadishaybancompiler bug
00:33ghadishaybanmetadata in a let binding vec doesn't get evaled
00:33amalloy,(let [foo ^{this should really throw an exception as well} []] (meta foo))
00:33clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: as in this context, compiling:(NO_SOURCE_PATH:0)>
00:34bbloom&(macroexpand '(let [foo ^{w t f ?} []] foo))
00:34lazybot⇒ (let* [foo []] foo)
00:34amalloyi recommend using clojurebot for this, bbloom. lazybot probably messes up metadata
00:34TimMcAnything to do with lazybot's parser/expander?
00:34mehworkfrom a .clj file ran via lein run, how do you create an infinite stdin prompt that echo's back what you type each time you hit enter?
00:34bbloom,(binding [*print-meta* true] (macroexpand '(let [foo ^{w t f ?} []] foo)))
00:34clojurebot(let* [foo []] foo)
00:35bbloomhm
00:35mehworkim trying everything i can google and nothing ever echo's back
00:35bbloom,(binding [*print-meta* true] (macroexpand '(identity ^{w t f ?} []))
00:35clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
00:35bbloom,(binding [*print-meta* true] (macroexpand '(identity ^{w t f ?} [])))
00:35clojurebot(identity [])
00:35bbloom*shrug* i've had bad luck with metadata
00:35ghadishaybanprint-meta won't affect that i believe
00:35bbloom(doc *print-meta*)
00:35clojurebot"; If set to logical true, when printing an object, its metadata will also be printed in a form that can be read back by the reader. Defaults to false."
00:36ghadishaybanit's a bug in Compiler$LetExpr
00:36TimMcbbloom: You didn't print.
00:36ghadishaybanTimMc: exactly
00:36bbloomTimMc: dur. yes, the repl is printing OUTSIDE heh
00:36bbloommy bad
00:36bbloom,(binding [*print-meta* true] (prn (macroexpand '(identity ^{w t f ?} []))))
00:36clojurebot(identity ^{f ?, w t} [])
00:36bbloom,(binding [*print-meta* true] (prn (macroexpand '(let [foo ^{w t f ?} []] foo))))
00:36clojurebot(let* [foo ^{f ?, w t} []] foo)
00:37bbloomhm yeah, gotta be a bug in LetExpr since it's not a bug in the let macro
00:38bbloomanyway: what are people using metadata for outside of symbols and vars? i know that zip.clj uses them, but i feel like defrecord is almost always preferable. i'm curious if others ignore metadata as often as i do....
00:41TimMcWait, so how is it that (let [foo ^{a b} []] foo) throws and (let [^{a b} foo []] foo) doesn't?
00:42TimMcI would think that both would throw, actually.
00:42TimMcDo metadata literals have an implicit quote?
00:43amalloyTimMc: [] gets eval'd, and foo doesn't, in that context. i imagine that's relevant
00:43ghadishaybangood catch
00:44ghadishaybanit won't really affect type hints though:
00:45amalloyof course it does. (Class/forName "not real") isn't a meaningful type-hint if it doesn't get eval'd
00:46TimMc(prm `^{a (+ 1 2)}[]) ;;= "^{clj.core/a (clojure.core/+ 1 2)} []"
00:46TimMc^ (defn prm [s] (binding [*print-meta* true] (pr-str s)))
00:46ghadishaybanbut typically ^objects or ^floats
00:47TimMc,(meta ^ints [])
00:47clojurebot{:tag #<core$ints clojure.core$ints@605af24c>}
00:47TimMcHmm, some sort of special-casing there...
00:47ghadishaybando the bots support def?
00:47TimMcghadishayban: Nope. Their sandboxes don't allow environment mutation.
00:48amalloyi believe the issue is that (let [^{:tag (Class/forName "x")} name val] ...) is equivalent to (let [name ^{:tag (list 'Class/forName "x")} val] ...)
00:48TimMcghadishayban: By the way, you can /msg them to test stuff out.
01:00pendlepantswould anyone recommend using an IDE for clojure development? noticed that intellij is $50 today, but am not sure how helpful it'd be.
01:01technomancypendlepants: IIRC the clojure support for intellij works fine in the OSS version
01:01pendlepantsoh, cool. thanks technomancy.
01:02pendlepantsis the value in an IDE re: debugging and java interop, or are most people using emacs?
01:02pendlepantss/the/there/
01:03Raynespendlepants: Most people are using Emacs, but plenty of people also use counterclockwise for Eclipse.
01:03technomancymost people use emacs. the value of an IDE depends on whether you end up working on large java codebases alongside your clojure.
01:03RaynesI don't think java interop is a factor, and there is some debugger stuff for Emacs too (ritz).
01:03RaynesBut if you're happy with something like Eclipse or Intellij, nobody will lynch you.
01:04technomancyI mean, that's where the distinctive strengths of IDEs stand out; it's impossible to navigate certain java codebases without a tool that's actually written in Java
01:04technomancybut you can do a lot in clojure without ever having to do that; it depends on what you're writing
01:04bbloomit's impossible to navigate certain java codebases</message>
01:04RaynesI've yet to need an IDE.
01:04RaynesBut I've yet to work with a Java codebase.
01:04RaynesBesides libraries, at least.
01:04RaynesNothing app-level.
01:05pendlepantsthat makes sense; I'm coming to clojure w/o a lot of java experience and was nervous that I may shoot myself in the foot without an IDE.
01:05pendlepantsbut that's heartening.
01:05RaynesI don't think an IDE will really help you with any foot shooting.
01:05technomancypendlepants: for pure-clojure code you almost never need a stepping debugger
01:06bbloom(-> some (long sequence of code) with a random println (in the middle) tends to work out)
01:06RaynesOf course, if you're frustrated with Emacs it might turn you off of Clojure, so make sure that if you're not comfortable with it you use something you are comfortable with until you actually want to learn Emacs.
01:06RaynesChas Emerick, author of Clojure Programming, uses Eclipse for his Clojure development. No shame in it.
01:06RaynesI mean, he has plenty of shame, but not because of that.
01:07pendlepantsI'm used to vim and have been developing in that w/ some tmux stuff to get copy/paste into the repl.
01:07RaynesVim works well for Clojure.
01:07bbloompendlepants: time to upgrade to tpope's foreplay!
01:07technomancydon't switch from vim to emacs while trying to learn clojure at the same time
01:07bbloompendlepants: https://github.com/tpope/vim-foreplay/
01:07technomancyyour brain will explode
01:07pendlepantsyeah, if vim's not a huge pain with clojure I'd just as soon keep using it.
01:07Raynespendlepants: I actually switched from Emacs to Vim for a long time and was very happy. I only switched back to Emacs when I discovered evil-mode. If you're good with Vim, I recommend you just stay there.
01:08Raynestechnomancy: I really don't buy that as a general thing for everybody.
01:08bbloomRaynes: it's common enough to be ill advised
01:08RaynesLike, I learned Emacs and Clojure at the same time and I was like 13.
01:08bbloomRaynes: being 13 makes it far easier
01:08technomancyRaynes: yeah, but when you're older it's harder to learn new things
01:08RaynesAlright gramps.
01:09RaynesI'll respect my elders and concede for now.
01:09bbloomRaynes: you didn't have to *unlearn* anything first :-P
01:09technomancyalso when you have lots of free time =)
01:09RaynesI was really busy. Internet porn and what not.
01:09bbloomvim was hard for me after 5 years of visual studio
01:09bbloomdamn free copies for schools, that shit is like crack
01:10bbloomjust as bad for you.
01:10technomancybut unfortunately it's legal
01:10bbloomwho do we sue?
01:11RaynesSue Chris Granger for damages, bbloom.
01:11RaynesHe worked on VS.
01:11Raynes:)
01:11ibdknoxI had nothing to do with it
01:11bbloom.... so did i....
01:11bbloomOMG I HAVE TO SUE MYSELF
01:11Raynestechnomancy: We have a traitor in our midst.
01:11ibdknoxI wanted to create a sku for $50
01:11ibdknoxnot a free one ;)
01:12technomancyRaynes: you know what to do
01:12technomancy~guards
01:12clojurebotSEIZE HIM!
01:12bbloomi wrote a large portion of the XNA sample games... i'm like walter white over here...
01:12Raynesibdknox: Were you just eavesdropping, or do you get highlighted on 'Chris' or 'Granger'?
01:13technomancybbloom: if you're going to make this difficult...
01:13technomancy~gourds
01:13clojurebotSQUEEZE HIM!
01:13amalloyhe gets highlighted on "Sue"
01:13RaynesHahahaha
01:13ibdknoxyep.
01:13amalloyyears of microsoft paranoia
01:13ibdknoxI actually happened to be looking
01:13technomancyamalloy: I was thinking along the lines of "A boy named..."
01:13ibdknoxthough I highlight my name to see all the bad things you guys say about me.
01:13ibdknoxfuckers.
01:14Raynesibdknox: Man, did you see all the people *thanking* us for deprecating noir?
01:14RaynesIt was spectacular.
01:14ibdknoxIt was the right thing to do :)
01:14RaynesA few people were sad and wanted me to be like "No, I was just kidding! Noir is back!"
01:14RaynesBut most of them were ecstatic.
01:14bbloom"how dare you build something for free and then get busy and change your preferences in design!"
01:15RaynesWell, he didn't go that far. :p
01:15bbloomnotice: no question mark
01:15technomancyRaynes: that would have been great if April were closer
01:15ibdknoxlol
01:15RaynesHe said he had non-clojure developers writing Clojure at work and that they apparently incapable of putting two dependencies in project.clj instead of 1 and he needed Noir for them.
01:15Raynes*shrug*
01:16RaynesI tried my best to not sound snarky, but... that just smells bad.
01:16amalloygood thing you didn't hack into his computer and upgrade him, then
01:16ibdknoxI understood what he was saying, but he's looking at the problem wrong
01:16ibdknoxwhat he wants can easily be accomplished by simply creating a template for compojure/lib-noir
01:16Raynesibdknox: Well, the problem is that he has developers who should probably not be writing Clojure in the first place if they aren't willing to actually learn and use it. I don't know what to say to that. We can't optimize for people who hate Clojure.
01:16ibdknoxand then fixing up some docs
01:17Raynesibdknox: I've got two things on my TODO re that goal.
01:17augustlpasting this here, in case it's a general JVM/leiningen solution for this problem, no idea if it's specific to datomic: https://groups.google.com/forum/?fromgroups=#!topic/datomic/iT6CVdagK5c
01:18ibdknoxRaynes: oh?
01:18Raynesibdknox: The first thing is getting a Noir to Compojure+lib-noir tutorial/migration guide thingy on compojure's wiki, and the second is somethin Andre Brehaut suggested which is possibly changing webnoir to be a tutorial for Compojure + lib-noir
01:18ibdknoxalso how did we get away from berating bbloom?
01:19RaynesWell, not necessarily a tutorial, but like a getting started sort of thing like is on the front page.
01:19bbloomi berate myself plenty
01:19ibdknoxRaynes: sounds like the right thing to do :)
01:19RaynesMaybe port the tutorials and stuff.
01:19ibdknoxRaynes: that also covers that guys points
01:19pendlepantsbbloom: thanks for the link to vim-foreplay; this is great.
01:19RaynesWhat Compojure needs is a good documentation website.
01:19ibdknoxyes
01:19RaynesAnd webnoir is a fine place to put it, as long as you don't mind getting rid of the old Noir tutorial stuff (or moving it to an 'old' link or something, which would be fine)
01:19bbloompendlepants: don't take me, thank tpope
01:19ibdknoxand I'm sure weavejester would love it if someone put one together :)
01:20bbloomthank*
01:21Raynesibdknox: Anyways, if the world ends in a few hours, meet me half way through the country.
01:22ibdknoxright at midnight the power went out here (I'm visiting NC)
01:22ibdknoxit has since unfucked itself
01:22bbloompower company have a sense of humor?
01:22RaynesYou and amalloy and I could survive an apocalypse
01:23ibdknoxRaynes: I have a fair number of unusual skills that would be very useful in such a situation
01:23technomancyI wonder if I'll ever get tired of ~guards
01:23ibdknoxtechnomancy: I never do
01:23technomancyibdknox: good to know it's not just me
01:23ibdknoxbbloom: I'm fairly convinced it was someone being funny
01:23Raynestechnomancy: I always cut up when you do ~gourds afterwards.
01:23amalloy$eball
01:24amalloydamn. Raynes, how do i ask him if technomancy will get tired of ~guards?
01:24Raynesamalloy: Long since removed.
01:24RaynesIIRc
01:24technomancywill I ever tire of ~guards??
01:24lazybottechnomancy: Definitely not.
01:24amalloyi guess i could cheat: o great lazybot, will technomancy ever grow tired of ~guards??
01:24lazybotamalloy: Uh, no. Why would you even ask?
01:24technomancysweet
01:24RaynesI deleted a lot of the old fun plugins because nobody cared about them and I got tired of rewriting lazybot's core and having a million pointless plugins to update.
01:24RaynesBut that's probably because I did too much core rewriting.
01:25technomancyclojurebot: botstack is <reply>/me puts lazybot on his head and gropes blindly for a third bot to complete the stack.
01:25clojurebotAlles klar
01:26ibdknoxlol
01:26technomancyanother classic from the Emacs channel
01:26technomancybut they actually have three bots in there, so it's a bit less awkward
01:27bbloomclearly somebody just needs to write a 3rd bot
01:28technomancydid we have a haskell bot at one point?
01:28technomancyor no, lazybot speaks haskell
01:28ibdknoxcorrect
01:28amalloy$heval [1,2..10]
01:28technomancychouser_log is a bot
01:28amalloydamn it. i can't do anything right
01:51witt3rdhello. may i ask a lighttable question (quick)
01:52bbloomibdknox ^^
01:53bbloomjust ask
01:54witt3rdis there a known issue in the latest build (OSX) with the instarepl eval munging the fn names with od chars
01:54witt3rd(def ï·‘'fn (fn [n] (+ n n)))
01:54witt3rd(ï·‘'fn 4) => 8
02:14ibdknoxwitt3rd: it is now: https://github.com/Kodowa/Light-Table-Playground/issues/237
02:14witt3rd:-)
02:15ibdknoxthanks :)
02:15ro_stibdknox - just curious, have you done anything with websockets and cljs?
02:16ibdknoxyeah
02:16ro_stwhat did you use on the backend? aleph?
02:16ibdknoxthough in every case I cheated
02:16ro_stoh, how so?
02:16ibdknoxaleph originally
02:16ibdknoxnow socket.io
02:16ro_stso node.js on the back
02:16ibdknoxI didn't need to support anything other than hcrome
02:16ibdknoxchrome*
02:17ibdknoxYeah, now it's node
02:17ibdknoxaleph worked fine though
02:17ibdknoxdidn't try any scaling with it
02:17Ember-ibdknox: hmm, have I missed something or does the Light Table support function navigation, meaning that I can "dive" into the definition of a function from a call
02:17Ember-similar to ctrl+lmb in eclipse+java or f3 in counterclockwise?
02:17ibdknoxEmber-: not in the current version
02:17Ember-ok
02:17Ember-so I'm not dumb :)
02:18ro_stok, thanks. we plan to go pretty large with websockets and i've seen a fair number of complaints about aleph's overall speed
02:18ibdknoxthough some changes I needed on the CodeMirror side came in that will let me do the function "bubbles" correctly this time
02:18Ember-that's one of the last things preventing me from using it for real
02:18ibdknoxro_st: I wrote a netty-based websocket server previously
02:18ibdknoxthat was blazingly fast
02:18ibdknoxorders of magnitude faster than node at the time
02:19ibdknoxEmber-: just to confirm I understand, you're talking about go-to-definition right?
02:19Ember-yes
02:19Ember-loving light table so far btw, happy I contributed in the kickstarter
02:19Ember-make it shine ;)
02:20ro_stit's going to be so cool once we have websockets and storm drpc set up
02:20ibdknoxEmber-: I'm hoping I'll get to announce a hire or two soon, which will mean that will come even faster :)
02:20ro_streal-time all the things
02:20Ember-I'm pretty sure that six months from here it's light table all the way for me with clojure
02:20Ember-oh really cool
02:21ro_stibdknox: did you ever look at atmosphere? https://github.com/Atmosphere/atmosphere
02:22ro_stlooks like it suports socket.io's protocol
02:22ro_stwe need a jvm solution so that we can leverage datomic's peer caching
02:23brainproxyneed to take a break and play w/ something .. different .. tcl or rebol/red?
02:23ibdknoxro_st: I did not
02:23ibdknoxro_st: when I looked into that stuff (where I actually needed to scale) I'm fairly certain that wasn't well known :)
02:23augustlI prefer (with-thing (fn [thing] .. do stuff .. )) over a macro style (with-thing [thing] .. do stuff ..), am I crazy? :)
02:24ro_stno. functions always compose better than macros!
02:25ibdknoxro_st: this has been gaining some steam lately https://github.com/sockjs/sockjs-client
02:25ibdknoxro_st: and it's got a vert.x impl (JVM)
02:25augustlro_st: that's what I'm thinking too
02:25brainproxythe aleph/lamina guy said he was looking into sockjs
02:26augustlI suppose if it's called a couple of thousand times per second a macro will be faster since you avoid the function call? :S
02:26brainproxybut I haven't seen any movement in that regard, i.e. on his github account
02:27ro_stsockjs looks great
02:27brainproxy"looking into" meaning considering a aleph/lamina based clojure server that would implement sockjs "spec"
02:28ro_statmosphere looks like it's pretty thoroughly battle tested
02:29brainproxyyeah, but i was hunting for a clojure wrapper/bridge to it, didn't see anything
02:29augustlro_st: I prefer to use something like faye instead of socket.io or sockjs, faye uses fewer hacks
02:29brainproxynot that clj java interop is bad, but it's just nice to have idiomatic functional api
02:29augustlsock.io has a lot of pretty nasty hacks in order to get cross origin messaging
02:29ro_stgot a link, augustl?
02:29brainproxyaugustl: faye is cool
02:29augustlro_st: http://faye.jcoglan.com/
02:29brainproxybut ... you're buying into the whole bayeux thing
02:29augustlbrainproxy: yeah I'm using it a lot
02:30augustltrue, but the java comet something project supports it
02:30ivanmost things, including sockjs, think it's okay to reorder or lose data
02:30ivanyou have to think about HTTP for over 10 minutes to see the problem
02:30brainproxyaugustl: right because faye is an impl of bayeux, which is the basis of cometd
02:30augustlro_st: example, if you try to use sock.js in a HTML4.1 frameset document in IE7 or lower, a popup is opened for each request :)
02:30augustland for a project I needed to use a html4.1 frameset doc
02:31ro_styikes
02:31ro_stwe only support modern-ish browsers anyway. ie9+.
02:31augustlthis is mostly because it does really funky stuff to achieve cross origin comapt, I think it submits forms in an iframe or smt
02:31brainproxyivan: socket.io, i think, has an optional ack api that will allow you to implement logic which could avoid reordering and msg loss
02:32ivanbrainproxy: if you take a look at the ack implementation, you find that it's used for some nonsense application-level confirmation, and not used to implement a reliable stream
02:32brainproxyivan: that's what I was going to say next
02:32brainproxy:)
02:32brainproxythe long and short being that it's best to use it in scenrios where lossy notification stream isn't a big deal
02:32ivansomeone wrote a BrowserChannel server for Clojure
02:33ro_stlooks like i have my homework cut out for me. thanks for the options, all
02:33ro_stbrowserchannel - that's in google closure js, isn't it?
02:33ro_stthis, ivan? https://github.com/thegeez/clj-browserchannel-demo
02:33ivanyes. and it is reliable and used by gmail.
02:33ro_sthttps://github.com/thegeez/clj-browserchannel too
02:33ivannot sure if the server is any good though
02:33ivanyes, that's the one
02:34ivanif I had infinite time I would port my Minerva server from Twisted to some Clojure thing
02:34ro_stinteresting. this looks pretty compelling
02:34ro_stwhat we'd be using it for is pretty well defined
02:34brainproxyyeah, but browserchannel is not websocket, right?
02:35ro_stcorrect
02:35ro_sthttp://thegeez.net/2012/04/03/why_browserchannel.html
02:36ivanif you think about the problem for even longer you discover that connection-oriented semantics are pretty crap
02:36brainproxycan't remember if faye websocket guarantees message order
02:36ivanCCNx probably has good ideas
02:36ivanwebsocket does
02:36ivanis faye websocket not websocket?
02:36ro_sti'm open to any solution that allows bi-di browser/server comms on the jvm
02:37brainproxyivan: sorry for confusion
02:37brainproxyfaye is an implementation of bayeux protocol
02:37brainproxyhttp://svn.cometd.com/trunk/bayeux/bayeux.html
02:37brainproxybut bayeux specs http, nothing about websocket
02:37ivanI can't remember what exactly was wrong with bayeux but I think it was in my not-even-wrong category
02:37brainproxyso faye's maintainer implemented his own idea for realizing bayeux over websocket transport
02:38brainproxythat's what i meant by faye websocket
02:38brainproxybut there is a library called faye-websocket which happens to a be just a websocket impl for node.js, nothing to do w/ bayeux
02:39brainproxyivan: cometd is an implementation of bayeux .. i think
02:40ivanlast I checked, yeah
02:40brainproxyimo, the real problem w/ sock, etc. is that devs start to drift into rpc/rmi mindset
02:42brainproxyand so create opaque "pipes" for data transport, when they would be better off using rest/hypermedia principles for their web apps/apis
02:42ivanthe content-centric networking talk is a must-watch
02:43ivanthe only problem is that it's much harder to design such a thing than dumb pipes
02:43ro_stwe're using event sourcing for our client side data and persistence models
02:43ivanhttp://www.youtube.com/watch?v=oCZMoY3q2uM
02:43brainproxyhave your read amunsen't "hypermedia oriented design"?
02:43ivandon't think so, I'll check it out
02:43brainproxy*amundsen
02:44ro_stright now it's one way over ajax. we want to use bi-di to allow events to come back into the browser from the server, so that, eg, users can collaborate in a workspace
02:44ro_stsame events as normal, just coming from a different place
02:44brainproxyivan: http://amundsen.com/articles/hypermedia-oriented-design/
02:44ro_stivan: Datomic has rest api, so right now :-)
02:45brainproxyivan: also see http://amundsen.com/hypermedia/profiles/
02:54augustlso.. I have a bunch of IO objects, separate ones for writing and reading. As soon as someone writes to the writing one, the associated reading one should die, but not until existing users of the reading one are finished. Suggestions? :)
02:54augustlI'm thinking plain old reference counting, but perhaps there's something more clever I can do
02:55augustlalso, if someone writes, and two readers are still alive, and a new read request comes along, that request should get a new reader, not the old one
02:59amalloyso like...(let [io-objects (ref (repeatedly make-new-io-object))] (defn reader [] (first @io-objects)) (defn writer [] (dosync (let [ret (reader)] (alter io-objects rest) ret)))), augustl?
03:01augustlamalloy: sec, interpreting :)
03:01augustlamalloy: hmm, don't think so. I should probably have explained it better..
03:02augustleach read happens via http requests so they are completely stand-alone. So I'm thinking a (with-reader ...) type macro that does reference counting
03:05callenI feel like this is going to be really dumb, but I'm going to ask anyway
03:05callenif I have a function returning [ [] [] [] ]
03:05callenand its result is going inside of another vector, how do I splice the sub-vectors into the enclosing vector?
03:06augustlcallen: mapcat does this
03:07augustlmapcat is for mapping _and_ concatenating in one go though
03:07callenI don't need to map.
03:07callenI think the answer to my question was concat.
03:08augustl,(reduce concat [[1] [2] [3]])
03:08clojurebot(1 2 3)
03:09mthvedt,(apply concat [[1] [2] [3]])
03:09clojurebot(1 2 3)
03:09augustlah
03:10mehworkwhat's the proper way to return true from a defn?
03:10amalloytrue
03:10mehworkah no parens
03:11amalloyparens are always for calling functions
03:29ro_stand for list literals, when quoted
03:29ro_st'(:a :b :c)
03:32borkdudeor inside macro's, like ns
03:32ro_styes
03:33borkdudeusually return true or false from a function involves a decision which has already the value true or false, so that can be returned
03:36bbloomor (boolean that)
03:36bbloomwhich i'll sometimes do to prevent callers from taking a dependency on the fact that i just happened to use 'or or 'some to implement my function
03:38mehworkin a cond check how do you use a function that returns boolean as a test? cond (is-whatever "arg1") (println "yep") gives an error
03:38callenis there a good/established way to manage application configs in Clojure? particularly when handling prod vs. local/testing
03:39ro_stcallen: we use env vars
03:39ro_stonly sane way. config in the git repo is a bloody pane
03:39ro_sts/pane/pain
03:39ro_sthttp://www.12factor.net/config
03:39bbloomi always prefer env vars plus a separate config repo
03:39bbloomthe config repo contains config for all deployed software
03:40ro_stwe have a pallet repo which has everything
03:40ro_stso i guess i concur :-)
03:40bbloommehwork: what error do you get?
03:40callenoh I see, this is for people terrified about configs getting into source control
03:40bbloomcallen: no, i want my configs in source control
03:41bbloombut configs are a separate concern since they span multiple versioning boundaries
03:41ro_styes. because it's a pain with multiple servers (prod/test/dev/dev/dev)
03:41callenI never really had that much of a problem with it.
03:41bbloomit wasn't an issue for us until we had 5+ smaller programs, each in it's own language
03:41bbloomthen env vars became the only sane approach
03:41callenin Python/Flask we used settings.cfg for prod, test_settings.cfg for local dev, staging_settings.cfg, experimental_settings.cfg, etc
03:42bbloomand we were duplicating config per project
03:42callenand pointed at each file based on ENV var.
03:42bbloomyeah, only need a small handful of env vars
03:42callenjust the one, for us.
03:42bbloomoften YOURCO_ENV is enough
03:42ro_stthe solution we have is one that we no longer need to think about
03:42callenit didn't require any thought on our part either.
03:42bbloombut sometimes YOURCO_HOST and a few others are nice to have
03:43bbloomfor app-specific, deployment-independent config: by all means, put that in your repo and check it in :-P
03:44ro_sthttps://www.refheap.com/paste/7773
03:45ro_stworks nicely for us
03:47mehworkbbloom: unable to resolve symbol "arg1" in this context
03:47bbloommehwork: refheap your code
03:48mehworkfixed now, it was a typo
03:48bbloomheh
03:48mehworkrefheap?
03:48clojurebotrefheap is gist
03:48tomojlol
03:48bbloom~pastebin
03:48ro_strefheap.com
03:49bbloom~paste
03:49bbloomclojurebot seems lazy
03:50tomojgrr.. I want to make my cljs port of clojure.test support asynchronous tests, but it uses a bunch of dynamic variables
03:51bbloom:-/
03:51bbloomtomoj: so i think most async test frameworks out there are pretty terrible
03:52tomojspecifically in the way they handle async?
03:52bbloom90% of the time, tests don't need any branching or looping, so you can write asynchronous tests synchronously by queuing every side effect and assertion, then having a test timeout
03:52bbloommuch more pleasant than (expect n-asserts) etc
03:53tomojetc includes calling a callback to indicate that you're done?
03:54tomojwouldn't that mean you have to wait for the timeout on every test? if the timeout is pretty short, maybe not so bad
03:54bbloomit's a little harder in a more general context, but skrenzel has an awesome coffeescript browser integration test library that he refuses to find the time to open source.... i'll convince him to do that eventually
03:55bbloomtomoj: you can run async tests in parallel, so timeouts are overlapping
03:57tomojand then you need some way to say "this test isn't safe, don't run it in parallel"?
03:58tomojwell I'm thinking of browser integration tests there, but you can't really do that with cljs.test anyway
03:58bbloomi haven't thought about the general case of unit tests deeply enough. with browser integration tests, you have a limited set of operators like click, fill, navigate, send_keys, etc
03:59bbloomand all those operators do is queue.append
03:59bbloomand you also have operators like assert_location, has_text, etc
03:59bbloomnone of those operators take callbacks
04:00tomojbetter not have those running in parallel, though, right? unless you have multiple browser windows, one running each test?
04:00bbloomright
04:00bbloomtomoj: example asynchronous integration test https://gist.github.com/4351531
04:01bbloomworks super smoothly & is blazing fast
04:01bbloomusing the queue strategy
04:02bbloomwe had 100+ of those tests & our non-programmer CEO wrote most of them via copy paste :-)
04:04bbloomother than things that were integration testable, we had very little async javascript
04:05tomojnice, even cucumber doesn't claim to be ceo-writable :)
04:06bbloomenglish is a terrible programming language :-P
04:06bbloomto be fair, our CEO was smart enough to learn and ultimately prefer both HAML and SASS
04:07bbloomanyway, if you're doing an async testing framework in cljs, consider the queue approach! would love to see what you come up with :-)
04:07augustlhmm, I need to create I/O objects inside dosync, does that make any sense at all? If the transaction runs multiple times I'm in trouble since I'll end up with unclosed IO objects
04:08tomojmy first tendency is to just write tests that return promises
04:08bbloomaugustl: describe your use case and why/how you elected to use refs
04:09augustlit's probably easier if I describe my overall goal, paste coming up
04:09bbloomtomoj: as useful as promises are, i think this idea of "let's use promises all the time every time!" is flawed
04:09bbloomi'd prefer a very limited async api surface
04:09bbloomwhich is difficult if you have a REST api or similar
04:10bbloombut even if you have a single api-call central point, you can use it in lots of places, and so have lots of promises
04:10tomojin cljs.test I just imagine being able to do (deftest foo [done] (js/setTimeout #(do (is (= 42 42)) (done))))
04:11tomojthen a promise library (which is what I'm testing) can I guess provide its own deftest that expects the test to return a promise
04:11bbloomsounds reasonable
04:11tomojin the queue approach, I guess if a test times out with no assertions, that's a failure?
04:12callenbbloom: re: HAML/SASS -> fairly analogous to hiccup/clj-style.
04:12bbloomtomoj: yes
04:12bbloomtomoj: but you also need to handle assertions coming after the timeout has already expired: also a failure... a *perf* failure :-)
04:13bbloomcallen: i'm aware
04:13callenbbloom: just humming. Hacking on a ring app right now.
04:14callenbbloom: using hiccup, contemplating the merits of clj-style.
04:14bbloomcallen: did you also evaluate https://github.com/paraseba/cssgen ?
04:16tomojI wonder if it acceptable for a cljs bound-fn stopgap to ignore set!
04:17augustlbbloom: https://www.refheap.com/paste/7775 - or anyone, not just bbloom :)
04:17bbloomtomoj: you mean with respect to root bindings vs dynamic bindings?
04:17tomojyeah
04:18augustlmy problem is the "TODO" part. As soon as someone writes to the index, I want to expire the index reader so new calls to with-index-reader creates a new one. But when all existing parallel users of with-index-reader ends, I need to close it
04:18augustlsince it's an I/O object
04:18bbloomaugustl: you're only altering a single ref in each transaction. why not use atoms?
04:18tomojsince cljs will allow you (?) to do (binding [*foo* 42] (set! *foo* 43) ((bound-fn *foo*)))
04:18tomojfor which a stopgap will return 42
04:18augustlbbloom: can I use atoms for atomic "get or set"?
04:18bbloom(doc atom)
04:18tomojbut people shouldn't be doing that anyway :/
04:18clojurebot"([x] [x & options]); Creates and returns an Atom with an initial value of x and zero or more options (in any order): :meta metadata-map :validator validate-fn If metadata-map is supplied, it will be come the metadata on the atom. validate-fn must be nil or a side-effect-free fn of one argument, which will be passed the intended new state on any state change. If the new state is unacceptable, the validate-fn should return fa
04:19bbloomthat's not a super helpful doc string if you don't knwo what an Atom is :-P
04:19augustl:)
04:19augustlI thought all operations on atoms were outside a transaction
04:19bbloomaugustl: http://clojure.org/atoms
04:19augustlsince you call "swap" without dosync
04:19augustlthat is, you don't need to put it in a transaction
04:19bbloomso 90% of the time, you want an atom
04:19augustlso atoms can do atomic "get or set"?
04:20bbloomthe purpose of an atom is to do atomic compare-and-swap
04:20bbloomvia ##(doc swap!)
04:20lazybot⇒ ------------------------- clojure.core/swap! ([atom f] [atom f x] [atom f x y] [atom f x y & args]) Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side ef... https://www.refheap.com/paste/7776
04:20bbloomthere's a sort of implicit "transaction" around f
04:20augustlI see, so I could pass my own function that gets or sets?
04:20bbloom,(let [x (atom 10)] (swap! x + 5) x)
04:20clojurebot#<Atom@4a1bb681: 15>
04:21bbloomaugustl: right
04:21bbloomalso available ##(doc reset!)
04:21lazybot⇒ ------------------------- clojure.core/reset! ([atom newval]) Sets the value of atom to newval without regard for the current value. Returns newval. nil
04:21augustlmakes sense, the values inside the function you pass to swap doesn't need to be derefed so they're in a transaction
04:21bbloomyeah
04:22augustlstill not quite sure how to handle all my side effect-y IO objects, and I now see that my paste is kind of messy and doesn't really showcase my problem, so I need to think about this some more ;)
04:22bbloomrefs are for when you have to coordinate writes between multiple mutable places
04:22bbloomand even then atoms are often better if you can get away with a map inside an atom
04:22augustlbbloom: I think I might need to coordinate multiple state changes though
04:23augustlas soon as someone gets an index writer, it's associated index reader should be tagged as "please die"
04:23augustlthen as soon as all current users of the index reader (via with-index-reader) finishes, it should be closed
04:23augustlhmm, that's just one state change :)
04:23bbloomhmm what are the ownership semantics of a writer?
04:24bbloomhow many/which threads are responsible for IO?
04:24augustlbbloom: index writers stay alive forever. Then HTTP requests comes in and reads and writes.
04:25augustlso it's very side effecty indeed, since individual threads/http requests will read and write in any order at any time
04:25bbloomthere can be multiple simultaneous writers per index ?
04:25augustlno, just one writer per index
04:25augustlbut multiple calls to the same writer. That is handled by the writer code though, it's thread safe
04:26bbloomhm, generally, i try to isolate IO to a small number of workers and communicate with them
04:26bbloomparticularly for network, one IO thread is often enough for a gigabit
04:26bbloombut disk IO is different....
04:27bbloomhow many indexes do you expect to have?
04:28augustlbbloom: a bunch, there's one index per main domain object in my system
04:28bbloomaugustl: so on the order of a dozen?
04:28augustlprobably not more than hundreds or so per server though
04:28bbloomhm
04:28augustls/server/process
04:28bbloomhave you considered an agent per index with async writes?
04:28augustlgo on :)
04:29augustlah, I think I see what you mean
04:29bbloomyou basically have one atom which is a map of domain object -> table manager
04:29bbloomthe table manager is an agent which is basically the current state, read/write/etc
04:29bbloomand you send messages to the appropriate agent to perform IO
04:30bbloomthis way you use a swap! on the db atom to load a table
04:31bbloom(send (@db :foo) some-write-operation bar) ; might be send-off, i can never remember which is which
04:31augustlhmm
04:32bbloomfor reads, you can pass the agent a promise and then block on that
04:32augustlmight as well make my lucene indexing eventually consistent :)
04:32bbloomqueues and messages: damn good ideas that more people need to employ more often :-)
04:34augustlconsidering using elastisearch instead.. Spending time on lucene details is not important for my business :P
04:35bbloomalso valid :-)
04:35augustland it makes my system composed of simple services, yay
04:37bbloomi'm not sure i like the name "simple service"
04:37bbloomi'd call them "utility services" in the same vein as utility functions and utility programs
04:37bbloom:-)
04:38augustlhmm, I don't think of queues and full text search systems and databases as utilities
04:40bbloomwell they certainly aren't simple! :-)
04:44ro_stcomplections? :-)
04:45augustldatomic comes close, but I actually couldn't use it in my project since the datomic-free peer library fails to load since I depend on lucene 4 :)
04:45augustlso I suppose that means datomic complects my app with the datomic peer or something like that? :P
04:47augustlnot sure what the actual problem was though.. When I removed my lucene 4 dependency, leiningen downloaded lucene 3.6. So I guess datomic just needs an explicit dependency on 3.6 since it seems to just use lucene 4 when it's available.
04:48tomojthat sucks
04:49augustlI posted on the mailing list, hopefully it will turn out to be my problem. It probably is, since I'm new to all things JVM!
04:49tomojseems like there should be a way to deal with that, which doesn't involve OSGI cus wtf is that
04:50augustlspeaking of elastisearch. Are there any libraries I can use that manages the http details for me? Retries, keep-alive connection pooling, etc
04:52tomojclj-http has both of those features
04:53augustlah
04:54augustlhmm, I'll be doing my http calls inside ring request handlers. Should I just wrap my entire handler in a middleware that does with-connection-pool?
04:55augustlsounds dangerous though, since then it probably applies to all calls to clj-http that might happen in libraries etc
04:55tomojoi
04:55augustlso some out of sight pool would be nice
04:56tomojand of course the only way to pass it in is with the dynamic var
04:56tomojoi
04:56augustl:(
04:56augustlI hate it when libraries does that!
04:57tomojfairly easy patch it seems though
04:57augustlI could just bind it on every call I do, since I have one thread per request anyway
04:57augustllike, (with-connection-pool my-global-pool do-stuff)
04:57tomojexcept with-connection-pool is even less usable than that
04:58augustlI meant my own with-connection-pool, sorry
04:58augustlwhere I manually set the binding
04:58tomojah, I see, yeah
05:00augustlcomplects my system with ring handlers though.. I might not always have one thread per business logic operation, meh.
05:01augustlsuppose I could just use the Java lib from apache directly
05:03augustlseems that irccloud.com is down :)
05:03tomojI don't think it should be hard to patch clj-http to just accept a conn manager in the request
05:03augustlonly problem would be if it already makes use of arity dispatch
05:06tomojnah it's a big map https://github.com/dakrone/clj-http/blob/master/src/clj_http/core.clj#L179
05:06augustlah, nice
05:06augustlI'll put it on my TODO list for the evening :)
05:08tomojwould be nice to also split with-connection-pool up to make it easier to get ahold of a conn manager
05:08tomojhmm
05:08tomojhttps://github.com/dakrone/clj-http/blob/master/src/clj_http/client.clj#L726
05:09tomojwat?
05:09clojurebotFor Jswat: start clojure with -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888
05:12augustltomoj: :D
05:12augustlhmm, just passing the connection manager in with the map makes sense, in order to not mess with arity
05:13augustl(http/post "http://foo.com&quot; {:connection-manager my-manager})
05:14augustlone of the lessions I've learned in my 4-5 months as a Clojure programmer, is that complex encapsulation really sucks.
05:21ro_stwould you go back to your previous language(s)?
05:25clgvhow do I "freeze a snapshot to [a] dated version" in leiningen?
05:25augustlro_st: I still program a lot of user interfaces, mutable single threaded environments are still status-quo there..
05:25augustlro_st: building systems with OO would be extremely painful now though
05:27ro_st+1.
05:27ro_stto think i was going to use Rails for the backend -shudder-
05:29augustlI'm writing a rails app nowadays too actually, but I think of it as a front-end only. Most of the core business stuff is on the JVM (integration with 3rd party invoicing system, etc)
05:33ro_stcondolences
05:34fredyrhow are you integrating your rails app with the jvm?
05:35fredyrrunning a queue inbetween?
05:36augustlfredyr: yup
05:36augustland the JVM stuff writes directly to the same postgres db
05:36fredyrnice
05:36fredyrwhich queue?
05:36augustlhaven't decided yet :)
05:36fredyri've been working with rabbit lately
05:37ro_strabbit is nice
05:37fredyri can recommend that one
05:37fredyryeah definitely
05:37fredyrand the bindings for JVM and ruby are good
05:37augustlas long as it talks something like stomp, it's pretty portable anyway
05:48fredyrok haven't looked at stomp
06:12silasdavisCould someone tell me why (map pretty-message (message/all)) works, (-> (message/all) (map pretty-message)) doesn't?
06:13silasdavisDon't know how to create ISeq from: pretty_message
06:13silasdavisah I thought -> inserts as second argument
06:14cemerickno, -> is thread-first
06:14cemerick->> is thread-last
06:14silasdavisah it is the second element in the list which is hte first argument
06:14silasdavisthank you
06:14cemerickyup
06:14cemericknp
06:14clgvhow do I "freeze a snapshot to [a] dated version" in leiningen?
06:15silasdavisis (->> seq (map f) (map g) (map h)) an idiomatic way of chaining maps?
06:15silasdavisis there a better way?
06:16bprsilasdavis: you could do (map (comp h g f) seq)
06:17silasdavisoh of course
06:17silasdavisthanks
06:17bprsure thing
06:18bprbut on the other hand if there are reduces and filters, etc. the threading macro can be nice
06:32acron^is there some short hand for this?
06:32acron^.(map #(str %) (seq "Hello, World"))
06:32acron^,(map #(str %) (seq "Hello, World"))
06:32clojurebot("H" "e" "l" "l" "o" ...)
06:34acron^,(split "Hello, World" "*")
06:34clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: split in this context, compiling:(NO_SOURCE_PATH:0)>
06:36cemerick,(map str "hello, world")
06:36clojurebot("h" "e" "l" "l" "o" ...)
06:36acron^facepalm
06:36acron^thanks
06:37silasdavisI am getting an arity exception from ((fn [m] ([:li (pretty-message m)])) ({:edge 34}))
06:37cemerickyou're invoking the map as a function with no arguments
06:37silasdavisbut fine if I remove the anonymous function and insert the map
06:41silasdavisOh i was trying to evaluate the vector
06:41silasdavisand the map
06:55clgvhow about ##(seq "hello, world")
06:55lazybot⇒ (\h \e \l \l \o \, \space \w \o \r \l \d)
07:09acron^clgv: they aren't strings then
07:09clgvahok. didnt know that was a requirement ;)
07:09acron^:)
07:10acron^turns out string/split is probably more suited to my needs anyway
08:05augustlwhat's a good way to do this transformation? https://gist.github.com/4352622
08:07augustlupdated it slightly, the original maps can have multiple keys
08:10bpr(reduce #(merge-with conj %1 %2) {} data) seems like a good start
08:11augustloh neat
08:11augustlbpr: do I really need an initial empty map there?
08:12bprno
08:12bpri usually like to put an explicit initial value though
08:13bpryou may want: (reduce #(merge-with (comp vec flatten conj) %1 %2) data)
08:13augustlaww, that gives me (reduce #(merge-with concat %1 %2) queries) yay
08:13augustljust concat instead of conj
08:13bprdepending on your requirements for the values in the resulting map
08:13augustlthanks :)
08:13bproh or that lol
08:14augustl:D
08:18bprthe concern with concat is that it turns your vectors into lazy-seqs, and then subsequent call to concat will have to walk the entire seq. Not sure if that's what you want
08:18ro_stjust a sanity check: are jvisualvm/yourkit the best way to profile clojure?
08:18augustlbpr: ah
08:19bprro_st: i'm not a jvm pro, but i do know that this exists: https://github.com/hugoduncan/criterium
08:19bprit's a clojure lib for benchmarking your code
08:20ro_stthanks, bpr! this looks handy once you've identified hotspots and you're now working to improve them
08:21bpraugustl: that said, my solution with flatten also walks the vector each time it's called too
08:21bprro_st: no prob
08:22augustlbpr: are there other data structures than vectors that are good for merging?
08:22augustlordering doesn't matter so I could use sets
08:22bpryeah, sets could be a good choice
08:22bprthe concern is the nesting though
08:23augustland then use clojure.set/join probably
08:28bprclojure.set/union
08:28bprthough i'm thinking there must be a way to accomplish that with vectors
08:31bpr(reduce #(merge-with (fn [a b] (apply conj a b)) %1 %2) data)
08:32bprit's cleaner like this: (reduce #(merge-with (partial apply conj) %1 %2) data)
08:33bpraugustl: ^ (in case you missed it)
08:34augustlah
08:34ro_stpartial rocks
09:05clojure-newbhi guys, I'm posting a csv file to Compojure with curl, but having trouble getting just the csv data out of an HttpInput… I'm getting all the 'Content-Disposition' and 'Content-Type; info also… how do I extract just the convent of the file ?
09:06weavejesterclojure-newb: The body of the request is a java.io.InputStream
09:07ro_stgoing to clojurewest, weavejester?
09:07weavejesterclojure-newb: So you can use clojure.core/slurp, or clojure.java.io/reader with clojure.core/line-seq
09:07weavejesterro_st: Not sure. Maybe not - it's a long way away
09:07ro_stcmonnn i'm going, and i'm from Cape Town, South Africa :-)
09:08clojure-newbweavejester: thx I'll look into ways to work with an InputStream
09:09weavejesterro_st: When is it? March?
09:09clojure-newbweavejester: I'm currently doing (slurp (:body req)), and that way I'm getting all the Content-Type stuff I don't want
09:09ro_styes
09:11weavejesterclojure-newb: What do you mean? The content type is a header.
09:17clojure-newbweavejester: I've tried to capture the details in a paste : https://www.refheap.com/paste/7780
09:18clojure-newbweavejester: I am probably not explaining myself very well
09:18clojure-newbbut I'm trying to just get the csv content in my output
09:18ro_stdon't need the reader
09:18weavejesterclojure-newb: No, that paste gives me all the info I need
09:18ro_stjust (slurp (:body req))
09:19ro_stclojure-newb: what if you (println req) ?
09:19weavejesterclojure-newb: With curl you're uploading a file as multipart form data
09:19weavejesterBut you're setting the content-type header explicitly as text/csv
09:19clojure-newbro_st: thx, removed the reader form
09:20weavejesterYou need to first decide whether you're uploading data in multipart format
09:20clojure-newbweavejester: so my curl post is kinda mixed up
09:20weavejesterOr whether you're uploading data directly in the HTTP body
09:21weavejesterYou're basically saying to curl, upload this as a multipart file, but tell the server it's a raw stream of data
09:21weavejestermultipart data can be uploaded through a HTML form
09:21weavejesterWhen you upload a file to a website, that's the format you're using
09:22weavejesterThe multipart stream also contains information about the file being uploaded
09:22weavejesterSuch as its content-type (as determined by the client) and the filename
09:22weavejesterYou can also upload data raw, just by sending the data directly as the HTTP request body
09:22weavejesterWithout any additional encoding
09:23clojure-newbweavejsester: so I am specifying something extra I don't need in my post ? from curl ?
09:23clojure-newbsorry, a little confused
09:24weavejesterclojure-newb: The -F option tells curl to send the file as multipart data
09:25weavejesterYou need to decide whether that's what you want to do
09:25weavejesterPut it another way: what is the intended use for this system?
09:25clojure-newbweavejester: so I could just do curl -v file=@sample.csv -X POST -H "Content-Type: text/csv" -u user:pass http://host:port/context
09:25weavejesterclojure-newb: You want the -d option
09:26clojure-newbweavejester: initially just to upload small csv files to import data into a system
09:26weavejesterclojure-newb: So you can send it as a multipart form, using -F file=@sample.csv
09:26weavejesterclojure-newb: Or you can send it as a raw data stream using -d @sample.csv
09:26weavejesterRing can handle either, but you need to make a choice :)
09:28clojure-newbweavejester: thx for your help, it appears I need to go read up on POST and multipart etc, think I got confused taking it all on in one go
09:29weavejesterclojure-newb: multipart data is a way of uploading one or more files as form data
09:29weavejesterclojure-newb: Usually used in web browsers for uploading files to websites
09:52clojure-newbaww, getting close, can anyone help me with extracting and parsing csv content properly ? https://www.refheap.com/paste/7781 - currently my csv lines are being merged after extracting from request body
09:59bpruse clojure.data.csv: https://github.com/clojure/data.csv
10:11WokenFuryany guesses why I'm running into this stackoverflow with Noir?
10:11WokenFuryException in thread "main" java.lang.StackOverflowError
10:11WokenFury at clojure.lang.PersistentHashMap.seq(PersistentHashMap.java:194)
10:11WokenFury at clojure.lang.RT.seqFrom(RT.java:480)
10:11WokenFury at clojure.lang.RT.seq(RT.java:475)
10:11WokenFury at clojure.lang.RT.keys(RT.java:503)
10:11WokenFury at clojure.lang.APersistentSet.seq(APersistentSet.java:45)
10:11WokenFury at clojure.lang.RT.seqFrom(RT.java:480)
10:11WokenFury at clojure.lang.RT.seq(RT.java:475)
10:11WokenFury at clojure.core$seq.invoke(core.clj:133)
10:11WokenFury at clojure.core$set.invoke(core.clj:3643)
10:12WokenFury at ns_tracker.dependency$seq_union.invoke(dependency.clj:13)
10:12WokenFury at ns_tracker.dependency$transitive$fn__19.invoke(dependency.clj:21)
10:12WokenFury at clojure.core.protocols$fn__5871.invoke(protocols.clj:76)
10:12WokenFury at clojure.core.protocols$fn__5828$G__5823__5841.invoke(protocols.clj:13)
10:12WokenFury at clojure.core$reduce.invoke(core.clj:6030)
10:12WokenFury at ns_tracker.dependency$transitive.invoke(dependency.clj:22)
10:12WokenFury at ns_tracker.dependency$transitive$fn__19.invoke(dependency.clj:21)
10:12WokenFurywoops. meant to be a refhjeap link, sorry
10:17phuffHowdy.
10:18phuffI'm making my first clojure project.
10:18phuffAnd I want it to have some components that are loaded or not loaded based on a config file of some type, but I'm not sure what the most idiomatic way to do that is in clojure :)
10:18phuffleinigen just loads clojure files for it's config, and I assume that's the preferred way of doing it.
10:18phuffBut I thought I'd actually ask somebody first :)
10:22dhmphuff: can you say more about your goal?
10:22hyPiRionphuff: The easiest way is that way, yes.
10:22hyPiRionHave a map in a file, which you read in at runtime.
10:23phuffdhm: So, I'm making a little program that will go and fetch different types of data and make an ebook out of it.
10:23phuffdhm: And I think different users will want different types of data in their ebooks.
10:23phuffSo I want to make a config file so different users can say: "Use these 5 subcomponents in this order to pull data for my ebook"
10:24hyPiRion,(-> "{:db {:pass \"secret\", :user \"bob\"}}" read-string (get-in [:db :pass]))
10:24clojurebot"secret"
10:25xeqiphuff: either ENV vars or a config file
10:25dhmphuff: well, tbh in that case i would just express the union of all dependencies in leiningen's project.clj and call it a day. i don't think there would be significant savings to conditionally loading them at runtime
10:25xeqiI've seen https://github.com/sonian/carica recently for config files
10:25xeqithough I've been using https://github.com/weavejester/environ for the ENV var way
10:25phuffdhm: Ah it's not dependencies so much as I need a place to store the things that the user wants
10:25hyPiRiondhm: Yeah, I read it that way as first, but the leiningen thing was an example
10:26phuffThough I suppose if my program gets really popular (hardy har har) then there might eventually be dependncies.
10:26phuffBut right now it's just "I want to use the following three components that are already part of the program to run the script with"
10:27phuff(trying to find the part in leiningen's source where they read the project map)
10:27hyPiRionphuff: it's easier to read Raynes' Refheap way of doing it
10:27hyPiRionhttps://github.com/Raynes/refheap/blob/develop/src/refheap/config.clj
10:28hyPiRionand https://github.com/Raynes/clj-config
10:28phuffOh that looks neat, hyPiRion
10:28hyPiRionIt's very easy to use
10:44hyPiRionWow, 1.2 certainly is old-fashioned.
10:45hyPiRionStrange defn-rules
10:47TimMcSuch as?
10:50hyPiRion(defn ^:private foo ...) isn't allowed
10:51hyPiRionHas to hook it up like (defn foo "docstring" ^:private [params*] ...)
10:54TimMcOh yeah.
11:59frozenlockI want to print some stuff to the repl. What I want to print will happen in another thread. Based on the last time I mentioned my problem, it seems that *out* doesn't point to the repl when in another thread. Is there a way to change that?
12:01frozenlockWhen still in swank, all I had to do was to `print' or `println' anything. In nrepl however, it's not the case :(
12:01hyPiRionfrozenlock: So when you hit up a thread in nrepl and println from it, it won't show?
12:03hyPiRionYou could try bound-fn - which will keep the bindings from where you define the function
12:04hyPiRionhttp://kotka.de/blog/2010/05/Did_you_know_IV.html
12:05frozenlockThat's what I understood from the last time I asked this question. I might be totally wrong... I have a webserver receiving webhooks. In my code I simply have a `print' to send a copy of the webhooks to my repl so I can see live what's being received (I could send to a log-file, but IMO that would defeat the handyness of the repl..). Anyhow, since I moved to nrepl, I can't see anything.
12:05frozenlock"Did you know about bound-fn?" Well, no :p
12:06llasramfrozenlock: This doesn't get you quite where you want, but should help verify the issue --
12:06llasramfrozenlock: If you start the nrepl server via `lein nrepl :headless`, then connect to it
12:06llasramEr, `lein repl :headless`
12:06frozenlockHmm, rather than nrepl-jack-in?
12:06llasramThe printed messages should end up on that process's stdout
12:06llasramYes
12:07frozenlockLet me try that.
12:07llasramFrom emacs just do `M-x nrepl`
12:07llasramand provide the port the :headless process indicates it is using
12:09hyPiRionBut yeah, from a web server, the bound-fn trick is probably hard to use without modifying the router and thread scheduler manually.
12:09hyPiRionI haven't looked at it though, so may be easier than what I anticipate.
12:09silasdavisWhat's the best way to dispatch in a functin depending on whether I get a single item or a collection?
12:10frozenlockNo, nothing showing up.
12:10hyPiRionsilasdavis: ##(if (coll? [1 2 3]) :coll :no-coll)
12:10lazybot⇒ :coll
12:11hyPiRionIf it's only a yes/no thing then that's the simplest to process for us humans.
12:11hyPiRionfrozenlock: what are you using? compojure?
12:11frozenlocksilasdavis: you might want to look `seq?'
12:12frozenlockhyPiRion: Noir... I'll switch to compojure after this. But it uses compojure in the background IIRC.
12:13llasramfrozenlock: Huh. Nothing showing up on the process stdout?
12:13hyPiRion,(map (juxt identity seq? coll?) ['(:list) [:vector] {:a :map} #{:set}])
12:13clojurebot([(:list) true true] [[:vector] false true] [{:a :map} false true] [#{:set} false true])
12:14hyPiRionmm.
12:14frozenlockNothing in eshell (where I started lein repl :headless), nothing in my *nrepl*, nor in *nrepl-connection*.
12:14hyPiRionWhat a tease. =|
12:17frozenlockhyPiRion: I just discovered pmap with your link, thanks :)
12:17mthvedtin core.clj, calling (concat) returns (lazy-seq nil)
12:17mthvedtwhy lazy-seq?
12:19hyPiRionI suppose it's because concat says it will lazily merge the lists it receives
12:20hyPiRion,(map class [() nil (concat)])
12:20clojurebot(clojure.lang.PersistentList$EmptyList nil clojure.lang.LazySeq)
12:20mthvedt,(type (concat))
12:20clojurebotclojure.lang.LazySeq
12:20llasramfrozenlock: At least for me, I'm able to verify that the root binding for *out* writes to stdout: (binding [*out* (.getRawRoot #'*out*)] (println "goes where?"))
12:20mthvedtmaybe it's to not break things that always expect a lazy seq
12:20hyPiRionmthvedt: yeah, I suppose it is.
12:21ppppauli want to do HTTP mocking/DI in clojure... any ideas?
12:21llasramfrozenlock: Do you get output with that?
12:21technomancyppppaul: requests or responses?
12:22frozenlockllasram: yup
12:22frozenlockOMG
12:22llasramWell then. I have absolutely no idea into what limbo your other lines are going
12:22frozenlockstupid stupid stupid stupid stupid stupid stupid
12:23frozenlockWhen I did what you asked it showed all the received webhooks. Guess I wasn't flushing the lines...
12:23ppppaulresponse mocking
12:23ppppaultechnomancy,
12:24technomancyppppaul: have you tried using with-redefs on your HTTP client defns?
12:24llasramfrozenlock: Oh! I wonder if running under eshell is affecting flushing behavior
12:24ppppaultechnomancy, i haven't tried anything yet cept doing some google searching on http mocking with clojure
12:24hyPiRionllasram frozenlock, yeah, eshell != terminal when it comes to flushing
12:24hyPiRionat least with java
12:25llasramAh, probably not providing it with a pty
12:25frozenlockWow, thanks so much guys! It's aliiive!
12:25technomancyeshell doesn't affect flushing
12:25technomancyunless your java code is checking for TERM=dumb and special-casing it or something
12:25frozenlockI think my mistake was to use print instead of println
12:26llasramOh! Well there we go then
12:26llasramHmm. So: should nrepl servers alter-root-var to make make the root binding of *out* be the REPL output buffer?
12:28technomancyI added that to swank
12:28ppppaultechnomancy, with-redef looks cool
12:28technomancyppppaul: 90% of the time people ask mocking questions, the answer is with-redefs
12:29technomancya common pattern is to close over an atom and redef the function in question to #(swap! received-atom conj %&)
12:29technomancythen once the code in question is run, the atom contains all the args the function has been called with
12:30ppppaulinteresting
12:30ppppauli haven't used atoms yet
12:30technomancymost people go wandering off looking for a "mocking framework" when everything they need is staring them right in the face
12:30ppppaulhaven't used swap either
12:30technomancythey go hand in hand
12:30ppppaulcan i only redef vars that i can see?
12:31ppppaulcan i redef a var in a lib that isn't exposed?
12:31technomancytry it and see
12:31ppppaulok
12:31ppppaul:)
12:31ppppaulhave you heard of midje?
12:32technomancyyes
12:33ppppaulthoughts?
12:34technomancyI don't think it offers much advantage over clojure.test
12:35bprppppaul: a lot of people who know more about clojure than i do seem to like it. I don't b/c it does a lot of "magic" with redefining vars and so forth that often breaks for me.
12:36llasramppppaul: I use it for testing Cascalog queries, but actively dislike its "tests run when loading the test namespace" model. It makes it fiddly to have helpers specific to a test namespace
12:36technomancyurgh; does it really have side-effects at load time?
12:36ppppaulhmmm interesting
12:37ppppaullol
12:37hyPiRionI suppose it's good for TDD
12:38ppppaultechnomancy, can you comment on weather this is a good example of using with-redefs to mock? https://gist.github.com/4354264
12:38hyPiRionBut I'm usually testing to check that the design of the library I design is okay
12:38hyPiRionIt's good to find code smells.
12:39technomancyppppaul: with-redefs-fn is lower-level; use with-redefs instead
12:39technomancyppppaul: typically in a real test you would want to store the value in an atom where you can check it later rather than printing it, but for interactive use printing is fine
12:39ppppaulthe only examples i have are at http://clojuredocs.org/clojure_core/clojure.core/with-redefs those any good?
12:40technomancyyeah that looks reasonable
12:40ppppaul^_^
12:41ghadishaybantry this in your repl: (def ^{:foo (println "HA")} bar 42)
12:41ppppaul##(def ^{:foo (println "HA")} bar 42)
12:41lazybotjava.lang.SecurityException: You tripped the alarm! def is bad!
12:42TimMcInteresting.
12:42TimMcSo, we've seen metadata get eval'd 0, 1, and 2 times.
12:42ghadishaybanI just fixed it on CLJ-1137
12:42ghadishaybanyeah
12:42ghadishaybaninteresting follow up to last night
12:43DaReaper5How do i check {"derp" true} for the existence of the key "herp"
12:43TimMcDaReaper5: contains?
12:43DaReaper5contains? is throwing null pointer error
12:44DaReaper5hmm this might be stupid but if i have nothing set for the else for an "if" that should nto cause an issue
12:44TimMc,(contains? {:a 5} :a)
12:44clojurebottrue
12:44ghadishayban##(let [^{unresolved mysteries} foo 42] foo)
12:44lazybot⇒ 42
12:45TimMcDaReaper5: (if x y) is the same as (if x y nil) (or (when x y))
12:45ghadishayban##(let [^{:key (throw (Exception. "hurt me"))}  foo 42] foo)
12:45lazybotjava.lang.RuntimeException: Unable to resolve symbol: foo in this context
12:45ghadishaybanoh strange
12:45technomancyghadishayban: clojure doesn't treat non-breaking spaces right IIRC
12:45technomancy" foo"
12:45technomancyI opened a bug for it and it was wontfix'd
12:46TimMc,(let [^{:key (throw (Exception. "hurt me"))} foo 42] foo)
12:46clojurebot42
12:46TimMctechnomancy: That's rather infuriating.
12:46DaReaper5http://pastebin.com/m1zdctfM
12:47DaReaper5there is a snipit of my code
12:47DaReaper5(simplified kinda)
12:47TimMcclojurebot: nbsp is http://www.trygve.com/doomsday.html
12:47clojurebotc'est bon!
12:47technomancyTimMc: I had a ridiculous hack that was foiled by that bug involving problems in cygwin's escaping and using clojure.main -e with an arg that cygwin would parse as a single token but Clojure would parse as multiple
12:47TimMcOh yeah, I think I remember that. Horrifying.
12:48DaReaper5TimMc (contains? {"derp" true} "display") is causing my error
12:48DaReaper5:/
12:48TimMc,(contains? {"derp" true} "display")
12:48clojurebotfalse
12:48TimMcNot by itself it isn't.
12:49TimMc,(->  foo quote name count)
12:49clojurebot4
12:49DaReaper5http://pastebin.com/3EjtEZ8n
12:50DaReaper5hmm i might have an idea
12:50DaReaper5if false then does the if return null
12:50hyPiRionYeah, those spaces man
12:50hyPiRion,(let [a 10, a 9] {a 1, a 2})
12:50clojurebot{10 1, 9 2}
12:50xeqiany recommendations on a full text search library?
12:50TimMchyPiRion: AAAAGGGHHH
12:51hyPiRionTimMc: ?
12:51TimMcDaReaper5: Check my message of 6 minutes ago.
12:51DaReaper5TimMc i have only been here for like 3 min
12:51DaReaper5i see now
12:52DaReaper5dam
12:52TimMchyPiRion: Somehow that was even more visually terrifying than the example I posted.
12:52hyPiRionI have this lovely Norwegian keyboard, which contains the key "Alt Gr". Whenever I hit that one and space simultaneously, I get these lovely spaces all over. It's a complete mess to debug too.
12:53technomancyhttp://dev.clojure.org/jira/browse/CLJ-419
12:53DaReaper5TimMc is there a way i can specify the if on else to do absolutly nothing?
12:53DaReaper5not even pass null?
12:53TimMchüÖíËíóñ° Í há®é ñó íðéá åháþ üóú´ëé þáøœíñg ábóúþ. °¥
12:53technomancyxeqi: other than lucene you mean?
12:53DaReaper5i think the null being passed is fucking up my parent method
12:53DaReaper5... which is actually just a sql query builder
12:54TimMcDaReaper5: It's an expression, just like (almost?) everything in Clojure. It has a return value. What shall the return value be?
12:54xeqitechnomancy: as in I know very little about fts other then lucene,solr,and such exists
12:54xeqiand easy ways to use it from clojure / score things
12:55TimMchyPiRion: ^ my keyboard is set up with an AltGr as well.
12:55jkkramerxeqi: I think elasticsearch or solr are the go-to solutions these days
12:55jkkramerxeqi: there's an elasticsearch clojure lib
12:55technomancyxeqi: lucene is pretty much the gold standard in the industry for full-text search
12:55hyPiRionTimMc: ←↓→ :D
12:56technomancysolr and elasticsearch are just ways of making lucene indices that span multiple machines
12:56technomancy"just"
12:56hyPiRionIt's handy for those times i need a µ or a π without going to a character map
12:56TimMcHmm, AltGr + space doesn't give me U+00A0.
12:56hyPiRionWhich is possibly once a year.
12:56hyPiRionTimMc: lucky bastard
12:57technomancyM-x ucs-insert
13:10hyPiRionI find myself using (fn [a b] (f (g a) (g b))) quite often, is there a function within core which takes f and g and produces such a fn?
13:10technomancyI bet useful has something
13:11hyPiRionRight, I'll have a peek there. Though I don't like to depend on such a huge set of fns for such a small thing.
13:11hyPiRionOh well
13:13ppppaultechnomancy, i'm running my project off a SAAS and they want me to go back to lein 1.7 instead of 2 (which is what i'm developing on)... any thoughts? seems like a pain to go back to 1.7 since plugins are installed differently and my project file would need to be changed.
13:18technomancyppppaul: 1.7 is pretty outdated. who is it that's stuck on it?
13:19DaReaper5TimMc ok i know exatly my issue right now, a third party library i am using cannot except nil.
13:20DaReaper5I am trying to check a value and if it exists then i indicate a field to be used in a query
13:20DaReaper5either i need a way of check and doing absolutly nothing if it does not exist
13:20DaReaper5or i need a way of building an array
13:21DaReaper5but i cant do that because data structure are immutable
13:21DaReaper5Here is what i want to do in plain english: "If field exists, include/use field name"
13:27ppppaultechnomancy, vmfarms. they aren't used to clojure
13:28ppppaulthey think that 1.7 is the latest stable branch
13:30technomancyppppaul: that's a technicality. if it helps you can send them to https://github.com/technomancy/leiningen/commit/14f566bd5738cba44e692131fb81cdfbc67f28b2#L1R83
13:32technomancyor you can tell them I said they're wrong =)
13:33technomancyalso relevant is that the only mention of 1.x on leiningen.org is a link titled "Still using 1.x?"
13:35ppppaulthanks a lot :)
13:48bprtechnomancy: i'm glad you mentioned the "useful" library earlier. I'd never heard of it, and it contains some really cool stuff.
13:52technomancyyeah lots of good stuff in there
13:53technomancyamalloy_: are there docs for it?
13:57hyPiRionIt's hard to dig through to try and find the fns you need
13:57hyPiRionOr well, it's not apparent
14:09unlinkIs there a function/macro which is like: (fn [x & rest] x) i.e. that discards all arguments but the first (for side effects)
14:12llasramunlink: Oh, like Scheme/CL `prog1`? AFAIK there isn't one in the Clojure standard library, no
14:13llasramwtf, CL has `prog2`? When would you ever want that?
14:15daimrodllasram: retro-compatibility with older lisp dialects I guess.
14:17technomancyunlink: comp first list maybe?
14:18technomancyunlink: if you want a macro try doto
14:20unlinkyeah, prog1 is what I want, not doto.
14:20unlinkthanks.
14:24technomancyhuh; apache's sshd is still maintained
14:24technomancythough its web page has no CSS applied
14:26mehworkanyone know why clojure would give me the error: Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String ?
14:26mehworkin a repl i clearly can convert a long to a string
14:26mehwork,(str 1)
14:26clojurebot"1"
14:27amalloytechnomancy, hyPiRion: not much comprehensive documentation for useful. i'm not sure how you would document "a collection of utility functions" any better than listing all the function names and docstrings which, of course, is in the source already
14:28technomancyamalloy: ns-level docstrings?
14:29amalloy(ns ^{:doc "Functions for working with maps"} useful.map)?
14:29amalloyanyway, if (fn [f g] (fn [a b] (f (g a) (g b)))) were in useful it would be in useful.fn, but i don't think it is
14:29technomancyat least use proper docstring syntax =)
14:30llasrammehwork: That's not the same thing. ##(symbol (str 1))
14:30lazybot⇒ 1
14:30llasrammehwork: That's not the same thing. ##(symbol 1)
14:30lazybotjava.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
14:30llasramEr, didn't mean to repeat "not the same thing" twice
14:30llasramBut you get the idea
14:31llasrammehwork: Something which ultimately calls a java method expecting a particular type will throw a ClassCastException when getting the wrong type
14:31hammerthis has to be so easy: how do i re-run my last statement in counterclockwise?
14:32hammer(yes, i tried hitting up arrow)
14:33TimMchammer: Hmm, try ctrl-up?
14:33TimMcOr C-p I guess.
14:33hammerhaha
14:33mehworkllasram: interesting
14:33hammerthe ctrl -> command switch is still getting me
14:33jlrI'm curious enough to ask this cursorily now, but a full discussion will require a forum post... given the experience implementing ClojureScript, how plausible would it be to follow the same model but make Emacs Lisp the direct host of the language - rather than an extension language akin to pymacs or even guile, making it as easy as doing (require 'cl) and using the clojure interop style to call elisp functions?
14:33hammer(inc TimMc)
14:33lazybot⇒ 28
14:33TimMchammer: Was C-up?
14:33hammerctrl + up worked
14:34technomancyjlr: you would have to choose between seamless interop with existing elisp mutable types and having a proper equality predicate
14:34technomancythe two are mutually exclusive
14:34TimMctechnomancy: No 2.x release yet?
14:34jlrah, that's unfortunate
14:34technomancyjlr: I blogged more about it here: http://technomancy.us/159
14:34jlrobviously everyone would love a Clojure based Emacs
14:35jlrthank you for the link, I will certainly read it
14:35technomancyTimMc: no, library maintainers aren't pushing their libs to the clojars releases repo
14:35technomancyslackers
14:35jlrOf course you and the other Relevance people have contemplated it already ;)
14:35TimMctechnomancy: How does that block lein 2.x?
14:35technomancyI'm not a relevance guy
14:35brainproxyjlr: have you seen the deuce project?
14:35jlroh, I thought you were
14:36technomancynah I work for Heroku
14:36TimMcjlr: They *should* pay him.
14:36jlrI know who you are. Just assumed since you're one of the fundamental members of the community, you were part of relevance *laughs*
14:36jlrI would certainly agree. For lein and many many other contributions.
14:36jlr(TimMc)
14:37technomancyjlr: I don't actually work on Clojure itself
14:37jlrbrainproxy: no, I'll google it.
14:37jlrI consider your contributions to its ecosystem very much fundamental :) But not Clojure itself eh? Interesting. Well your tools are great.
14:37technomancyTimMc: everything will break if people start dropping the clojars snapshots repo before the releases repo is populated
14:37brainproxyjlr: https://github.com/hraberg/deuce
14:38brainproxy"emacs under clojure"
14:38TimMctechnomancy: Hmm, not familiar with this.
14:39technomancyIMO deuce goes the wrong way; there's too much existing code out there building on the quirks and undocumented behaviour of the existing elisp runtime for moving it to a new one to be feasible
14:39jlrAh ha. I had thought about this too at one point. Could you replace the C part of Emacs and just write a full elisp interpreter/compiler in Clojure and somehow succeed at that. I wonder if you could 'wall off' elisp into its own mutable world and then extend with clojure from where we are onward
14:39technomancyjlr: some people think it's possible and are trying to do it with Guile (which does have immutability)
14:39jlr(brainproxy. sorry - will address nicks properly. It's early)
14:40jlrWell, you guys are the ones who can if anyone can. I'm not up to that sort of level this early in my career.
14:40technomancythat effort is much more likely to succeed than a version on Clojure, but I think the odds of it actually being able to run extant elisp libraries are very slim
14:41jlrIt's such a tough thing, there's such a vast amount of Emacs in Emacs that reimplementation in full form seems crazy. But if we could get a more Genera-style environment with graphics+text but follow the Emacs way... Something so incredible could be built with this language.
14:41brainproxytechnomancy: yeah, i'm not sure deuce will actually succeed to any degree, but I was just pointing out to jlr that such a project exists
14:41TimMctechnomancy: Found it: https://groups.google.com/forum/?fromgroups=#!topic/clojars-maintainers/d8HNd-R4uw8
14:41technomancyjlr: people have tried to hoist it onto the CL runtime several times and they never got anywhere
14:41jlrI wonder what it would actually take financially to pay a few people to work full time to translate existing elisp libraries to Clojure like crazy, to tool up a new reimplementation of Emacs with enough stuff to pull people over
14:42jlrtechnomancy: I've read about those efforts. It's a tough thing for sure, people keep taking stabs at it and not succeeding
14:42technomancya clj->elisp compiler would be much less work, but you'd have to add immutable lists and strings to the Emacs runtime first
14:43technomancyimmutable strings in emacs are not completely out of the question according to the maintainers.
14:43technomancyI've asked them about it and apparently it wouldn't break much
14:43technomancyimmutable lists are way harder
14:43technomancyplus elisp doesn't really have the means of abstraction to do a proper self-hosted thing
14:43frozenlocktechnomancy: any chance to see immutable strings in the next.. 2 years?
14:43jlrAs I think of it - given what was done with Climacs, trying to do something sort of akin to that - custom GUI from scratch done the Clojure way, up to the point of an Emacs-like editor in Clojure - plus translation of a few hundred major elisp libs to Clojure... Do you have any thoughts about what that would take to pay to make happen? Could it be kickstartered?
14:44technomancyfrozenlock: it's never going to happen unless someone really cares about it and pushes through on it. and that someone would have to know C.
14:44jlrHire a few of the best, maybe even try to get Relevance and Rich himself to consult some
14:45technomancyit's a lot of work for little benefit; without immutable lists it's not really that valuable
14:45technomancyjlr: there was a summer of code proposal for that, but it wasn't accepted
14:45jlrwow, that's sort of a tragedy..
14:46technomancyI don't think it's a good idea
14:46jlrI still think given what we saw with Light Table it's not out of the question to kickstart it
14:46jlrreally?
14:46technomancyyou're never going to come close to competing with emacs for breadth of available libraries
14:47frozenlockWithout counting everyone's personal code...
14:47technomancywho's going to port magit, org-mode, gnus, etc?
14:47technomancygnus itself is larger than any public OSS clojure project in existence
14:47jlrI guess my image of it is to be more expansive, move emacs towards having more graphical command-line like qualities, interactions you can't do now, and just everything you could do if you wrote Emacs now
14:47technomancyand that's just a tiny slice of what's out there
14:47jlrOh my gosh, they're that big, I see
14:48ohpauleezand it's going to introduce another barrier for adopting Clojure- "I have to learn this new editor if I want the best support?"
14:48jlrI mean my own dot-emacs is like 4k lines so I understand, but I'd hoped if you reach critical mass people would see it as worth the effort
14:48jlrAh, good point as well
14:48ohpauleezNonethelss, writing an editor is a great learning experience
14:48ohpauleezso if you're interested, totally go for it!
14:48technomancyit's an inconceivably huge amount of effort for a tiny community like clojure
14:49jlrI lack anything resembling the technical skill to succeed at writing a new Emacs ;)
14:49jlrI see. Well, perhaps some day.
14:49technomancywriting just an editor of course is feasible
14:49jlrThanks for all that
14:49technomancybut you're talking about an entire OS
14:50jlrExactly - an entire OS is precisely what I want, in Clojure. Heh. Yes, that is getting ahead of ourselves by a few years...
14:57Netfeedwhat's the best way to convert something like f(x) = x + x to something like (defn f [x] (+ x x))?
14:58frozenlockNetfeed: if it's for math/analytics stuff, incanter allows you to use infix notation
14:59Netfeednono, parsing text
14:59dnolenNetfeed: write a parser?
14:59dnolenNetfeed: or use an existing Clojure parser - there are a few
15:00Netfeedalright
15:00frozenlockBig move... from Noir to compojure. Any advices/tutorials?
15:01technomancyfrozenlock: did you see the refheap port raynes posted?
15:01frozenlockLooking at it now in fact.
15:05bosiedoes anyone have a lib/idea how to detect binary files?
15:05bosieor rather: a tool detecting html files?
15:05frozenlock*.html :-)
15:06bosiefrozenlock: i don't have the filename ;)
15:06amalloybosie: just use the unix `file` command
15:07bosieamalloy: that seems a bit counterproductive, no?
15:07bosieamalloy: in the sense you can't run it on windows anymore
15:07bpri'd call that productive lol
15:08bosiehaha
15:09TimMcThere's always Apache Tika, I guess.
15:09TimMcI think it uses the same database as file.
15:10bosiehm
15:13TimMcecho "MOVIE REVIEWS" | file - ## /dev/stdin: Silicon Graphics movie file
15:13lazybot"MOVIE REVIEWS" | file - ## /dev/stdin: Silicon Graphics movie file
15:13TimMcGood times.
15:15TimMcExcept some bloopers.
15:15TimMc*Expect
15:18amalloyfor some reason, TimMc, i never imagined `file` could take input from stdin, even though i knew it only used the file's contents. i was like "well duh, you're asking what kind of file something is, so it has to be a file"
15:18tgoossensi keep using loop and recur for infinite loops in a thread. is there a better way. I'm kinda feeling bad about how i'm doing it now
15:20llasramtgoossens: Over what are you looping infinitely?
15:20AimHere,(loop [] (recur))
15:20clojurebotExecution Timed Out
15:21tgoossensit is still an unfinished function : https://gist.github.com/4355451
15:21tgoossensexperimenting
15:22llasramtgoossens: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html
15:23frozenlocktgoossens: at-at from overtone https://github.com/overtone/at-at
15:23tgoossensinteresting
15:24tgoossensdamnit! you/myself caught me again. On the fact that I did not search for existing solutions for that "rate" stuff
15:24tgoossensat at looks cool
15:24llasramfrozenlock: Oh, nice. I like the REPL-friendly aspect
15:26tgoossensi should really train myself to sometimes stop, look at what i want to do, and search for similar / same problems and solutions
15:26frozenlock20s on IRC can save weeks of development
15:26tgoossensyes
15:26tgoossensfunny though
15:27tgoossenstoday a book arrived that i ordered
15:27tgoossens"how to solve it"
15:27tgoossenspolya
15:28bbloomtgoossens: that top level loop isn't required
15:28tgoossensit addresses exactly the thing i just experienced
15:28bbloomfunctions are themselves loop targets
15:29bbloom,(fn [] (recur))
15:29clojurebot#<sandbox$eval53$fn__54 sandbox$eval53$fn__54@58ab3daf>
15:29tgoossensbbloom: can you recur on that?
15:29bbloom,((fn [] (recur)))
15:29tgoossensah yes
15:29clojurebotExecution Timed Out
15:29tgoossensi see what you mean
15:30bbloomalso, when-not's body is an implicit do, so you don't need the do either
15:30bbloom(doc when-not)
15:30clojurebot"([test & body]); Evaluates test. If logical false, evaluates body in an implicit do."
15:30tgoossenswow
15:30bbloomthat's the whole point of when vs if
15:30tgoossens,(doc when)
15:30clojurebot"([test & body]); Evaluates test. If logical true, evaluates body in an implicit do."
15:31tgoossensmmyes
15:31tgoossenslol
15:31tgoossensthis is getting embarrassing :p
15:31bbloomother than that: there's nothing wrong with an infinite loop for a simulation
15:31bbloomthat's how simulations work!
15:31bbloomand tail recursion is the clojure way of looping
15:34nDuff...well, _one_ clojure way of looping. :)
15:34nDuffThere's also iterating over infinite lazy sequences.
15:34nDuff...which I'd argue is actually more clojure-y
15:36tgoossensbbloom: btw this is the context (namespace) where that function is
15:36tgoossenshttps://github.com/tgoossens/robotclj/blob/master/src/robotclj/virtual.clj
15:37tgoossensits a first experiment. i'm still far from sure how i want to create the simulator
15:37tgoossensjust playing aroud
15:37tgoossens*around
15:37bbloomtgoossens: nitpick: most clojure code uses 2-space indents instead of tabs
15:37tgoossensblloom: i know. But for some reason when i push it to git. it is screwed up
15:38bbloom....what? that seems unlikely heh
15:38tgoossensin my sublimetext editor it looks fine
15:38tgoossens(2 spaces)
15:39bbloomtgoossens: (fn [simulator] false) -> (constantly false)
15:40bbloomwhy does your multimethod return functions?
15:40bbloomwhy not take the simulator atom as an argument? you can dispatch on the :type of the second argument
15:41bbloomer rather take the simulator *value* as an argument
15:41bbloomand return the new value
15:41tgoossensbbloom: this is what happend. I wanted a map from command-> action. but a simple hash-map did not suffice. So I found out that i could do what i want with multimethods: binding to a command a function
15:42mpanwould it be a good/bad idea to use zippers for an implicit search tree that isn't actually modifiable?
15:42bbloomwhy didn't a hash-map suffice?
15:42tgoossensa command is {:type ::drive :other keys}
15:42bbloomah.
15:42tgoossensi needed a function based on the type
15:43bbloomi have a thing for this :-) https://github.com/brandonbloom/dispatch-map
15:43tgoossensah. yes. i remember reading that on planet clojure
15:43bbloombut in reality, a multimethod is probably fine for what you need
15:43tgoossensi think i commented on the blogpost asking whether you don't lose "exentability"
15:43tgoossens*extendability
15:44bbloomah
15:44tgoossenswas that you?
15:44bbloomthat's me
15:44tgoossensaight :)
15:44tgoossenscool
15:45bbloomi'm just not sure why your multimethod has 3 levels of indirection: the method, the (fn [simulator] ...) and then the :*-fn
15:45bbloomseems like you could collapse those all down
15:46tgoossenshmmm maybe. but i wanted was a mapping from command type to function. and then be able to still pass that function around (not executing it immediately)
15:47bbloomi see
15:47tgoossensi'll be back in a minute. then i'll explain my intends with the simulator abit
15:49ppppaulis it possible for me to call private functions?
15:50bbloomppppaul: private vars are callable: (#'the-ns/private-fn 1 2 3)
15:50ppppaulcool
15:50ynnivI would like to use korma's query dsl, but korma really wants to bring along its friends. is there a way to make this happen, or another project that only generates query strings?
15:51amalloy$google lein dependency xclusions
15:51lazybot[technomancy/leiningen · GitHub] https://github.com/technomancy/leiningen
15:51amalloywell, typo. anyway, check the sample project.clj for exclusions
15:51TimMcamalloy: I hadn't considered before either. I just wanted a really short example, and "-" *usually* works with GNU utils...
15:52amalloywell, usually - is optional
15:52TimMcIn this case it is required, apparently.
15:53ynnivamalloy: is that a reply to me? I'm already excluding deps, but korma statically loads things that I don't want
15:53amalloyyou're out of luck, then
15:53TimMc- appears to be an undocumented option to file.
15:54tgoossensbbloom: ok https://github.com/tgoossens/robotclj/blob/master/src/robotclj/core.clj
15:54tgoossensthis will be the "dispatching" part
15:54tgoossensi need to send commands like, drive, turn, explore maze, to either a virtual robot or a remote (bluetooth) nxt robot
15:55tgoossensso for the simulator case, it will have to create commands and send it to the simulator
15:56tgoossensi'm still not sure whether i should use an atom, agent for the simulator (currently i'm opting for an atom because i need to be able to stop the robot immediately, but an agent reflects maybe better reality)
15:56tgoossensin the simulator there is a key ":command" that contains the command (to be) being executed in the simulator
15:58tgoossensthe simulator must start executing the command as long as the stopcondition returns false.
15:58tgoossensOr it should start executing another command if it gets swapped
15:59tgoossensbbloom: thats the general idea
16:00mehworkhow can i conver a list like '("a","b","c") into strings as separate args that i can pass to a function: "a" "b" "c"
16:00dnolenmehwork: apply
16:00dnolen(apply f some-list)
16:00mehworkalthough, if [& args] puts them back in a list i don't know why i can't just pass it as a list
16:00mehworkthanks i'll try it
16:01dnolen,(str "a" "b" "c")
16:01AimHereWell how would the function know that you wanted to pass a list of arguments, rather than a list as your first argument?
16:01ynnivyeah, annoying to work around what seems to be unnecessary destructuring
16:01clojurebot"abc"
16:01dnolen,(apply str (list "a" "b" "c"))
16:01clojurebot"abc"
16:02mehworki don't want them to become a single string
16:02dnolenmehwork: I know, it's just an example
16:03mehworki think the prob is that "a" "b" "c" is a concatentation on a string, so it's the same as saying "abc"
16:03TimMcmehwork: It's not.
16:04mehworkthere needs to be the opposite where it splits "abc" to "a" "b" "c"
16:04mehworkoh you're right nm
16:04mehworki guess that's only if you print it
16:04mehworker
16:04mehworkwhat the heck it was just happening, now it's not :/
16:05seangrove,(type (str "a "b "c))
16:05clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading string>
16:05mehworkoh that does a b c
16:05seangrove,(type (str "a "b "c"))
16:05clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: b in this context, compiling:(NO_SOURCE_PATH:0)>
16:05seangrovehah
16:05seangrove,(type (str "a" "b" "c"))
16:05clojurebotjava.lang.String
16:06TimMc,(str)
16:06clojurebot""
16:14mehworkis there a way to convert a sequence ["a","b","c"] to just "a" "b" "c"?
16:15technomancymehwork: that question doesn't really make sense
16:16mehworktechnomancy: well i want to pass a variable list of arguments dynamically
16:16bbloom(doc apply)
16:16clojurebot"([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."
16:16technomancyoh, during function application specifically?
16:16technomancyyeah, that
16:16mehworkok i guess i need to play with apply more, i couldn't get it to work yet
16:17technomancy,(apply str "a" "b" ["c" "d" "f"])
16:17clojurebot"abcdf"
16:18mehworkyeah that's all i can ever get it to do which isn't what i want because i want to do (myfunc <expand '("a" "b" "c") args>) and have it act as though i typed: (myfunc "a" "b" "c")
16:18mehwork3 sep args, not 1
16:19technomancyapply only does its magic on the last argument
16:19seangroveAlmost ready for our new release - 99% clojurescript: http://dl.dropbox.com/u/412963/zenbox/zenbox_preview_jan.mov
16:19bbloom,(apply str (concat '("a" "b" "c") [1 2 3]))
16:19clojurebot"abc123"
16:20seangroveJust a tiny bit of glue javascript here and there, but overall extremely happy with clojurescript for production apps
16:20mehworki feel stupid because i'm just not getting what you're saying :[
16:20bbloommehwork: read the doc string for apply again
16:21amalloybbloom: the docstring for apply is not instructive at all
16:21bbloomthen consider this function (fn [& args] (count args))
16:21bbloom((fn [& args] (count args)) 1 2 3)
16:21bbloom((fn [& args] (count args)) 1 2 3),
16:21bbloomdammit:
16:21seangrovehah
16:21bbloom,((fn [& args] (count args)) 1 2 3)
16:21clojurebot3
16:21bbloom,(apply (fn [& args] (count args)) 1 2 [3])
16:21clojurebot3
16:21bbloom,(apply (fn [& args] (count args)) 1 2 [3 4 5])
16:21clojurebot5
16:21bbloom,(apply (fn [& args] (count args)) 1 2 [3 4 5] 6)
16:21clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
16:21bbloom,(apply (fn [& args] (count args)) [1 2] [3 4 5])
16:21clojurebot4
16:21dnolenmehwork: apply does what you want - give us an example (paste) where it's not working for you.
16:22bbloomdoes it make sense now?
16:22mehworkno but i'm playing with it in a repl till it does
16:23bbloombetter yet: (fn [& args] args)
16:23hyPiRionwhen apply is given more than one arg, all but the latter is considered as singletons
16:23bbloom,((fn [& args] args) 1 2 [3 4 5])
16:23clojurebot(1 2 [3 4 5])
16:23bbloom,(apply (fn [& args] args) 1 2 [3 4 5])
16:23clojurebot(1 2 3 4 5)
16:23bbloom,(apply (fn [& args] args) [1 2] [3 4 5])
16:23clojurebot([1 2] 3 4 5)
16:23bbloomseangrove: neat. some kind of CRM tool?
16:23mehworko wait
16:24seangrovebbloom: Kind of a meta-crm tool, yeah
16:24bbloomread
16:24bbloomer wrong window
16:25seangroveIt fits in gmail like rapportive, or anywhere on the web where you hover over an email, and it'll pull in all of the data you have on that email from Salesforce, Mailchimp, Stripe, your database, and ~25 others
16:25bbloomseangrove: sounds interesting
16:26bbloomgonna write up a cljs success story? :-)
16:26mehworkdoes apply not work on normal lists?
16:26dnolenmehwork: it does
16:27seangrovebbloom: Yeah, this has been a complete re-write from js/jQuery -> cljs/Closure. There'll be a post on the UI design changes in the product, and another on the technical changes to cljs
16:27seangroveBoth are reasonably interesting in hindsight
16:28bbloomseangrove: looking forward to them
16:28mehwork,(apply (fn [& args] (count args)) ("a" "b" "c"))
16:28clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>
16:29mehwork,(apply (fn [& args] (count args)) '("a" "b" "c"))
16:29clojurebot3
16:29mehworkahhh now i get it
16:31dnolenmehwork: though that issue really has nothing to do w/ apply
16:32dnolen,("a" "b" "c")
16:32clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>
16:32jro_do yo write unit tests in your clojure development? or quickcheck style testing?
16:33mehworkjro_: what's quickcheck style?
16:33ppppaulwhen i set my :test-paths ["test"] in project.clj i get an error-> lein test
16:33ppppaulError loading project.clj
16:33mehworklike manually running it to see if it seems to be working?
16:34ppppaulanyone able to point me to a url that'll help me get 'lein test' working on my project?
16:34jro_combinatorial testing, like Haskell's QuickCheck. ClojureCheck seems to be similar
16:34technomancyppppaul: :test-paths defaults to ["test"]; no need to add it
16:35technomancyweird that you're getting an error though; works here
16:35dnolenjro_: there's also the test.generative contrib library
16:35ppppaulwhen i omit that line i get Exception in thread "main" java.io.FileNotFoundException: Could not locate clojure_api/core_test__init.class or clojure_api/core_test.clj
16:35technomancyjro_: most people just use regular clojure.test by a fairly wide majority
16:40tgoossensbbloom: your dispatch-map works great
16:41ppppaulwhen testing clojure do i have to call all my tests from core_test.clj?
16:41bbloomtgoossens: nice! :-)
16:41tgoossensstill figuring out how to pass use the other fields of the command
16:41tgoossens(like my multimethod)
16:41technomancyppppaul: you can scatter deftest forms all over your test/ directory as you like
16:41technomancyppppaul: maybe it'd be helpful to look at an existing project as an example
16:43tgoossensbbloom is it even possible?
16:43ppppaulthat could be helpful
16:43bbloomtgoossens: is that possible?
16:43ppppauli have tests all over my test dir, but i haven't used lein test until now and it's failing bad
16:44bbloomtgoossens: s/that/what/
16:44tgoossensbbloom: ? :p
16:44bbloomexplain your question please
16:44tgoossensah ok
16:44hiredmanis there a write up of the core.logic deffact stuff?
16:45hiredmandefrel
16:45tgoossensbbloom: the dispatch-map dispatches by applying a function to the given inputvalue. In my multimethods i can still use that inputvalue.
16:46jro_lein2 run swallows my stdout
16:46tgoossens(defmethod command-map ::drive [command] (:blablab command))
16:47bbloomoh, no that wouldn't make any sense for dispatch-map b/c the values in a dispatch map aren't necessarily functions
16:47tgoossensexactly
16:47dnolenhiredman: not really, do you have a specific question? I will say it's still a bit half-baked
16:47tgoossensso my "point" was that dispatch map is not really useful for what i'm trying to achieve
16:47bbloom(let [value ...] (partial (get (dispatch-map ...) value) value))
16:48bbloomdispatch map is a building block
16:48tgoossensalso possible is that my current design sucks and i should reconsider it
16:48bbloomone thing you can build with it is a multimethod :-P
16:48tgoossens:)
16:48tgoossensi totally get it now (compared to my comment on your blog :p )
16:49dnolenooh Nashorn source is out, http://blogs.oracle.com/nashorn/entry/open_for_business
16:49tgoossensg2g thanks and we speak again!
16:49bbloomdnolen: cool
16:51hiredmandnolen: no, I just have some code that uses a "database" (a big map) and delves in to the internals of core.logic to provide predicates from the database, and defrel seems like a replacement for that
16:53dnolenhiredman: gotcha - you may find defrel pretty yucky. I really made it for myself so I could work through Prolog books. The basic idea is OK but the implementation details need to change, but I'm too busy w/ other things.
16:54hiredmandnolen: yeah, I kinda do :) mainly because it is a bunch of calls vs. data as a map, but I can just write something to drive the calls from the map
16:55francisIs anyone aware of a clojure tool that removes unused dependancies from namespaces?
16:55amalloy$google lein slamhound
16:55lazybot[slamhound/lein-slamhound at master · technomancy ... - GitHub] https://github.com/technomancy/slamhound/tree/master/lein-slamhound
16:56technomancyfrancis: disclaimer: doesn't work all that well
16:56francistechnomancy & amalloy: tried slamhound earlier, didn't work at all
16:56technomancyin particular it assumes :require :as aliases are always going to match the last segment of the namespace, and I haven't written code like that since 2011
16:57technomancyhowever, fixing slamhound would be easier than starting from scartch
16:57technomancyscratch
16:57francistechnomancy: I'm considering doing that
16:57technomancyit's pretty well documented
16:57francisIt's either that or write my own
16:57technomancyhttp://technomancy.us/148
16:58francisgroovy, thanks
16:58ppppauli'm looking at how lein's project testing is set up
16:58ppppauli find it a bit strange that there is a lein/test/lein/test/ dir structure...
16:59technomancyyou mean for leiningen itself?
16:59ppppaulyes
16:59technomancythat might not be the best example; lein has some weird self-hosting things that make it atypical
16:59ppppauli'm using it as an example of how to set up my project
16:59technomancymaybe clojars?
16:59ppppaulhmm
17:00ppppaulclojars-web / test / clojars / test /
17:00ppppaulseems the same
17:01technomancyppppaul: the first test/ dir is there to keep test/ separate from src/
17:01technomancythe second test/ is there because it's part of the namespace name
17:02ppppauli see
17:02ppppauli was able to progress after this realization
17:02ppppaul:)
17:09jro_I've Emerick et al "Programming Clojure", and just ordered "Joy of Clojure". Could you recommend other books complement those?
17:10technomancythose are the best
17:10ChongLiClojure Programming
17:10technomancyoh wait, yeah thats' what I meant
17:11jro_yes, that is the Emerick's and others book
17:11jro_I did like it
17:11ChongLiProgramming Clojure is Halloway and Bedra
17:12devinus_Clojure in Action
17:12devinus_is in MEAP isnt it?
17:12jro_my weakness now is to design bigger programs using clojure, maybe the language and its abilities are covered pretty well in these two
17:13technomancyjro_: a book won't help with that, you need to read code
17:13ChongLiI think SICP can help with that
17:14jro_yeah, now I just no need to code...
17:15jro_my first cloure app has so far 46,423 hits :-) and number of active user's are increasing all the time ;-)
17:16jro_I very pleased about the robustness of the infrastructure: lein, compojure+ring, netty bridge
17:22dnolenhmm looks like Nashorn is going to be pretty serious about optimizing JS ...
17:27bosiehttp://clojure.github.com/clojure/clojure.core-api.html#clojure.core/if-let it says: "If test is true"... what test is this?
17:28xeqi(if-let [.. test] .. ..)
17:30bosiexeqi: right
17:30bosie(if-let [a b]....)
17:30bosieit would only execute the .... if b is a truthy?
17:31ucbbosie: I'd like to think so
17:31ucb,(doc if-let)
17:31clojurebot"([bindings then] [bindings then else & oldform]); bindings => binding-form test If test is true, evaluates then with binding-form bound to the value of test, if not, yields else"
17:32bosieucb: i read the docs but couldn't make sense of it ;)
17:32ucboh
17:32xeqi(if-let [a 5] 1 (throw (Exception.)))
17:32bosieucb: i also dont get what "bindings => binding-form test" means
17:32xeqi&(if-let [a 5] 1 (throw (Exception.)))
17:32lazybot⇒ 1
17:32xeqithat means you can destructure the test result
17:33xeqi(if-let [{:keys [x y z]} {:x 1 :y 2 :z 3}] [x y z])
17:33xeqi&(if-let [{:keys [x y z]} {:x 1 :y 2 :z 3}] [x y z])
17:33lazybot⇒ [1 2 3]
17:33bosiethats interesting xeqi
17:34bosiethanks
17:45jballanc_is anybody doing sql migrations in Clojure?
17:46technomancyclojurebot: migrations?
17:46clojurebotI don't understand.
17:46technomancyclojurebot: migrate.clj?
17:46clojurebotunquote in project.clj is an escape hatch
17:46technomancyblargh
17:46technomancyjballanc_: here's what I use: https://github.com/heroku/buildkits/blob/master/src/buildkits/db/migrate.clj
17:46jballanc_cool, thanks!
17:47xeqifor completeness theres https://github.com/budu/lobos and https://github.com/weavejester/ragtime as well
17:47technomancylobos is really complicated though
17:47xeqibut clojars uses something like what technomancy linked
17:47technomancyand tries to pretend that it's possible to do nontrivial migrations that are portable across databases
17:48jballanc_so, let's say someone was interested in adding something akin to DataMapper's automigrations to Korma...
17:48jballanc_anyone know the state of Korma development?
17:48technomancyI would strongly advise against the development of any system which tries to do migrations in a db-agnostic way
17:48technomancyit's not possible to do well
17:48jballanc_heh...understatement of the year
17:49jballanc_hmm...ok, I'll think on all these
17:49jballanc_thanks for the help!
17:49dybadoes anyone know how to require a clojure contrib library?
17:49xeqi~contrib
17:49clojurebotMonolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go
17:49dybaI've tried (:require clojure.contrib.math)
17:49dybabut that doesn't work
17:50TimMctechnomancy: Naw, man, you just wait until I release my ORM that works across all SQL and NoSQL DBs and also between different runtimes.
17:50TimMcYOU JUST WAIT.
17:50TimMcWe're pushing back our release date just a bit. 2035.
17:50technomancydyba: contrib libraries aren't special; you would load them like any other library after adding them to project.clj
17:50weavejesterdyba: https://github.com/clojure/math.numeric-tower
17:51dybaxeqi: thanks! I'll read up on that
17:51weavejesterdyba: Add [org.clojure/math.numeric-tower "0.0.2"] to your project.clj deps
17:51weavejesterdyba: And then (require '[clojure.math.numeric-tower :as math])
17:52dybathanks technomancy & weavejester!
17:52dybaI'll give that a try
17:53technomancynp
17:59nDuffCan agent send operations be forced to block beyond a given queue length?
18:01llasramnDuff: I don't believe there's any explicit support for that sort of thing
18:02llasramHmm, although -- Agents do expose a public `.getQueueCount` method
18:04amalloyone thing i'd like, if anyone feels excited about implementing it, is an agent-like thing where you can specify the queue to use
18:04technomancyamalloy: yes please
18:04technomancyerr--specifically letting you bring your own thread pool is what I was thinking of
18:04amalloytechnomancy: i think you can do that in 1.5
18:05technomancyno kidding?
18:05technomancyno more shutdown-agents-of-death?
18:06amalloytechnomancy: (send-via executor agent f & args)
18:06technomancyoh
18:06technomancyI guess that's better than nothing
18:06technomancythere's still global defaults hard-wired in that are hands-off
18:06amalloyhttps://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L1895
18:06amalloyno, you can change those too
18:06technomancyoh sweet
18:06llasramAlso `set-agent-send-executor!` if you're into mutating global state
18:07technomancytwo features I actually care about in a single release! that hasn't happened since 1.1 or 1.2.
18:07llasramlol
18:07llasramreducers are pretty spiffy
18:08technomancyI appreciate them in theory but don't see myself using them in practice.
18:11dnolenfeedback welcome on this one - http://dev.clojure.org/jira/browse/CLJS-448?focusedCommentId=30277#comment-30277
18:11dnolenoops http://dev.clojure.org/jira/browse/CLJS-335
18:30dybaby the way I was able to get that contrib library to work with my project
18:31dybaI will say that I would never have guessed to find the `abs` function in a namespace like clojure.math.numeric-tower
18:32dybathanks again to technomancy, weavejester, and xeqi!
18:33technomancythere's a Math/abs
18:33technomancybut it doesn't work on all numbers IIRC
18:34nDuffHrm.
18:37dnolenbbloom: applying your compiler patches, thanks
18:37bbloomdnolen: cool thanks!
18:44dyba_ok, so I reached my level of know-how with Clojure after this exception:
18:44dyba_org.apache.lucene.store.LockReleaseFailedException: Cannot forcefully unlock a NativeFSLock which is held by another indexer component: /Users/Paintdexter/.lein/indices/https___clojars.org_repo_/write.lock
18:44callenso I converted to using raw ring/clojure, but I'm noticing a lot of repetitious patterns and middleware that 99% of web apps are going to need regardless
18:44dnolenbbloom: done!
18:44dyba_where would I begin to learn about locking?
18:45callenis there some reason Noir is being abandoned when everybody seems to need the same functionality over and over? Would a base template on top of ring make more sense than a framework?
18:45callendyba_: lesson #1: Avoid it unless it's strictly necessary
18:45dyba_I feel I might have to read up on promise/deliver since I used that in my code
18:46dyba_callen: so if I'm getting a locking exception, I'm probably doing something wrong?
18:46callendyba_: no I don't know your circumstances, but I'll put it this way
18:46technomancycallen: lib-noir isn't being abandoned
18:46technomancyjust noir
18:47callentechnomancy: I'm not sure how much ground lib-noir covers, I'll have to take a look to see if it encompasses the stuff I keep having to do over and over.
18:47callendyba_: locking and threading both get resorted to a lot more than they usually merit.
18:47weavejestercallen: What sort of things did you keep doing over and over?
18:47llasramcallen: dyba_ is getting that error I assume just running leiningen, not creating locks him/herself
18:47callendyba_: a good example is when my front-end guy had to implement locks in a frontend JS app and ended up running into deadlocks.
18:48callendyba_: if you're getting a locking exception just from running somebody else's code, I wouldn't sweat it.
18:48technomancydyba_: do you have any concurrent operations going on for this index?
18:48ibdknoxcallen: weavejester: Raynes is going to do a lib-noir template and that should get 98% of the way there
18:49technomancydyba_: sometimes that kind of thing can happen when you mess up when doing interactive development and restarting the process can fix it if it's a simple problem
18:49weavejesteribdknox: I was curious as whether it was a templating problem, or something else.
18:49callenibdknox: ah well, we'll see I guess. I can't really wait on other people though. I had an increasingly verbose middleware.clj last night when I was converting to Ring from Noir.
18:49dyba_technomancy: I don't think I do
18:49weavejesteribdknox: Some good templates would be nice :)
18:49callenibdknox: I could turn the results of what I did into a quick-start Ring template.
18:49dyba_I'm not very savvy with concurrent processes. I don't think I'm running anything in parallel
18:49callenin fairly short order, I think.
18:50dyba_I was working on that fix I volunteered for in Leiningen
18:50callenthe nice thing about templates is that they're easily fit to purpose.
18:50ibdknoxweavejester: we've been talking about reworking webnoir into a nice compojure+lib-noir doc site too. Those with templates should get us to a good place :)
18:50dyba_and then I decided to use promise/deliver to work with a stream of bytes I get when I run the search command
18:51dyba_then for the input stream i use an atom to track the number of bytes read
18:51dyba_I can provide a link to the code if anyone is interested in looking into it
18:51technomancydyba_: sure
18:51callendyba_: why are you using promise?
18:51dyba_https://github.com/dyba/leiningen/blob/master/src/leiningen/search.clj
18:52dyba_callen: I have no idea what I'm doing :/
18:52callendyba_: that's me every single day, just ask any of the others here. :P
18:52dyba_phew, I just keep telling everyone I'm a newbie
18:53technomancydyba_: I think promise is appropriate here if you're just trying to capture proxied .setFoo args
18:53technomancydyba_: have you tried just deleting the index in question and trying again?
18:53dyba_technomancy: how would I do that? you mean rm -rf .m2 ?
18:54technomancydyba_: no, ~/.lein/indices rather
18:54dyba_oh let me try that
18:54bbloomdnolen: awesome! one more while you're at it :-) http://dev.clojure.org/jira/browse/CLJS-424
18:55callenone concern I have about publishing a template is that my base I'm using to fix up all my apps use hiccup.
18:55callenfor the error pages et al
18:56callenI was hoping to avoid being overly opinionated to that end.
18:56dyba_technomancy: hm, same problem
18:57dyba_maybe if I get rid of that atom inside the input-stream-proxy function
18:57dyba_ha, just realized I didn't share the right branch
18:57dyba_https://github.com/dyba/leiningen/tree/progress-reporting-search-index
18:57dyba_ugh
18:57dyba_wrong file
18:58dyba_https://github.com/dyba/leiningen/blob/progress-reporting-search-index/src/leiningen/search.clj
18:58technomancydyba_: the lock error just means that multiple writers are trying to be opened on the same index
19:07alex_baranoskytechnomancy: any suggestions when looking at slam hound with an eye towards fixing it up? Francis and I might try to work on it over the next week and get it working so we can use it on our work projects
19:08dnolenbbloom: will have to look at that later, I see have a backlog since I've been working on core.logic so much
19:09dnolenbbloom: is this still relevant? http://dev.clojure.org/jira/browse/CLJS-412
19:11bbloomdnolen: let me think about CLJS-412 for a second
19:11technomancyalex_baranosky: that'd be tops. let me take a peek.
19:12dnolenbbloom: well I responded, I might jet so soon so leave a comment :)
19:12bbloomdnolen: i think the first comment was a typo
19:12bbloomshoulda been defn
19:12dnolenbbloom: yep I put that in, no warnings
19:13technomancyalex_baranosky: the primary problem right now is that the heuristic for replacing :require :as is rubbish; you'd need to accumulate over a list of all attempted aliased references as they come up and when there's a new failure pick a namespace where all the aliased vars still appear
19:13technomancyalex_baranosky: does that make sense? happy to answer questions as they come up if I'm around
19:13bbloomdnolen: did you have warn on undelcared enabled?
19:14technomancyalex_baranosky: also you'll want to replace :use with :require :refer
19:14technomancybut I don't think that'd be difficult
19:14dnolenbbloom: that's the default for Rhino REPL
19:15technomancyalex_baranosky: I'm not sure how difficult it'd be to keep a running list of failures; that's probably going to be the primary challenge. but the existing codebase is pretty tiny and fairly well-factored
19:16technomancywish I had time to hack on it; that's a really fun codebase
19:16bbloomdnolen: hmm dunno about that first comment, but i def get the issue from the original body
19:17bbloomdnolen: https://gist.github.com/4356706
19:19dnolenbbloom: yes but does that happen at the REPL or in a source file?
19:19dnolenbbloom: in anycase I have to go - I need a lot more information about what you are trying to do.
19:19bbloomdnolen: it happens when i use analyze
19:19bbloombut no not in the repl any more it seems
19:19dnolenbbloom: so an explanation of why not in the REPL & yet at analyze would be helpful.
19:19dnolengotta run
19:20bbloomdnolen: cya
19:23alex_baranoskytechnomancy: sorry, got distorted… yes that makes sense. I was thinking as enhancements it'd be nice to configure whether you want :use/only or require/refer… require/refer doesn't work on 1.3 right?
19:23alex_baranoskybut first thing is to make it work :)
19:23alex_baranoskytechnomancy: I've got to run, but will keep you posted
19:27technomancyalex_baranosky: I wouldn't bother with 1.3 support
19:27technomancy1.3 is best forgotten
19:27technomancyplumbing configurability all the way through for such a minor feature isn't worth the complexity
19:51bbloomwhy do academics insist on fancy typography, even when they are showing source code for a language that is *usually* written in ascii? We get it, you think \Lambda looks nice. But some of us are trying to read your paper....
19:53callenbbloom: the poltergeist of APL haunting us
19:53callenbbloom: also: LaTeX
19:55bbloomi can maaaaaaaaaaybe understand space requirements in journals, etc, but for an unbounded digital dissertation, what motivation could there possibly be for inventing your own syntax for scheme? it's gotta be a cargo cult situtation...
20:04llasrambbloom: Are you reading the FrTime paper?
20:11yedihttps://github.com/doo/process
20:11yedipretty sweet
20:13paultagAnyone know how to get unbuffered stdin in Clojure? I'm a bit new, it'd help a lot if you had a small example (but doc pointers would be great too)
20:14cemerickpaultag: that might require going straight for System/in
20:15RaynesIf I need unbuffered in and out, I go straight for System/*
20:15paultagrighto. thanks
20:15RaynesI couldn't get it unbuffered from *out*, so I expect the same would make sense in *in*.
20:15paultagwhat, that it's buffered still?
20:15seangroveWhat's GClosure? This https://github.com/rhysbrettbowen/G-closure ?
20:15paultagAh, right.
20:15paultagYeah, sorry took a seec
20:16paultagsec* thanks, y'all.
20:16seangrovednolen recommended people use it to pass objects from potentially different contexts
20:18paultagis there something like `progn' in Clojure?
20:18paultagah, do. right, nvmd.
20:20scottjseangrove: GClosure is Google Closure
20:21seangroveAh. Wonder how that's related to passing object between contexts
20:21RaynesTelling someone GClosure can do what they want is like telling someone who is hungry that a grocery store can do what they want.
21:10callenRaynes: GClosure isn't really useful unless you have a lot of really big frontend apps that you want to be able to reuse code across.
21:11callena lot of their adops people are trying to push angular to replace a lot of the ajaxy functionality.
21:17seangrovecallen: The ui widgets seem very nice, the event bus stuff is reasonably nice, the DOM stuff is solid if ugly (though things like domina make it nicer), the promise/deferred stuff isn't too bad... the ajax stuff is *meh*, but I haven't used it much yet
21:17seangroveCurious what you mean by it not being super useful
21:17seangroveAlso really curious about people pushing for angular to replace the ajax parts and why that'd happen
21:25callenseangrove: the UI widgets aren't useful for most customer-facing development.
21:26callenseangrove: angular is a more declarative and data-driven approach to frontend dev, it's being used all over Google but the strongest proponents are the people in their ad depts. The devs who work on Angular that I know are mostly in NY.
21:26callenseangrove: Angular is pretty nice, I think Goodreads did a write-up on building a mobile web app in Angular.
21:27callenAngular does a lot to prevent event/data spaghetti on the frontend, but is more generally applicable to a variety of problems than Backbone.
21:28callenweavejester: so is most of your contracting work Clojure work then?
21:28weavejestercallen: All of it so far
21:30callenweavejester: that's pretty great. Most of what I heard about Clojure so far mostly concerned using it as a secret weapon in Enterprise Java environments.
21:30callenSupposedly this is partly what spurred Hickey on, beyond his ongoing language experimentation.
21:31callenweavejester: is it mostly backend, full-stack, new stuff or building on existing stuff?
21:31weavejesterThere's a few businesses in London starting using it. Forward and Likely spring to mind.
21:31weavejestercallen: I've currently just had two contracts - I only started back in July :)
21:32weavejestercallen: One was for a web service that was semi-client facing.
21:32callenweavejester: cool, thanks for sharing. It seemed like the Clojure work was bimodal, either it was being snuck into a Java environment or a startup was using it from 0
21:33callenweavejester: watching your talk on clojure web dev. Thanks for your work on Ring!
21:33weavejestercallen: Another deals with big data - cascalog, hadoop, that kinda thing
21:34weavejestercallen: You're welcome
21:34weavejesterNow….
21:34weavejesterI gotta get to bed :)
21:34callenCheers :)
21:45ferdcan somebody point me to "substantial" open-source apps built in Clojure?
21:46callenferd: gimme a specialization broskie
21:46callenferd: I can help you but you need to tell me what you want to see.
21:46callenferd: e.g. Web app, big data application, etc.
21:46callendata store library...
21:47ferda web app would work
21:47ferd I'm looking for complete business apps (not specialized libraries) ... I want to draw ideas around how to structure non-trivial codebases
21:47callenhttps://github.com/Raynes/refheap go with my classic stand-by for checking for idiomatic patterns in Clojure web apps then.
21:47callenferd: I'm actually cobbling together a template for Clojure Ring apps atm because I'm migrating away from Noir. I'd look at RefHeap for now though, Raynes is 300x more experienced at Clojure than I am.
21:48callenI used to use Noir + Stencil, I'm switching to Ring + Hiccup.
21:50ferdThanks
21:50callenferd: np. let me know if you have any questions. My work tends to be along the lines you described.
21:50callenferd: business and consumer facing web apps.
21:52ferdfor now I'm looking for good practices for structuring namespaces, managing configuration, environments, abstracting data-access layer (I might need to support a couple of options), mapping (say, from client's JSON to a diff. structure for persistence)
21:53callenferd: well, you're basically asking to become professionally competent in the entire language. Refheap is a good reference for reminding yourself of idioms but the best way to learn and *internalize* those things is to just start hacking on a side project until it sticks
21:53callenwhich has been my way of learning Clojure. It's worked well for me, better than books.
21:53callenalthough I've been fond of a few.
21:54callenferd: I just solved that configuration/environment problem last night. I'm not 100% satisfied with it but I'm confident it's fine for now.
21:56callenarohner: your cofounder was suprisingly gracious about a relatively petty spelling-fix pull request.
21:57callenarohner: you wouldn't happen to be able to comment on how you guys use Dieter, would you
21:57callenpretend there was a question mark at the end of that.
22:14technomancyferd: clojars is the most widely-used OSS clojure web app
22:15technomancyit's been around a while but I think for the most part exhibits good design
22:16ferdthanks... taking a look at it now...
22:21sgeo_,(resolve 'first)
22:21clojurebot#'clojure.core/first
22:21callenferd: clojars is even bigger than refheap, technomancy makes a great suggestion.
22:22ferdyeap... excellent
22:22technomancyas long as you ignore the fact that it uses sqlite
22:22technomancy=)
22:22ferd:-)
22:22callentechnomancy: I cringed.
22:22ferdI plan on using Mongo or Datomic
22:22technomancycallen: it was fine until we started to add background tasks
22:22callenferd: do you have some reason for doing so?
22:23callentechnomancy: oh yes, multiple writers to a single sqlite database.
22:23callentechnomancy: always a great idea.
22:23technomancycallen: I originally thought that it was just multiple processes hitting the same DB that wouldn't work
22:24technomancynope! it's threads. *facepalm*
22:24callenI generally use sqlite when I need to stash something in something vaguely approximating "a file", but I want indexed access to rows. Anything beyond that...meh. Use a real database, failing that, use Redis if you want something lightweight.
22:24callentechnomancy: well it's anything that means "multiple writers"
22:24callentechnomancy: doesn't matter if it's threads, processes, whatever.
22:25technomancythe docs say multiple processes but in the fine print there's "if you're in a multi-threaded runtime, substitute threads for processes as you read this"
22:25callenthat's why I specifically use the wording multiple writers so that people don't mistake implementation for semantics.
22:25xeqias soon as I replace search I can see about changing the db
22:25ferdcallen: yes... the app I need is very "document"-oriented
22:26callenferd: well lets talk about that. I have a lot of experience with MongoDB and as a result spend a decent amount of time warning people off it.
22:26technomancyxeqi: you are a hero =)
22:26callenferd: what do you mean by document oriented in this case? it's fairly application specific.
22:26callenxeqi: we love you. (use postgres)
22:26callenxeqi: how are you doing search perchance? that happens to be a knack of mine.
22:27technomancyxeqi: I hope to get an email out this weekend explaining the situation around promotion
22:27technomancythen maybe a preview11 after christmas
22:27xeqicallen: still trying to decide, could just use lucene on the premade repo indexes
22:28ferdwell... I mean, I have entities which are basically a lot of hierarchical data fields... and each "instance" will vary on which pieces of data it has or not
22:28callenxeqi: could do that. I'd avoid using Lucene in the raw unless you have a specific reason for doing so though.
22:28xeqibut I don't see an easy way to score based on downloads with that
22:28callenxeqi: I understand there are some uncommonly good lucene libraries for clojure, but it's kinda rough for most use-cases.
22:28ferdso, definitely more natural to think of them as hierarchical "documents" than SQL tables
22:28callenxeqi: have you considered ElasticSearch?
22:28technomancyelasticsearch makes no sense for a corpus this size
22:29callenI regard ES as being fairly lightweight and easy to use as contrasted with using raw lucene indices.
22:29technomancyI mean, unless you're going to expose a rest API to 3rd party tools or something
22:29callenour non-programming data guy figured out how to set it up himself.
22:29xeqiI've only started digging into it today, os still in the exploration phase
22:30technomancythere's no need for dynamo-style clustering for a 5MB index
22:30xeqinever had to plug in fts myself yet
22:30callentechnomancy: it's not about the clustering, it's about the high-level featues.
22:30callentechnomancy: ES has a lot of nice high-level features for things like scoring.
22:30callenand dynamic sorting
22:30seangroveWhy do we love xeqi?
22:31callentechnomancy: I'm not utterly incapable of applying reason, I know he doesn't need anything "webscale" so to speak. I recommended it because ES solves a lot of really common problems you run into if you're using lucene on its own.
22:31seangrovetechnomancy: and what does "promotion" mean in this context?
22:31technomancyI dunno; raw lucene was really pleasant for me to use when I wrote lein search
22:31xeqiseangrove: cause I spend freetime on clojars
22:31ferdcallen: so, what are your main points against MongoDB ?
22:31seangroveAh, thank you xeqi, you're awesome ;)
22:32callenferd: sorry, hold on :P
22:32technomancyseangrove: clojars has a separate "releases" repo that only accepts packages that qualify around certain metadata criteria
22:32callentechnomancy: clojars is a web app that's going to have concurrent clients, not a local-only command line service
22:32technomancyseangrove: so packages need to get promoted from the "classic" repo into "releases"
22:32callentechnomancy: the needs are different and he wants to have intelligent human-facing scoring
22:32seangrovexeqi: Is there an open list of bugs/features others can work on?
22:32callento use raw lucene here is the same sort of mistake as using sqlite for a public-facing webapp to begin with
22:33technomancylucene works fine for concurrent reads
22:33seangroveI wouldn't mind taking a look at it sometime, maybe for a hackathon or something
22:33callentechnomancy: step away from the specifics for a moment
22:33technomancythe indices are already generated asynchronously, so concurrency is a non-issue
22:33callentechnomancy: how is going to efficiently do custom scoring with raw lucene?
22:33callentechnomancy: he'll end up duplicating the effort Baron already put into ES
22:33technomancycallen: in the case of clojars, the indices already exist; they are published for Leiningen
22:33xeqiseangrove: https://github.com/ato/clojars-web/issues , but there needs some classification for easier tasks
22:34seangroveYeah, was just looking through that, seems like some pretty specific stuff
22:34callentechnomancy: if it's a case of reusing existing code and functionality, so be it
22:34callentechnomancy: but more advanced user-facing features are going to be painful.
22:34technomancyxeqi: are you getting download counts from the nginx logs?
22:35technomancyneed to enable logs on the S3 bucket too; hmm.
22:36xeqitechnomancy: think _ato had some work that direction
22:36callentechnomancy: the fact that lein is already using them and that has some sort of symmetry with clojars is the real winning argument in favor of raw lucene btw.
22:36technomancycool
22:36callenferd: right, okay.
22:36xeqiwas hoping to be able to plug that in to make search rankings better
22:36xeqiautomatic canonical finding, etc
22:36callenferd: usually you just want to use a SQL database, commonly Postgres unless you have a good reason to the contrary.
22:36technomancycallen: can you run ES entirely in-process?
22:37technomancycallen: one of the great things about clojars right now is that you can hack on it without any external dependencies; everything's in the JVM
22:37callentechnomancy: yes, it's a thing that's done.
22:37callentechnomancy: it's not an officially supported use-case, but that's definitely a thing.
22:37technomancyok cool; when we were using it that was really hard to set up
22:37technomancybut that was a long time ago
22:37callentechnomancy: at heroku or with clojars/lein?
22:37technomancyat my last job; http://sonian.com
22:38callentechnomancy: odd. as I said a guy who only just learned to code was able to set it up himself and he was barely able to handle his python dependencies in the past.
22:38callentechnomancy: besides that, we've got some fairly involved multi-cluster deployments
22:38callenyou...don't want to know what cross-cluster data migration is like with ES. It's worse with Solr.
22:38callenit resembles Riak, actually.
22:38technomancysure; it's not difficult to set up a separate server along side clojars while developing, but it's tedious
22:39callencalling it dynamo like really doesn't do it enough justice. It does a better job at rebalancing than other dynamo-likes like Cassandra.
22:39ferdcallen: well... my entities will contain 30+ fields each... and each "record" will only fill about 20 of them depending the kind. If I model that in SQL, it'd be ~5 diff. tables to store a single entity
22:39technomancylittle impediments like that are actually more appropriate in a work environment than an OSS project, because people are more likely to get bored and move on =)
22:39technomancycallen: I agree it's very impressive at large scale.
22:40callenferd: what I understand so far, it's not a great reason just yet to use MongoDB
22:40technomancyjust a bit skeptical that it scales in the other direction =)
22:40callenferd: try to understand that the schema-free nature of MongoDB is seemingly convenient but that means it demands more, not less thought be given to data modelling.
22:40callentechnomancy: I would be too. it's memory-hungry.
22:40ferdcallen: so, I was under the impression that mapping the conceptual "document" from higher layers (say, JSON from the UI) would be easier in Mongo than SQL
22:41callentechnomancy: it's very aggressive about keeping things in-memory to satisfy soft realtime constraints.
22:41ferdcallen: is there any good reading (book, or deep articles) to help me ?
22:41xeqicallen: thanks for the pointers, had someone else mention ES before, I'll have to take a look at it
22:41callenferd: it resembles JSON, but migrations, schema changes, and general modelling are harder not easier to do correctly in MongoDB.
22:41callenferd: you should get a book on data modelling in SQL, learn to do it right there
22:41callenferd: once you learn the right way to do it there, you'll be better prepared to make a decision between a SQL DB and MongoDB
22:42ferdhonestly, I like what I see on Datomic better... it's just that it's not very popular nor open source ... and I don't yet know how much the "free" edition can stand
22:42callenferd: if you don't already have very strong opinions and lots of experience with data modelling MongoDB is *not* the way to go
22:42ferdcallen: I've been using sql for 15+ years... not an expert, but... no need to read more for now :-)
22:42callenif I hadn't had a lot of experience contracting in feature-creep heavy enterprise projects I would've been boned when we used MongoDB
22:43callenferd: then I don't know what to tell you. If you posted some potential JSON representations of the data you're thinking of, I could start working in the conrete
22:43callenconcrete*
22:43technomancyI would take couch over mongo any day.
22:43seangroveferd: wei_ and I hacked on a side-project to get to know datomic, and the free version can hold up well, *but* it's an entirely different experience than with postgres et al
22:43callenxeqi: sure but from what technomancy is saying, it seems like most of the clojars developers want a complete embedded and in-process deployment story.
22:43callentechnomancy: I would not @ couch.
22:44callentechnomancy: couch is insanely irritating and slow.
22:44clojurebotOk.
22:44seangrovetechnomancy: I would shoot couch any day
22:44technomancycallen: mostly because it doesn't set unrealistic expectations
22:44seangroveSecond to mongo, no software has ever caused me to wake up more in the middle of the night than couch
22:44callentechnomancy: CouchDB is a data roach motel
22:44callen"data goes in, but never comes back out"
22:44ferdI see couch, indeed, another alternative.... I though of Mongo just 'cause it seemed more popular and better supported
22:45callencouch is best for non-user-facing data archival and roll-ups
22:45technomancyferd: are you sure it's not just "people blog about it more"?
22:45seangroveCouch could be alright, but in general everything seems wrong about it
22:45seangrovetechnomancy: Our post about CouchDB http://sauceio.com/index.php/2012/05/goodbye-couchdb/
22:45seangroveOt
22:45technomancyyeah actually couch's strengths like on the client side with putting the user literally in control of their own data
22:46seangroveIt is - generally - very cordial given team sentiments
22:46ferdwondering if I'll find a DB that nobody will bitch about here :-)
22:46technomancybut I'd still take it over mongo =)
22:46technomancyferd: postgres
22:46callenthe three most common databases among founders that I encounter are MySQL, PostgreSQL, and MongoDB.
22:46seangroveferd: postgres
22:46seangroveEspecially on Heroku
22:46callenferd: postgres
22:47ferdOK... I'm very familiar with postgres... so that's good
22:47callenpostgres is blameless. It lives up to its mission and it's fine for 99% of projects.
22:47callenit's not flawless, it just does what it says.
22:47seangrovecallen: I'd add more nines to that
22:47callenseangrove: I wouldn't, I work at a company that uses and needs MongoDB and ElasticSearch :P
22:48seangroveBut yes, if you've outgrown postgres, then you've done an awesome job and are a good engineer, most likely
22:48callentakes less than you think
22:48technomancyseangrove: if you've outgrown postgres, you're probably not looking for DB advice on IRC =)
22:48ferdI was hoping to avoid tons of mappings from JSON to SQL entity-roots and an explostion of sub-entity tables
22:48callenhighly sparse data schemas are pretty rough in tabular row-stores.
22:48seangrovetechnomancy: True, true
22:49seangroveI got an email from you guys accusing me of using env vars on Heroku as a database ;)
22:49callenincidentally I consider persistence and search to be my favorite subjects and they also happen to be the subjects I seek the least amount of advice for on IRC
22:49seangroveThe last line was, "Have you ever heard of Heroku Postgres?"
22:49technomancyseangrove: haha; nice
22:49callenseangrove: 12-factor?
22:49seangroveI still can't figure out if it's a sarcastic line or not
22:49technomancyseangrove: pretty sure it is
22:50callen12-factor deployments can often be mistaken for ENV var as a data-store.
22:50seangrovecallen: Yeah, more or less
22:50callenI'm psychic.
22:50seangroveIt was required as a shim for deploying to our own PaaS, dotCloud, Cloud Foundry, and Heroku, in order to do it seamlessly
22:50callenI consciously chose not to do 12-factor.
22:50technomancyseangrove: an object lesson in the importance of adding caps sooner rather than later =)
22:51seangrovetechnomancy: I suppose
22:51seangroveIt wasn't abusive
22:51technomancyseangrove: for us, I mean
22:51seangroveAnd it was within the limits supported by linux's env, etc.
22:51seangroveOh, yes, I know
22:51seangroveYou guys are generally very good at that
22:51seangroveBy the way, you're not out here in SF are you?
22:51callentechnomancy: 12-factor apps can end up having hundreds of env vars. It's pretty typical for projects that are hyper aggressive about deployments.
22:51technomancyseangrove: sure, but we are changing the backing store and found that some (very small) number of configs wouldn't work in the new one
22:51callenwell, dev-ops, lets say.
22:51technomancyseangrove: nah; seattle
22:52callenI'm in MV.
22:52seangrovetechnomancy: Bummer, you guys have a great team out here
22:52technomancycallen: haven't seen it myself, but I have only deployed small apps on the platform
22:52technomancyseangrove: I visit every couple months, which is about the right amount of SF for me =)
22:52seangroveI've heard that clojure is more or less out of Heroku these days though, sadly
22:52seangroveSomething about it being too hard to hire for
22:52ferdanybody has an opinion on Datomic? I really like the model, but not sure if I can trust the free edition... (I don't need Dynamo-level scalability, not even close)
22:53seangrove... and yet you persist in using Erlang ;)
22:53technomancyseangrove: there was only ever one clojure app in use internally
22:53seangroveferd: If it's for a production-level app, don't use Datomic
22:53technomancythough I might be introducing another; we'll see
22:53seangroveThat must be some kind of universal law
22:53seangrove"Never use a database you don't have personal experience with as the foundation of your new production-grade business app"
22:54seangroveAlways screw around with it first
22:54technomancythe project I spend most of my time on just isn't a good fit. since mcgranaghan switched to Go I don't think there are any other clojure fans at work.
22:54callentechnomancy: did he make a post about why he switched?
22:54technomancyseangrove: there's no replacement for Erlang for what we're using it for
22:54callenas far as clojure hiring, I've always seen it as something you don't hire directly for.
22:54technomancycallen: no, but I know that he never used a repl when writing clojure
22:54seangroveYeah, that was the turning point from what I heard, when even Mcgranaghan gave up
22:54callenRather, somebody volunteers to teach the next hire that is interested in it.
22:54technomancyso it's no surprise he didn't mind writing Go
22:54callenand that scales up in a double-fashion quickly.
22:54callentechnomancy: ...never used...a repl?
22:55technomancycallen: a victim of Textmate
22:55callenpoor bastard.
22:55seangroveouch
22:55technomancymaintaining his stuff was all "OK, you made a change; now deploy it to staging to see if it works"
22:55technomancyinsane
22:55callentechnomancy: I actually shied away from Go because the entire community told me I didn't need a debugger or a REPL.
22:55callentechnomancy: not exaggerating.
22:55seangrovetechnomancy: Yeah, Erlang comment was tongue-in-cheek
22:55technomancycallen: yep. completely baffling.
22:55technomancythere's no excuse for ignoring interactive development. life is too short.
22:55callentechnomancy: why did testing his code require abusing staging? no unit tests?
22:56technomancycallen: yeah that too
22:56callentechnomancy: their counter-argument was that type signatures and documentation should be enough @ interactive development.
22:56technomancyso it's actually kind of relieving that app has been retired
22:56technomancyhaha
22:56technomancytype signatures; the ones that are required because you have a crappy inference engine?
22:56callenLOL
22:57callenI really have to think that the sort of people who think they can do without interactive development haven't done any seriously complicated development that meant interacting with unfamiliar code or libraries
22:57callenspend their whole lives in the stdlib.
22:57callenmy contracting work was too vertical to be like that.
22:58callenincidentally Go's equivalent to ring is actually part of the stdlibs.
22:58seangrovego does allow for some pretty impressive code:functionality ratios, and stays readable
22:59callenseangrove: I *like* Go, that's why I said I shied away from after having to confront the rest of the community
22:59callenseangrove: they just lack taste.
22:59seangroveHeh, they're alright
22:59technomancyyeah and gofix is an amazing feat for a non-homoiconic language
22:59seangroveAt least when comparing them to the CL community
23:00seangroveAnd yes, gofix is awesome
23:00technomancybut you have to draw a line somewhere
23:00technomancyand for me it's that I won't go back to punch cards
23:00seangroveHrm, I wonder if community is the right word in CL's case...
23:00seangroveWarzone maybe?
23:00callenseangrove: dude. CL was my original serious PL
23:01technomancyI tried it with Mirah (where I had the excuse of wanting to target mobile) and said never again.
23:01callenseangrove: C# and Python, which came after CL for me, were like dying and going to heaven.
23:01seangroveHeh, I love CL in many ways, it's mind-blowingly cool
23:01seangroveBut it's impossible to get any consensus in the community, and everyone is extremely hostile
23:01callenseangrove: I was trying to get work done. To that end, CL was painful in many non-trivial ways.
23:02n_bI went Java->Python->Ruby->JS->Clojure in learning order, every one has been a step up except for JS
23:02callenseangrove: in the end, using CL means doing everything yourself. Absolutely no division of labor or real community-wise code reuse beyond things like WHO and Hunch.
23:02seangrovecallen: CL's fine for getting work done, particularly with quicklisp these days
23:02n_bClojure has the friendliest community, Python the broadest range of application+well-written code, Ruby the largest # of mono-lingual devs
23:02seangroveBut yeah, its' difficult
23:03n_bI wanted to pick up CL or an ML next, but the communtiy aspect makes it daunting
23:03technomancyn_b: erhm; ruby more than Java even?
23:03callenseangrove: quicklisp makes it easy to get libraries you can't use to begin with :P
23:03seangroven_b: Interesting's point about ruby mono-lingual devs...
23:03n_btechnomancy: Yes, but that's a view shaped by only doing Java @ Google
23:03callenseangrove: try using a CL library written by a guy who read Let over Lambda, let me know how that goes for you.
23:03seangrovecallen: And lots of them!
23:03clojurebotcallen: there's a small subset of things you *can* do in paredit that I actually do -- I would imagine the same is true for most
23:03technomancyn_b: ah, that makes sense
23:03seangrovecallen: I've written tons of them ;)
23:03technomancycallen: hah
23:03seangroveSo I'm part of the problem, hah
23:03callenseangrove: see? this is why I'm here.
23:04seangroveLoL is amazing though... definitely enjoyed it
23:04seangroveAbused the hell out of it
23:04callenrestraint and taste are very important to me. That's why I went Python after using Python and Ruby at the same time for a few years.
23:04seangroveAnd I'm all better now... mostly
23:04n_band I'll never even go so far as to suggest I'm a competent Java dev, so I can't speak to it much. The perspective I have on it is very unusual
23:04seangrovecallen: Clojure's definitely in a nice spot for that so far
23:04callenseangrove: agreed.
23:04n_bcallen: Ruby taught me a great deal about metaprogramming and made me a much better Python developer; frankly I don't enjoy using either nowadays
23:05callenrestaint, taste, and power all in one package.
23:05seangroveBut isn't Haskell more so?
23:05callenn_b: python is still my day job, I don't mind it, but OTOH, the codebase is my personal kingdom of functional programming.
23:05seangroveI've been increasingly impressed with some of the ideas behind Haskell these days
23:05callenseangrove: Haskell is BDSM incarnate.
23:05n_bFP in python is ehhhh
23:05callenHaskell was a great learning experience, but I'll never use it for anything I care about.
23:05seangroveWhy's that?
23:05n_bseangrove: the restraint and academic background crimp its power in a number of places
23:05callenHaskell did a lot to improve my Python code.
23:06seangroven_b: I'm not sure...
23:06n_bthe default string impl, for one, is a linked list
23:06seangroveI think it may end up fulfilling the goals of Lisp in a more powerful way
23:06callenn_b: there a lot of reasons not to use Haskell, that's not precisely one of them.
23:06callenn_b: more importantly, there are 3 or 4 prominent string types that all work differently and seem to have half-overlapped use-cases
23:06callenfor which any given 3rd party library can choose to use any mix of them they like
23:06n_bI'm aware, it's just one of the things that immediately springs to mind
23:06callenwhich means you end up doing a ton of typecasting all over your damn code
23:06callen*irritating*
23:07callenalso cabal is a Lovecraft Horror of the first order.
23:07n_bmy knowledge of Haskell is informed entirely by my roommate having taught it to me, and then going through The Haskell Road. Can't comment to using it productively and would defer to others.
23:07callencabal did a LOT to make me stop using Haskell.
23:07n_bCabal2 is better! _we swear_
23:08callenwhenever a buddy that uses haskell asks me why I went 100% clojure for side projects, I usually point to leiningen and compare it with cabal.
23:09n_bWhere's that quote about the #haskell community and it's tendency to immediately jump to arguments about the most generic way of doing something?
23:09TimMccallen: When you say that Clojure is not usually something one "hires for", do you mean that you don't restrict yourself to hiring existing Clojure users?
23:09seangrovecallen: You've certainly got a lot of reasons why you've stopped using languages ;)
23:09callenTimMc: yes, and it puzzles me when people claim you have to do so.
23:09TimMcMe too.
23:09callenClojure is not difficult to learn and a lot of backgrounds are good for learning it.
23:09callenPython, Ruby, and Java people are all well suited to learning it, if they want to learn FP.
23:10TimMcThat's one of my pet peeves: People overestimate the difficulty of learning languages and underestimate the difficulty of learning tools, libraries, and services.
23:10callenthe O'Reilly book is well designed.
23:10callenTimMc: THANK YOU! Yes. That.
23:10TimMcI think it's because they usually only know one of the former and many of the latter.
23:10callenTimMc: that's why leiningen is so important to me.
23:10callenTimMc: tools can turn into a bigger time-suck than your problem you're solving in a hury.
23:10TimMcBecause it's dead easy?
23:10callenhurry*
23:10callenTimMc: and well-designed, etc etc
23:11TimMc"Oh, you know Java? Good. Now let's get you up to speed on our 35 tera-LOC codebase."
23:11callenTimMc: incidentally I know a Java dev that is terrified of and refuses to use any other languages
23:11callenTimMc: I figured out why...he didn't really understand what he was doing
23:12callenhe only understood IntelliJ and Spring
23:12callenand anything outside Spring and IntelliJ, he didn't understand a whit.
23:12callenLike say, basic unix principles. 0 comprehension.
23:12n_bI don't understand how that happens
23:12n_bI can understand knowing something else and not understanding Java
23:12callenn_b: I don't either, but this character is starting to build a picture for me as to how it happens
23:12n_bIt took me a couple of books and tons of time in a code base to figure out the typical design patterns
23:12callenit seems to largely arise from complaceny and over-reliance on familiar tools.
23:13TimMccallen: Tab-complete your way to working software!
23:13callenTimMc: yeah that's actually how he codes.
23:13callenTimMc: it took ages to explain to him why I use Emacs.
23:13TimMcIt's how *I* code.
23:13TimMcI mean, at work, when doing Java.
23:13callenTimMc: there's nothing wrong with it as long as you understand what's going on
23:13callenthe problem is, the "helpers" were a crutch for him
23:14renderfulthey refer to these people as brogrammers
23:14seangroven_b: Linux is a rabbit hole of knowledge
23:14callenrenderful: kinda-sorta. Brogrammers is more of Ruby/Rails community archetype.
23:14seangroveIt's not something you "just pickup" unless you're really banging away at it
23:14renderfulcallen: yes, because they rely too much on Rails magic
23:14TimMcI'm largely working with existing libraries, so it's not unreasonable.
23:14renderfulwhich is similar
23:14callenseangrove: I learned Linux by using over 100 different distributions and just constantly breaking and reconfiguring shit.
23:14callentook years. pretty big timesink.
23:14renderfulsame for me callen
23:15renderful15 years so far
23:15seangroveBut that's my point
23:15callenif I didn't do a fair bit of dev-ops alongside my coding these days, it'd have been a pretty big waste.
23:15seangroveI've use it for years
23:15callenrenderful: similar number of years here, I started with Red Hat 5
23:15seangroveWasn't until I had to build something paas-like out of it, and later lxc, that I started to grok some of the ideas and implementations behind it
23:15renderfulyar, slackware 3 i believe
23:15TimMcI picked up GNU/Linux in 2005. I now feel confident in using dd without wiping my hard drive. It's been... an interesting journey.
23:16callenI started from a young age, so some of my time was misspent
23:16seangrovePoint being, that I would in no way expect someone who says they "know Java" to "know linux"
23:16callenbut I started with Linux in 1998
23:16seangroveHeh, the glory days of wasted time
23:16renderfulmost of my time was misspent :)
23:16TimMcseangrove: Wait, where did Linux come into this? I think I missed something.
23:17callenseangrove: I guess, but my point is that he was unwilling to learn and was afraid of anything outside of his cocoon.
23:17renderfulbut i love all of that time that i spent doing bullshit and making mistakes
23:17seangrovecallen: Ah, yes
23:17callenTimMc: what I said about the dude being clueless outside of generating java and XML in his IDE
23:17ioexceptionUsing windows for Java dev, is a bit painful to me, no tools.. no grep, no less, no shell...
23:17TimMcOh, I see it now.
23:17n_bseangrove: The way I took "didn't understand what he was doing" was that as a programmer he lacked a mental model and was cargo culting via intellisense to software; I would absolutely not expect someone to go from JVM->kernel dev
23:17callenseangrove: you should at least know some basic unix commands if you're deploying to Linux servers on a regular basis.
23:17callenwhat n_b said.
23:17n_bI'd expect someone to go from using Play! to Rails without issue
23:17seangroveIt's important to have an attitude of "Fuck, another problem? Alright, have to solve it. A kernel compilation problem? Alright... let's look that up..."
23:18callenn_b: agreed although Rails has a pretty deep rabbit-hole of conventions.
23:18ioexceptionn_b: high expectations, not the common human
23:18TimMcYou can get surprisingly far in any computery thing with mimicry.
23:18callenPlay! is a bit better designed.
23:18n_bPlay! (1.0 at least) and Rails are fairly similar in terms of convention doing significant amounts for you
23:18seangroveioexception: Yeah, I think in the same way, I have *no idea* about developing on windows, despite having used it a ton as a child
23:19seangroveTimMc: Well put!
23:19callenn_b: I've used Rails at a few different points in its evolution, my point is that your point was more true a couple years ago
23:19callenn_b: it's less true these days because Rails has a really deep and very vertical stack of things you need to learn that are usually scaffolded for you.
23:19seangroveMeh, I love rails for what it's good at
23:20renderfulagreed seangrove
23:20seangroveIt'll be interesting to see if it can evolve from what it is now to where people are going though
23:20callenI prefer Django and Flask. more restraint, more obvious as to how it works, less magic.
23:20renderfulmagic is bad
23:20seangroveNever used flask, just Django and a fuck-ton of pylons
23:20n_bioexception: then I've only been exposed to some very top-tier developers, but nigh every person I've worked with has started out on JVM or the CLR and later migrated to Python, Rails, or similar, typically when going from BigCo™ to a startup
23:21callenI went CLR -> Python professionally and I use Clojure a lot on my free time.
23:21callenit's been a similar Java/CLR -> Python/Ruby migration path for most startup people I know that have past experience
23:21n_bRails is a rabbit hole, no doubt, but I much, much rather come into some weirdly configured, built from mish-mash of Active* components and rack middleware ruby project than some GWT-monstrosity
23:22callenn_b: agreed
23:22n_bat least than the change/reload/recompile is faster while breaking stuff
23:25seangroven_b: sounds right
23:25seangroveOnly used GWT for two weeks in a side project years ago, and wrote the gwt-rails plugin at the time
23:25seangroveWas an absolute nightmare
23:26squidzseangrove: why is that?
23:26n_bGWT is a really great idea implemented poorly
23:26seangroveMainly there wasn't any documentation at the time, almost at all. The tooling was beyond horrendous..
23:26n_b, to the extent that it's not really a great fit for what people expect of modern applications
23:26clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: to in this context, compiling:(NO_SOURCE_PATH:0)>
23:26seangrove(dec n_b)
23:26lazybot⇒ -1
23:27seangroveSorry, had to happen
23:27squidzouch
23:27seangrove(inc n_b_
23:28seangrove(inc n_b)
23:28lazybot⇒ 0
23:28squidzseangrove: didnt know you could go negative
23:28seangroveOk n_b, I hope you've learned your lesson
23:28n_bDon't split messages on clauses?
23:28seangroveExactly
23:28seangroveAt least not when the bots are watching
23:29n_bTime to whip up an irssi script that escapes any messages starting with a comma
23:29callen(inc n_b)
23:29lazybot⇒ 1
23:29seangrove(inc me)
23:29lazybot⇒ 2
23:29seangrovewoo!
23:30squidzcallen: what's CLR?
23:30callensquidz: .NET runtime
23:30n_b,(identity n_b) ;;I assume this doesn't work
23:30clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: n_b in this context, compiling:(NO_SOURCE_PATH:0)>
23:30squidzoh i see
23:30callensquidz: in a past life I was a code monkey for enterprise/insurance companies.
23:30callennow I'm a pirate for a bay area startup. whee.
23:30squidzlucky you
23:31seangrovecallen: If you're out here anyway, why not drag arohner's cofounder out to drinks anyway?
23:31n_bGoing to MS for the summer, will be my first experience somewhere that uses anything MS
23:33seangroven_b: I've been impressed with all my friends that have worked at MS
23:34seangroveThough none of them were in the business area...
23:34rbxbxMS has a wonderful research department fwiw.
23:35callenseangrove: his cofounder hates me, haha.
23:35n_bLooking forward to it, will be on a team doing exciting-ish stuff and it should be useful experience if I go interview for APM back at Google
23:35seangrovecallen: Really? That's impressive
23:35TimMcrbxbx: Can you develop on anything other than Windows in MS Research?
23:35seangroveHe seems like a very chill guy overall
23:35n_band I can stick around for Seajure :)
23:35callenseangrove: other than the pull request I sent him on github, the last time I had a conversation with his cofounder I ended up getting hellbanned from HN.
23:35callenseangrove: he is a very chill guy.
23:35n_bTimMc: they do tons of non-Windows stuff
23:35rbxbxTimMc I'm not sure... they seem to have a lot of Haskell/functional cats over there.
23:35TimMcI would not be able to go back to Windows.
23:36seangrovecallen: That can't have been a "conversation" then...
23:36rbxbxI'd imagine in R&D you're capapble of doing research on other platforms so long as you could bring something back to MS land
23:36rbxbxie: F# or linq
23:36rbxbx(maybe other things as well)
23:37squidzIve heard somebody say that Google uses bayes filtering the way MS uses if statements, but im not sure who said it
23:37callenseangrove: depends on how you look at it. it was a conversation about an IRC service that shut-down.
23:37n_bIME the people at Google and the people at Microsoft are equally capable at least as far as the rank and file are concerned
23:37seangrovecallen: 'fess up, what did you say about his mother...
23:38callenseangrove: myself and a few others noted that the founder of the service had a habit of starting and dropping services without warning that had paying customers. rohner's cofounder took exception to this.
23:38seangroveAh yes, grove
23:38seangroveYou were one of the dicks he was referring to, presumably?
23:38callenI don't think I was even the main one.
23:38callenseangrove: amusingly, Raynes was one of the people he was arguing with as well.
23:39callenI described his position on the matter as "advocating for total unaccountability on the part of startup founders"
23:39seangroveLeah's certainly had a weird path at this point
23:39callenthat's what really set him off.
23:39callenseangrove: throwing spaghetti at the wall is fine, that's not my problem.
23:39seangroveYeah, he seemed very incensed at the time
23:39callenseangrove: my problem is doing it at the expense of paying (business!) customers.
23:39callenthey deserve to be warned in future if she starts a service designed to serve businesses that it might disappear from underneath them at any time.
23:40callenif she'd handled her past projects in a more professional manner, I doubt anybody would've noticed or cared.
23:40seangroveYeah, we shutdown Bushido, and spent probably a week migrating everyone
23:40callenshe didn't, so we noticed. Then rohner's cofounder got really mad.
23:40callenoh well.
23:40seangroveNot a single user complained in a way we didn't take care of... felt happy of that at least
23:40callenI'm mostly mad about my account getting hellbanned. I've been through like 4 or 5 HN accounts.
23:41callenseangrove: I'm otherwise sanguine about the matter.
23:41callenseangrove: are you in SF?
23:41seangroveI am
23:41seangroveYourself?
23:42callenseangrove: MV
23:42seangroveI also like Paul a lot ;)
23:42seangroveAh, I lived there for ~2 years
23:42TimMcMolybdenum Valley?
23:42callenI like Paul, he just holds opinions I'm not going to coddle or countenance seriously.
23:42technomancysounds like a good preventative measure
23:42callentechnomancy: you're too well known
23:42seangrovetechnomancy: I can have a word for you if you'd like...
23:43callenI actually heard about him originally because of his compiler work.
23:43callenI didn't really make the connection between his compiler work and CircleCI until he popped up in a discussion about HipHop
23:44technomancyI could be like giles bowkett and just redirect all HN-referred requests to a page telling them how they're jerk-faces
23:44seangrovearohner: There're a lot rumors about your cofoudner flying about
23:44seangroveYou might want to squash them sooner rather than later
23:44mehworkhow do you apply a symbol to each item in a coll?
23:44seangroveRumors like he cared enough to comment on hiphop...
23:44callentechnomancy: part of the reason I mention ES off and on is that I've been able to use it in creative ways to make hard problems VERY tractable. @ bowkett: that's some dedicated trolling.
23:44technomancycallen: he's a remarkable man
23:44callenseangrove: meh, I tried @'ing him earier, he didn't respond. I think he's semi-AFK or doesn't have working notifications in his client.
23:44technomancyin good and bad ways
23:45callentechnomancy: remind me why he did that?
23:45technomancycallen: he writes a lot of very flame-baity articles, mostly well-written but the kind of things that bring out the worst of HN
23:45callenhttp://hyperdex.org/ <--- I use ES for a similar use-case as this
23:46seangroveES?
23:46clojurebothttps://github.com/dakrone/cheshire
23:46callentechnomancy: the only threads that don't bring the worst out of HN are about Erlang.
23:46callenseangrove: elasticsearch
23:46callentechnomancy: remember the day of Erlang?
23:46seangroveAh, ok
23:46callenit was glorious.
23:46mehworkwell actually how do you map symbols to things like so '("a" "b" "c") becomes {:foo "a" :bar "b" :baz "c"}
23:46seangrovemehwork: zipmap?
23:47seangrove,(zipmap [:foo :bar :baz] ["a" "b" "c"])
23:47clojurebot{:baz "c", :bar "b", :foo "a"}
23:47mehworkyeah zipmap works darnit my question stilli sn't what i mean
23:47Raynescallen: Who was I arguing with?
23:47callenmehwork: please elaborate.
23:47seangroveRaynes: technomancy over clojars
23:47callenRaynes: cofounder of CircleCI. The grove.io thread.
23:47technomancycallen: I must have missed that
23:47Raynescallen: Oh, yeah, that one-can-short-of-a-one-pack guy.
23:47callenRaynes: I'm the Gandalf of remembering HN threads.
23:48RaynesYeah, that guy was about as smart as as box of hair.
23:48callenRaynes: LOL
23:48seangroveHah, ouch
23:48mehworkzipap only maps 1:1, and i need to create a nested map as i do it, such that: '("a" "b" "c") becomes: {:foo {:foo "a"}, :bar {:bar "b"}, :baz {:baz "c"}}
23:48TimMcRaynes: See, this is why Alabama is allowed.
23:49RaynesIt's just that I like Leah and didn't mean anything by it, but by the 3rd or 4th abandoned startup, you start to wonder if you should really rely on anything she does. *shrug*
23:49TimMcThe South has some pretty good sayings.
23:49RaynesIt's great for her startup lifestyle, not so great for users of said startups.
23:49seangroveTimMc: I sitll think it's a stretch to argue the existanace of the south is justified
23:49callenMy position was identical to Raynes'
23:50Raynesseangrove: So what was I arguing with technomancy about clojars for?
23:50seangroveRaynes: sorry, just a bit of trolling
23:50callenRaynes: he was kidding
23:50mehworkthe south deserves to exist. the people in it are another question ;p
23:50TimMcseangrove: It's also very scenic.
23:50callenRaynes: the argument mentioned was the grove.io thread.
23:50RaynesWell, I actually did complain about technomancy making the releases repo.
23:50technomancywe got bit by grove.io disappearing and are stuck on campfire =(
23:50technomancyit's ... not a good piece of software.
23:50callentechnomancy: haha oh god, point proven.
23:50seangrovetechnomancy: Stripe might release their system
23:50callentechnomancy: most people make-do with campfire by using propane.
23:51technomancycallen: unacceptable
23:51seangroveIt's an irc server witha web frontend as well
23:51RaynesBut then I realized it didn't effect me at all as long as I put information in my project.clj that I should have put there anywhere.
23:51callentechnomancy: if I made a grove.io clone, would your company pay for it?
23:51technomancyfor many reasons, foremost of which is that it's not Emacs
23:51Raynestechnomancy: I've yet to figure out why people don't just get a private channel on any given IRC network.
23:51RaynesUnless you're Red Hat.
23:51technomancycallen: the problem isn't a lack of alternative, it's that I blew my "get me the hell away from campfire" capital on a lost cause =\
23:51callenRaynes: my company did that initially.
23:51RaynesWho has like 400 IRC channels on their private network.
23:51callentechnomancy: that's sad. Really sad.
23:51technomancyRaynes: because "freenode" isn't "free as in we host your infrastructure for you"? =)
23:52callenwe actually switched away from freenode because it was too unreliable.
23:52Raynestechnomancy: I set up an ircd once. I would not recommend it.
23:52TimMcRunning a private IRC server is like... the easiest thing, right?
23:52callenTimMc: if you're competent at the whole unix and editing text files thing, sure.
23:52technomancyRaynes: we used subrosa (written in Clojure) at my last job and it was awesome.
23:52Raynestechnomancy: The only people who say setting up an IRC network is easy are people who have already done it a couple of years ago and blocked out the memory of it.
23:52TimMccallen: Wait, there's no GUI? :-O
23:53callentechnomancy: subrosa is abandoned, no?
23:53Raynescallen: If you're competent at editing text files with settings that seem nearly meaningless.
23:53RaynesBut are super important.
23:53technomancycallen: it's not actively developed, but it's in active use every day by its author, which counts for something?
23:53RaynesWell, I'll be honest, setting up the server is fairly simple. Linking services and other servers with it is not.
23:53callentechnomancy: fair enough.
23:53technomancyRaynes: the problem is using software that's not written in lisp.
23:54technomancyugh; flashbacks to configuring znc--so horrible
23:54Raynestechnomancy: The problem is using software with custom configuration languages.
23:54technomancyfaux-xml
23:54technomancyis. the. worst.
23:54technomancyworse even than .ini files
23:54RaynesDear people, you do not need a custom configuration language. Use a good language.
23:54rkingWell, what's the solution to the config problem?
23:54technomancyRaynes: yes: if your programming language isn't sufficient for a config file language I don't even want to talk to you; just leave the premises at once or I'll call the ~gourds on you
23:54seangroveOr use a non-deterministic config language
23:54callenI've actually been giving thought as to how to make a reliable distributed IRC network
23:54rkingRaynes: OK so how do you get it from that language to your language?
23:55Raynesrking: In Clojure, my configuration language *is* my language.
23:55rkingEverybody has to write configs in the language that's interpreting them? What does C do, then?
23:55RaynesI was kinda implying you shouldn't do it in C. :p
23:55rkingRaynes: Do you have an example of software that uses Clojure as a config?
23:55technomancyinc
23:55Raynesrking: Plenty of my own software, and pretty much everyone elses.
23:55RaynesDid I offend you or something somehow?
23:55seangrovetechnomancy: dec
23:55rkingRaynes: URL to config files?
23:56callenanyone seen Nginx or Varnish config files?
23:56RaynesI think I offended him. :(
23:56mehworkDjango uses python as a config language
23:56callenit's a mini-language just for configuration. Hilarious.
23:56amalloyrking: every project.clj file ever, is leiningen's configuration, in clojure
23:56technomancycallen: nginx doesn't feel so bad just because it's usually compared with apache
23:56TimMcI write my Piet config files in Piet, what's the problem?
23:56callentechnomancy: I know...god I hate configuring apache.
23:56amalloy(inc piet)
23:56lazybot⇒ 1
23:56Raynesrking: Well, there is lazybot. It uses Clojure code for configuration. The plugins might as well be configuration because they are dynamically loaded at runtime.
23:57RaynesI mean, I'm not sure what I have to prove.
23:57callenTimMc: I prefer Mondrian.
23:57RaynesClojure is perfect for Clojure configuration.
23:57RaynesIt's just natural.
23:57RaynesPython and Ruby and even Haskell can do it too.
23:57TimMcRaynes: My entire source tree is config for the JVM.
23:57mehwork"code being data"
23:57RaynesSee xmonad for Haskell.
23:57callenTimMc: HAHAHAHA
23:57callenTimMc: the people who've worked in "enterprise" will get your joke :P
23:57RaynesBut seriously, I promise, it's possible, people do it, it's better.
23:57TimMcMy hard drive is source for the CPU.
23:57TimMc*config
23:58Raynesxmonad is a great example.
23:58technomancyseangrove: I actually think the suckless way is great for C programs
23:58TimMccallen: I'm not sure I get it from that perspective, jsut from a comp arch perspective.
23:58RaynesI'd also bet that you can even do something like it in C.
23:58mehworkif the world only makes sense to you in java/xml then the world might has well have just ended today afterall
23:58rkingHahaha
23:58technomancyseangrove: you want to reconfigure it? recompile it. it only takes 5s because it's small =)
23:58rkinghttps://github.com/flatland/lazybot/blob/develop/.lazybot/config.clj
23:58rking*That's* supposed to be an end-user facing config lang?
23:58technomancyanything larger and you have no business using C =)
23:58RaynesUh
23:58mehworkrking: that's what admin interfaces are for
23:59rkingSorry, I'm new enough to clojure that I didn't realize that was as good as it gets.
23:59RaynesI...
23:59technomancyjson would be OK for config if it weren't for the insane refusal to support comments
23:59RaynesI didn't...
23:59TimMcrking: Looks fine to me.
23:59ibdknoxRaynes: make better configs :p
23:59ibdknoxgeez
23:59RaynesI never said that was as good as it gets, Mr. Sir. Furthermore, end-user configurations?
23:59TimMctechnomancy: Crockford is pretty weird about JSON.
23:59rkingmehwork: Then the serialization format doesn't matter if you have an admin interface. Could be a gzipped wad of ints.
23:59callenrking: it would seem you haven't done much Clojure development.