2012-12-21
| 00:00 | amalloy | i don't know clojure's do-notation, but in haskell you can do it like: do {x <- return value; return (function x)} |
| 00:01 | sgeo_ | In clojure.algo.monads at least, domonad puts an implied return around the last expression |
| 00:01 | sgeo_ | So a bit like a list/monad comprehension |
| 00:31 | muhoo | frozenlock: is cljs-in-cljs a real thing? |
| 00:31 | ghadishayban | &(let [^{this should really throw an exception} foo 42] foo) |
| 00:31 | lazybot | ⇒ 42 |
| 00:31 | ghadishayban | hilarious |
| 00:32 | muhoo | metadata on a vector? |
| 00:32 | ghadishayban | &(let [foo ^{this should really throw an exception as well} []] foo) |
| 00:32 | lazybot | ⇒ [] |
| 00:32 | TimMc | That's... surprising. |
| 00:32 | bbloom | &(let [foo ^{this should really throw an exception as well} []] (meta foo)) |
| 00:32 | lazybot | ⇒ nil |
| 00:32 | ghadishayban | see my comments on CLJ-1136 |
| 00:33 | ghadishayban | compiler bug |
| 00:33 | ghadishayban | metadata in a let binding vec doesn't get evaled |
| 00:33 | amalloy | ,(let [foo ^{this should really throw an exception as well} []] (meta foo)) |
| 00:33 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: as in this context, compiling:(NO_SOURCE_PATH:0)> |
| 00:34 | bbloom | &(macroexpand '(let [foo ^{w t f ?} []] foo)) |
| 00:34 | lazybot | ⇒ (let* [foo []] foo) |
| 00:34 | amalloy | i recommend using clojurebot for this, bbloom. lazybot probably messes up metadata |
| 00:34 | TimMc | Anything to do with lazybot's parser/expander? |
| 00:34 | mehwork | from 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:34 | bbloom | ,(binding [*print-meta* true] (macroexpand '(let [foo ^{w t f ?} []] foo))) |
| 00:34 | clojurebot | (let* [foo []] foo) |
| 00:35 | bbloom | hm |
| 00:35 | mehwork | im trying everything i can google and nothing ever echo's back |
| 00:35 | bbloom | ,(binding [*print-meta* true] (macroexpand '(identity ^{w t f ?} [])) |
| 00:35 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 00:35 | bbloom | ,(binding [*print-meta* true] (macroexpand '(identity ^{w t f ?} []))) |
| 00:35 | clojurebot | (identity []) |
| 00:35 | bbloom | *shrug* i've had bad luck with metadata |
| 00:35 | ghadishayban | print-meta won't affect that i believe |
| 00:35 | bbloom | (doc *print-meta*) |
| 00:35 | clojurebot | "; 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:36 | ghadishayban | it's a bug in Compiler$LetExpr |
| 00:36 | TimMc | bbloom: You didn't print. |
| 00:36 | ghadishayban | TimMc: exactly |
| 00:36 | bbloom | TimMc: dur. yes, the repl is printing OUTSIDE heh |
| 00:36 | bbloom | my bad |
| 00:36 | bbloom | ,(binding [*print-meta* true] (prn (macroexpand '(identity ^{w t f ?} [])))) |
| 00:36 | clojurebot | (identity ^{f ?, w t} []) |
| 00:36 | bbloom | ,(binding [*print-meta* true] (prn (macroexpand '(let [foo ^{w t f ?} []] foo)))) |
| 00:36 | clojurebot | (let* [foo ^{f ?, w t} []] foo) |
| 00:37 | bbloom | hm yeah, gotta be a bug in LetExpr since it's not a bug in the let macro |
| 00:38 | bbloom | anyway: 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:41 | TimMc | Wait, so how is it that (let [foo ^{a b} []] foo) throws and (let [^{a b} foo []] foo) doesn't? |
| 00:42 | TimMc | I would think that both would throw, actually. |
| 00:42 | TimMc | Do metadata literals have an implicit quote? |
| 00:43 | amalloy | TimMc: [] gets eval'd, and foo doesn't, in that context. i imagine that's relevant |
| 00:43 | ghadishayban | good catch |
| 00:44 | ghadishayban | it won't really affect type hints though: |
| 00:45 | amalloy | of course it does. (Class/forName "not real") isn't a meaningful type-hint if it doesn't get eval'd |
| 00:46 | TimMc | (prm `^{a (+ 1 2)}[]) ;;= "^{clj.core/a (clojure.core/+ 1 2)} []" |
| 00:46 | TimMc | ^ (defn prm [s] (binding [*print-meta* true] (pr-str s))) |
| 00:46 | ghadishayban | but typically ^objects or ^floats |
| 00:47 | TimMc | ,(meta ^ints []) |
| 00:47 | clojurebot | {:tag #<core$ints clojure.core$ints@605af24c>} |
| 00:47 | TimMc | Hmm, some sort of special-casing there... |
| 00:47 | ghadishayban | do the bots support def? |
| 00:47 | TimMc | ghadishayban: Nope. Their sandboxes don't allow environment mutation. |
| 00:48 | amalloy | i believe the issue is that (let [^{:tag (Class/forName "x")} name val] ...) is equivalent to (let [name ^{:tag (list 'Class/forName "x")} val] ...) |
| 00:48 | TimMc | ghadishayban: By the way, you can /msg them to test stuff out. |
| 01:00 | pendlepants | would anyone recommend using an IDE for clojure development? noticed that intellij is $50 today, but am not sure how helpful it'd be. |
| 01:01 | technomancy | pendlepants: IIRC the clojure support for intellij works fine in the OSS version |
| 01:01 | pendlepants | oh, cool. thanks technomancy. |
| 01:02 | pendlepants | is the value in an IDE re: debugging and java interop, or are most people using emacs? |
| 01:02 | pendlepants | s/the/there/ |
| 01:03 | Raynes | pendlepants: Most people are using Emacs, but plenty of people also use counterclockwise for Eclipse. |
| 01:03 | technomancy | most people use emacs. the value of an IDE depends on whether you end up working on large java codebases alongside your clojure. |
| 01:03 | Raynes | I don't think java interop is a factor, and there is some debugger stuff for Emacs too (ritz). |
| 01:03 | Raynes | But if you're happy with something like Eclipse or Intellij, nobody will lynch you. |
| 01:04 | technomancy | I 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:04 | technomancy | but you can do a lot in clojure without ever having to do that; it depends on what you're writing |
| 01:04 | bbloom | it's impossible to navigate certain java codebases</message> |
| 01:04 | Raynes | I've yet to need an IDE. |
| 01:04 | Raynes | But I've yet to work with a Java codebase. |
| 01:04 | Raynes | Besides libraries, at least. |
| 01:04 | Raynes | Nothing app-level. |
| 01:05 | pendlepants | that 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:05 | pendlepants | but that's heartening. |
| 01:05 | Raynes | I don't think an IDE will really help you with any foot shooting. |
| 01:05 | technomancy | pendlepants: for pure-clojure code you almost never need a stepping debugger |
| 01:06 | bbloom | (-> some (long sequence of code) with a random println (in the middle) tends to work out) |
| 01:06 | Raynes | Of 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:06 | Raynes | Chas Emerick, author of Clojure Programming, uses Eclipse for his Clojure development. No shame in it. |
| 01:06 | Raynes | I mean, he has plenty of shame, but not because of that. |
| 01:07 | pendlepants | I'm used to vim and have been developing in that w/ some tmux stuff to get copy/paste into the repl. |
| 01:07 | Raynes | Vim works well for Clojure. |
| 01:07 | bbloom | pendlepants: time to upgrade to tpope's foreplay! |
| 01:07 | technomancy | don't switch from vim to emacs while trying to learn clojure at the same time |
| 01:07 | bbloom | pendlepants: https://github.com/tpope/vim-foreplay/ |
| 01:07 | technomancy | your brain will explode |
| 01:07 | pendlepants | yeah, if vim's not a huge pain with clojure I'd just as soon keep using it. |
| 01:07 | Raynes | pendlepants: 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:08 | Raynes | technomancy: I really don't buy that as a general thing for everybody. |
| 01:08 | bbloom | Raynes: it's common enough to be ill advised |
| 01:08 | Raynes | Like, I learned Emacs and Clojure at the same time and I was like 13. |
| 01:08 | bbloom | Raynes: being 13 makes it far easier |
| 01:08 | technomancy | Raynes: yeah, but when you're older it's harder to learn new things |
| 01:08 | Raynes | Alright gramps. |
| 01:09 | Raynes | I'll respect my elders and concede for now. |
| 01:09 | bbloom | Raynes: you didn't have to *unlearn* anything first :-P |
| 01:09 | technomancy | also when you have lots of free time =) |
| 01:09 | Raynes | I was really busy. Internet porn and what not. |
| 01:09 | bbloom | vim was hard for me after 5 years of visual studio |
| 01:09 | bbloom | damn free copies for schools, that shit is like crack |
| 01:10 | bbloom | just as bad for you. |
| 01:10 | technomancy | but unfortunately it's legal |
| 01:10 | bbloom | who do we sue? |
| 01:11 | Raynes | Sue Chris Granger for damages, bbloom. |
| 01:11 | Raynes | He worked on VS. |
| 01:11 | Raynes | :) |
| 01:11 | ibdknox | I had nothing to do with it |
| 01:11 | bbloom | .... so did i.... |
| 01:11 | bbloom | OMG I HAVE TO SUE MYSELF |
| 01:11 | Raynes | technomancy: We have a traitor in our midst. |
| 01:11 | ibdknox | I wanted to create a sku for $50 |
| 01:11 | ibdknox | not a free one ;) |
| 01:12 | technomancy | Raynes: you know what to do |
| 01:12 | technomancy | ~guards |
| 01:12 | clojurebot | SEIZE HIM! |
| 01:12 | bbloom | i wrote a large portion of the XNA sample games... i'm like walter white over here... |
| 01:12 | Raynes | ibdknox: Were you just eavesdropping, or do you get highlighted on 'Chris' or 'Granger'? |
| 01:13 | technomancy | bbloom: if you're going to make this difficult... |
| 01:13 | technomancy | ~gourds |
| 01:13 | clojurebot | SQUEEZE HIM! |
| 01:13 | amalloy | he gets highlighted on "Sue" |
| 01:13 | Raynes | Hahahaha |
| 01:13 | ibdknox | yep. |
| 01:13 | amalloy | years of microsoft paranoia |
| 01:13 | ibdknox | I actually happened to be looking |
| 01:13 | technomancy | amalloy: I was thinking along the lines of "A boy named..." |
| 01:13 | ibdknox | though I highlight my name to see all the bad things you guys say about me. |
| 01:13 | ibdknox | fuckers. |
| 01:14 | Raynes | ibdknox: Man, did you see all the people *thanking* us for deprecating noir? |
| 01:14 | Raynes | It was spectacular. |
| 01:14 | ibdknox | It was the right thing to do :) |
| 01:14 | Raynes | A few people were sad and wanted me to be like "No, I was just kidding! Noir is back!" |
| 01:14 | Raynes | But most of them were ecstatic. |
| 01:14 | bbloom | "how dare you build something for free and then get busy and change your preferences in design!" |
| 01:15 | Raynes | Well, he didn't go that far. :p |
| 01:15 | bbloom | notice: no question mark |
| 01:15 | technomancy | Raynes: that would have been great if April were closer |
| 01:15 | ibdknox | lol |
| 01:15 | Raynes | He 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:15 | Raynes | *shrug* |
| 01:16 | Raynes | I tried my best to not sound snarky, but... that just smells bad. |
| 01:16 | amalloy | good thing you didn't hack into his computer and upgrade him, then |
| 01:16 | ibdknox | I understood what he was saying, but he's looking at the problem wrong |
| 01:16 | ibdknox | what he wants can easily be accomplished by simply creating a template for compojure/lib-noir |
| 01:16 | Raynes | ibdknox: 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:16 | ibdknox | and then fixing up some docs |
| 01:17 | Raynes | ibdknox: I've got two things on my TODO re that goal. |
| 01:17 | augustl | pasting 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:18 | ibdknox | Raynes: oh? |
| 01:18 | Raynes | ibdknox: 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:18 | ibdknox | also how did we get away from berating bbloom? |
| 01:19 | Raynes | Well, not necessarily a tutorial, but like a getting started sort of thing like is on the front page. |
| 01:19 | bbloom | i berate myself plenty |
| 01:19 | ibdknox | Raynes: sounds like the right thing to do :) |
| 01:19 | Raynes | Maybe port the tutorials and stuff. |
| 01:19 | ibdknox | Raynes: that also covers that guys points |
| 01:19 | pendlepants | bbloom: thanks for the link to vim-foreplay; this is great. |
| 01:19 | Raynes | What Compojure needs is a good documentation website. |
| 01:19 | ibdknox | yes |
| 01:19 | Raynes | And 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:19 | bbloom | pendlepants: don't take me, thank tpope |
| 01:19 | ibdknox | and I'm sure weavejester would love it if someone put one together :) |
| 01:20 | bbloom | thank* |
| 01:21 | Raynes | ibdknox: Anyways, if the world ends in a few hours, meet me half way through the country. |
| 01:22 | ibdknox | right at midnight the power went out here (I'm visiting NC) |
| 01:22 | ibdknox | it has since unfucked itself |
| 01:22 | bbloom | power company have a sense of humor? |
| 01:22 | Raynes | You and amalloy and I could survive an apocalypse |
| 01:23 | ibdknox | Raynes: I have a fair number of unusual skills that would be very useful in such a situation |
| 01:23 | technomancy | I wonder if I'll ever get tired of ~guards |
| 01:23 | ibdknox | technomancy: I never do |
| 01:23 | technomancy | ibdknox: good to know it's not just me |
| 01:23 | ibdknox | bbloom: I'm fairly convinced it was someone being funny |
| 01:23 | Raynes | technomancy: I always cut up when you do ~gourds afterwards. |
| 01:23 | amalloy | $eball |
| 01:24 | amalloy | damn. Raynes, how do i ask him if technomancy will get tired of ~guards? |
| 01:24 | Raynes | amalloy: Long since removed. |
| 01:24 | Raynes | IIRc |
| 01:24 | technomancy | will I ever tire of ~guards?? |
| 01:24 | lazybot | technomancy: Definitely not. |
| 01:24 | amalloy | i guess i could cheat: o great lazybot, will technomancy ever grow tired of ~guards?? |
| 01:24 | lazybot | amalloy: Uh, no. Why would you even ask? |
| 01:24 | technomancy | sweet |
| 01:24 | Raynes | I 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:24 | Raynes | But that's probably because I did too much core rewriting. |
| 01:25 | technomancy | clojurebot: botstack is <reply>/me puts lazybot on his head and gropes blindly for a third bot to complete the stack. |
| 01:25 | clojurebot | Alles klar |
| 01:26 | ibdknox | lol |
| 01:26 | technomancy | another classic from the Emacs channel |
| 01:26 | technomancy | but they actually have three bots in there, so it's a bit less awkward |
| 01:27 | bbloom | clearly somebody just needs to write a 3rd bot |
| 01:28 | technomancy | did we have a haskell bot at one point? |
| 01:28 | technomancy | or no, lazybot speaks haskell |
| 01:28 | ibdknox | correct |
| 01:28 | amalloy | $heval [1,2..10] |
| 01:28 | technomancy | chouser_log is a bot |
| 01:28 | amalloy | damn it. i can't do anything right |
| 01:51 | witt3rd | hello. may i ask a lighttable question (quick) |
| 01:52 | bbloom | ibdknox ^^ |
| 01:53 | bbloom | just ask |
| 01:54 | witt3rd | is there a known issue in the latest build (OSX) with the instarepl eval munging the fn names with od chars |
| 01:54 | witt3rd | (def ï·‘'fn (fn [n] (+ n n))) |
| 01:54 | witt3rd | (ï·‘'fn 4) => 8 |
| 02:14 | ibdknox | witt3rd: it is now: https://github.com/Kodowa/Light-Table-Playground/issues/237 |
| 02:14 | witt3rd | :-) |
| 02:15 | ibdknox | thanks :) |
| 02:15 | ro_st | ibdknox - just curious, have you done anything with websockets and cljs? |
| 02:16 | ibdknox | yeah |
| 02:16 | ro_st | what did you use on the backend? aleph? |
| 02:16 | ibdknox | though in every case I cheated |
| 02:16 | ro_st | oh, how so? |
| 02:16 | ibdknox | aleph originally |
| 02:16 | ibdknox | now socket.io |
| 02:16 | ro_st | so node.js on the back |
| 02:16 | ibdknox | I didn't need to support anything other than hcrome |
| 02:16 | ibdknox | chrome* |
| 02:17 | ibdknox | Yeah, now it's node |
| 02:17 | ibdknox | aleph worked fine though |
| 02:17 | ibdknox | didn't try any scaling with it |
| 02:17 | Ember- | 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:17 | Ember- | similar to ctrl+lmb in eclipse+java or f3 in counterclockwise? |
| 02:17 | ibdknox | Ember-: not in the current version |
| 02:17 | Ember- | ok |
| 02:17 | Ember- | so I'm not dumb :) |
| 02:18 | ro_st | ok, thanks. we plan to go pretty large with websockets and i've seen a fair number of complaints about aleph's overall speed |
| 02:18 | ibdknox | though some changes I needed on the CodeMirror side came in that will let me do the function "bubbles" correctly this time |
| 02:18 | Ember- | that's one of the last things preventing me from using it for real |
| 02:18 | ibdknox | ro_st: I wrote a netty-based websocket server previously |
| 02:18 | ibdknox | that was blazingly fast |
| 02:18 | ibdknox | orders of magnitude faster than node at the time |
| 02:19 | ibdknox | Ember-: just to confirm I understand, you're talking about go-to-definition right? |
| 02:19 | Ember- | yes |
| 02:19 | Ember- | loving light table so far btw, happy I contributed in the kickstarter |
| 02:19 | Ember- | make it shine ;) |
| 02:20 | ro_st | it's going to be so cool once we have websockets and storm drpc set up |
| 02:20 | ibdknox | Ember-: I'm hoping I'll get to announce a hire or two soon, which will mean that will come even faster :) |
| 02:20 | ro_st | real-time all the things |
| 02:20 | Ember- | I'm pretty sure that six months from here it's light table all the way for me with clojure |
| 02:20 | Ember- | oh really cool |
| 02:21 | ro_st | ibdknox: did you ever look at atmosphere? https://github.com/Atmosphere/atmosphere |
| 02:22 | ro_st | looks like it suports socket.io's protocol |
| 02:22 | ro_st | we need a jvm solution so that we can leverage datomic's peer caching |
| 02:23 | brainproxy | need to take a break and play w/ something .. different .. tcl or rebol/red? |
| 02:23 | ibdknox | ro_st: I did not |
| 02:23 | ibdknox | ro_st: when I looked into that stuff (where I actually needed to scale) I'm fairly certain that wasn't well known :) |
| 02:23 | augustl | I prefer (with-thing (fn [thing] .. do stuff .. )) over a macro style (with-thing [thing] .. do stuff ..), am I crazy? :) |
| 02:24 | ro_st | no. functions always compose better than macros! |
| 02:25 | ibdknox | ro_st: this has been gaining some steam lately https://github.com/sockjs/sockjs-client |
| 02:25 | ibdknox | ro_st: and it's got a vert.x impl (JVM) |
| 02:25 | augustl | ro_st: that's what I'm thinking too |
| 02:25 | brainproxy | the aleph/lamina guy said he was looking into sockjs |
| 02:26 | augustl | I 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:26 | brainproxy | but I haven't seen any movement in that regard, i.e. on his github account |
| 02:27 | ro_st | sockjs looks great |
| 02:27 | brainproxy | "looking into" meaning considering a aleph/lamina based clojure server that would implement sockjs "spec" |
| 02:28 | ro_st | atmosphere looks like it's pretty thoroughly battle tested |
| 02:29 | brainproxy | yeah, but i was hunting for a clojure wrapper/bridge to it, didn't see anything |
| 02:29 | augustl | ro_st: I prefer to use something like faye instead of socket.io or sockjs, faye uses fewer hacks |
| 02:29 | brainproxy | not that clj java interop is bad, but it's just nice to have idiomatic functional api |
| 02:29 | augustl | sock.io has a lot of pretty nasty hacks in order to get cross origin messaging |
| 02:29 | ro_st | got a link, augustl? |
| 02:29 | brainproxy | augustl: faye is cool |
| 02:29 | augustl | ro_st: http://faye.jcoglan.com/ |
| 02:29 | brainproxy | but ... you're buying into the whole bayeux thing |
| 02:29 | augustl | brainproxy: yeah I'm using it a lot |
| 02:30 | augustl | true, but the java comet something project supports it |
| 02:30 | ivan | most things, including sockjs, think it's okay to reorder or lose data |
| 02:30 | ivan | you have to think about HTTP for over 10 minutes to see the problem |
| 02:30 | brainproxy | augustl: right because faye is an impl of bayeux, which is the basis of cometd |
| 02:30 | augustl | ro_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:30 | augustl | and for a project I needed to use a html4.1 frameset doc |
| 02:31 | ro_st | yikes |
| 02:31 | ro_st | we only support modern-ish browsers anyway. ie9+. |
| 02:31 | augustl | this is mostly because it does really funky stuff to achieve cross origin comapt, I think it submits forms in an iframe or smt |
| 02:31 | brainproxy | ivan: socket.io, i think, has an optional ack api that will allow you to implement logic which could avoid reordering and msg loss |
| 02:32 | ivan | brainproxy: 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:32 | brainproxy | ivan: that's what I was going to say next |
| 02:32 | brainproxy | :) |
| 02:32 | brainproxy | the long and short being that it's best to use it in scenrios where lossy notification stream isn't a big deal |
| 02:32 | ivan | someone wrote a BrowserChannel server for Clojure |
| 02:33 | ro_st | looks like i have my homework cut out for me. thanks for the options, all |
| 02:33 | ro_st | browserchannel - that's in google closure js, isn't it? |
| 02:33 | ro_st | this, ivan? https://github.com/thegeez/clj-browserchannel-demo |
| 02:33 | ivan | yes. and it is reliable and used by gmail. |
| 02:33 | ro_st | https://github.com/thegeez/clj-browserchannel too |
| 02:33 | ivan | not sure if the server is any good though |
| 02:33 | ivan | yes, that's the one |
| 02:34 | ivan | if I had infinite time I would port my Minerva server from Twisted to some Clojure thing |
| 02:34 | ro_st | interesting. this looks pretty compelling |
| 02:34 | ro_st | what we'd be using it for is pretty well defined |
| 02:34 | brainproxy | yeah, but browserchannel is not websocket, right? |
| 02:35 | ro_st | correct |
| 02:35 | ro_st | http://thegeez.net/2012/04/03/why_browserchannel.html |
| 02:36 | ivan | if you think about the problem for even longer you discover that connection-oriented semantics are pretty crap |
| 02:36 | brainproxy | can't remember if faye websocket guarantees message order |
| 02:36 | ivan | CCNx probably has good ideas |
| 02:36 | ivan | websocket does |
| 02:36 | ivan | is faye websocket not websocket? |
| 02:36 | ro_st | i'm open to any solution that allows bi-di browser/server comms on the jvm |
| 02:37 | brainproxy | ivan: sorry for confusion |
| 02:37 | brainproxy | faye is an implementation of bayeux protocol |
| 02:37 | brainproxy | http://svn.cometd.com/trunk/bayeux/bayeux.html |
| 02:37 | brainproxy | but bayeux specs http, nothing about websocket |
| 02:37 | ivan | I can't remember what exactly was wrong with bayeux but I think it was in my not-even-wrong category |
| 02:37 | brainproxy | so faye's maintainer implemented his own idea for realizing bayeux over websocket transport |
| 02:38 | brainproxy | that's what i meant by faye websocket |
| 02:38 | brainproxy | but 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:39 | brainproxy | ivan: cometd is an implementation of bayeux .. i think |
| 02:40 | ivan | last I checked, yeah |
| 02:40 | brainproxy | imo, the real problem w/ sock, etc. is that devs start to drift into rpc/rmi mindset |
| 02:42 | brainproxy | and so create opaque "pipes" for data transport, when they would be better off using rest/hypermedia principles for their web apps/apis |
| 02:42 | ivan | the content-centric networking talk is a must-watch |
| 02:43 | ivan | the only problem is that it's much harder to design such a thing than dumb pipes |
| 02:43 | ro_st | we're using event sourcing for our client side data and persistence models |
| 02:43 | ivan | http://www.youtube.com/watch?v=oCZMoY3q2uM |
| 02:43 | brainproxy | have your read amunsen't "hypermedia oriented design"? |
| 02:43 | ivan | don't think so, I'll check it out |
| 02:43 | brainproxy | *amundsen |
| 02:44 | ro_st | right 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:44 | ro_st | same events as normal, just coming from a different place |
| 02:44 | brainproxy | ivan: http://amundsen.com/articles/hypermedia-oriented-design/ |
| 02:44 | ro_st | ivan: Datomic has rest api, so right now :-) |
| 02:45 | brainproxy | ivan: also see http://amundsen.com/hypermedia/profiles/ |
| 02:54 | augustl | so.. 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:54 | augustl | I'm thinking plain old reference counting, but perhaps there's something more clever I can do |
| 02:55 | augustl | also, 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:59 | amalloy | so 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:01 | augustl | amalloy: sec, interpreting :) |
| 03:01 | augustl | amalloy: hmm, don't think so. I should probably have explained it better.. |
| 03:02 | augustl | each 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:05 | callen | I feel like this is going to be really dumb, but I'm going to ask anyway |
| 03:05 | callen | if I have a function returning [ [] [] [] ] |
| 03:05 | callen | and its result is going inside of another vector, how do I splice the sub-vectors into the enclosing vector? |
| 03:06 | augustl | callen: mapcat does this |
| 03:07 | augustl | mapcat is for mapping _and_ concatenating in one go though |
| 03:07 | callen | I don't need to map. |
| 03:07 | callen | I think the answer to my question was concat. |
| 03:08 | augustl | ,(reduce concat [[1] [2] [3]]) |
| 03:08 | clojurebot | (1 2 3) |
| 03:09 | mthvedt | ,(apply concat [[1] [2] [3]]) |
| 03:09 | clojurebot | (1 2 3) |
| 03:09 | augustl | ah |
| 03:10 | mehwork | what's the proper way to return true from a defn? |
| 03:10 | amalloy | true |
| 03:10 | mehwork | ah no parens |
| 03:11 | amalloy | parens are always for calling functions |
| 03:29 | ro_st | and for list literals, when quoted |
| 03:29 | ro_st | '(:a :b :c) |
| 03:32 | borkdude | or inside macro's, like ns |
| 03:32 | ro_st | yes |
| 03:33 | borkdude | usually return true or false from a function involves a decision which has already the value true or false, so that can be returned |
| 03:36 | bbloom | or (boolean that) |
| 03:36 | bbloom | which 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:38 | mehwork | in 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:38 | callen | is there a good/established way to manage application configs in Clojure? particularly when handling prod vs. local/testing |
| 03:39 | ro_st | callen: we use env vars |
| 03:39 | ro_st | only sane way. config in the git repo is a bloody pane |
| 03:39 | ro_st | s/pane/pain |
| 03:39 | ro_st | http://www.12factor.net/config |
| 03:39 | bbloom | i always prefer env vars plus a separate config repo |
| 03:39 | bbloom | the config repo contains config for all deployed software |
| 03:40 | ro_st | we have a pallet repo which has everything |
| 03:40 | ro_st | so i guess i concur :-) |
| 03:40 | bbloom | mehwork: what error do you get? |
| 03:40 | callen | oh I see, this is for people terrified about configs getting into source control |
| 03:40 | bbloom | callen: no, i want my configs in source control |
| 03:41 | bbloom | but configs are a separate concern since they span multiple versioning boundaries |
| 03:41 | ro_st | yes. because it's a pain with multiple servers (prod/test/dev/dev/dev) |
| 03:41 | callen | I never really had that much of a problem with it. |
| 03:41 | bbloom | it wasn't an issue for us until we had 5+ smaller programs, each in it's own language |
| 03:41 | bbloom | then env vars became the only sane approach |
| 03:41 | callen | in Python/Flask we used settings.cfg for prod, test_settings.cfg for local dev, staging_settings.cfg, experimental_settings.cfg, etc |
| 03:42 | bbloom | and we were duplicating config per project |
| 03:42 | callen | and pointed at each file based on ENV var. |
| 03:42 | bbloom | yeah, only need a small handful of env vars |
| 03:42 | callen | just the one, for us. |
| 03:42 | bbloom | often YOURCO_ENV is enough |
| 03:42 | ro_st | the solution we have is one that we no longer need to think about |
| 03:42 | callen | it didn't require any thought on our part either. |
| 03:42 | bbloom | but sometimes YOURCO_HOST and a few others are nice to have |
| 03:43 | bbloom | for app-specific, deployment-independent config: by all means, put that in your repo and check it in :-P |
| 03:44 | ro_st | https://www.refheap.com/paste/7773 |
| 03:45 | ro_st | works nicely for us |
| 03:47 | mehwork | bbloom: unable to resolve symbol "arg1" in this context |
| 03:47 | bbloom | mehwork: refheap your code |
| 03:48 | mehwork | fixed now, it was a typo |
| 03:48 | bbloom | heh |
| 03:48 | mehwork | refheap? |
| 03:48 | clojurebot | refheap is gist |
| 03:48 | tomoj | lol |
| 03:48 | bbloom | ~pastebin |
| 03:48 | ro_st | refheap.com |
| 03:49 | bbloom | ~paste |
| 03:49 | bbloom | clojurebot seems lazy |
| 03:50 | tomoj | grr.. I want to make my cljs port of clojure.test support asynchronous tests, but it uses a bunch of dynamic variables |
| 03:51 | bbloom | :-/ |
| 03:51 | bbloom | tomoj: so i think most async test frameworks out there are pretty terrible |
| 03:52 | tomoj | specifically in the way they handle async? |
| 03:52 | bbloom | 90% 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:52 | bbloom | much more pleasant than (expect n-asserts) etc |
| 03:53 | tomoj | etc includes calling a callback to indicate that you're done? |
| 03:54 | tomoj | wouldn't that mean you have to wait for the timeout on every test? if the timeout is pretty short, maybe not so bad |
| 03:54 | bbloom | it'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:55 | bbloom | tomoj: you can run async tests in parallel, so timeouts are overlapping |
| 03:57 | tomoj | and then you need some way to say "this test isn't safe, don't run it in parallel"? |
| 03:58 | tomoj | well I'm thinking of browser integration tests there, but you can't really do that with cljs.test anyway |
| 03:58 | bbloom | i 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:59 | bbloom | and all those operators do is queue.append |
| 03:59 | bbloom | and you also have operators like assert_location, has_text, etc |
| 03:59 | bbloom | none of those operators take callbacks |
| 04:00 | tomoj | better not have those running in parallel, though, right? unless you have multiple browser windows, one running each test? |
| 04:00 | bbloom | right |
| 04:00 | bbloom | tomoj: example asynchronous integration test https://gist.github.com/4351531 |
| 04:01 | bbloom | works super smoothly & is blazing fast |
| 04:01 | bbloom | using the queue strategy |
| 04:02 | bbloom | we had 100+ of those tests & our non-programmer CEO wrote most of them via copy paste :-) |
| 04:04 | bbloom | other than things that were integration testable, we had very little async javascript |
| 04:05 | tomoj | nice, even cucumber doesn't claim to be ceo-writable :) |
| 04:06 | bbloom | english is a terrible programming language :-P |
| 04:06 | bbloom | to be fair, our CEO was smart enough to learn and ultimately prefer both HAML and SASS |
| 04:07 | bbloom | anyway, if you're doing an async testing framework in cljs, consider the queue approach! would love to see what you come up with :-) |
| 04:07 | augustl | hmm, 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:08 | tomoj | my first tendency is to just write tests that return promises |
| 04:08 | bbloom | augustl: describe your use case and why/how you elected to use refs |
| 04:09 | augustl | it's probably easier if I describe my overall goal, paste coming up |
| 04:09 | bbloom | tomoj: as useful as promises are, i think this idea of "let's use promises all the time every time!" is flawed |
| 04:09 | bbloom | i'd prefer a very limited async api surface |
| 04:09 | bbloom | which is difficult if you have a REST api or similar |
| 04:10 | bbloom | but 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:10 | tomoj | in cljs.test I just imagine being able to do (deftest foo [done] (js/setTimeout #(do (is (= 42 42)) (done)))) |
| 04:11 | tomoj | then 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:11 | bbloom | sounds reasonable |
| 04:11 | tomoj | in the queue approach, I guess if a test times out with no assertions, that's a failure? |
| 04:12 | callen | bbloom: re: HAML/SASS -> fairly analogous to hiccup/clj-style. |
| 04:12 | bbloom | tomoj: yes |
| 04:12 | bbloom | tomoj: but you also need to handle assertions coming after the timeout has already expired: also a failure... a *perf* failure :-) |
| 04:13 | bbloom | callen: i'm aware |
| 04:13 | callen | bbloom: just humming. Hacking on a ring app right now. |
| 04:14 | callen | bbloom: using hiccup, contemplating the merits of clj-style. |
| 04:14 | bbloom | callen: did you also evaluate https://github.com/paraseba/cssgen ? |
| 04:16 | tomoj | I wonder if it acceptable for a cljs bound-fn stopgap to ignore set! |
| 04:17 | augustl | bbloom: https://www.refheap.com/paste/7775 - or anyone, not just bbloom :) |
| 04:17 | bbloom | tomoj: you mean with respect to root bindings vs dynamic bindings? |
| 04:17 | tomoj | yeah |
| 04:18 | augustl | my 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:18 | augustl | since it's an I/O object |
| 04:18 | bbloom | augustl: you're only altering a single ref in each transaction. why not use atoms? |
| 04:18 | tomoj | since cljs will allow you (?) to do (binding [*foo* 42] (set! *foo* 43) ((bound-fn *foo*))) |
| 04:18 | tomoj | for which a stopgap will return 42 |
| 04:18 | augustl | bbloom: can I use atoms for atomic "get or set"? |
| 04:18 | bbloom | (doc atom) |
| 04:18 | tomoj | but people shouldn't be doing that anyway :/ |
| 04:18 | clojurebot | "([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:19 | bbloom | that's not a super helpful doc string if you don't knwo what an Atom is :-P |
| 04:19 | augustl | :) |
| 04:19 | augustl | I thought all operations on atoms were outside a transaction |
| 04:19 | bbloom | augustl: http://clojure.org/atoms |
| 04:19 | augustl | since you call "swap" without dosync |
| 04:19 | augustl | that is, you don't need to put it in a transaction |
| 04:19 | bbloom | so 90% of the time, you want an atom |
| 04:19 | augustl | so atoms can do atomic "get or set"? |
| 04:20 | bbloom | the purpose of an atom is to do atomic compare-and-swap |
| 04:20 | bbloom | via ##(doc swap!) |
| 04:20 | lazybot | ⇒ ------------------------- 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:20 | bbloom | there's a sort of implicit "transaction" around f |
| 04:20 | augustl | I see, so I could pass my own function that gets or sets? |
| 04:20 | bbloom | ,(let [x (atom 10)] (swap! x + 5) x) |
| 04:20 | clojurebot | #<Atom@4a1bb681: 15> |
| 04:21 | bbloom | augustl: right |
| 04:21 | bbloom | also available ##(doc reset!) |
| 04:21 | lazybot | ⇒ ------------------------- clojure.core/reset! ([atom newval]) Sets the value of atom to newval without regard for the current value. Returns newval. nil |
| 04:21 | augustl | makes sense, the values inside the function you pass to swap doesn't need to be derefed so they're in a transaction |
| 04:21 | bbloom | yeah |
| 04:22 | augustl | still 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:22 | bbloom | refs are for when you have to coordinate writes between multiple mutable places |
| 04:22 | bbloom | and even then atoms are often better if you can get away with a map inside an atom |
| 04:22 | augustl | bbloom: I think I might need to coordinate multiple state changes though |
| 04:23 | augustl | as soon as someone gets an index writer, it's associated index reader should be tagged as "please die" |
| 04:23 | augustl | then as soon as all current users of the index reader (via with-index-reader) finishes, it should be closed |
| 04:23 | augustl | hmm, that's just one state change :) |
| 04:23 | bbloom | hmm what are the ownership semantics of a writer? |
| 04:24 | bbloom | how many/which threads are responsible for IO? |
| 04:24 | augustl | bbloom: index writers stay alive forever. Then HTTP requests comes in and reads and writes. |
| 04:25 | augustl | so it's very side effecty indeed, since individual threads/http requests will read and write in any order at any time |
| 04:25 | bbloom | there can be multiple simultaneous writers per index ? |
| 04:25 | augustl | no, just one writer per index |
| 04:25 | augustl | but multiple calls to the same writer. That is handled by the writer code though, it's thread safe |
| 04:26 | bbloom | hm, generally, i try to isolate IO to a small number of workers and communicate with them |
| 04:26 | bbloom | particularly for network, one IO thread is often enough for a gigabit |
| 04:26 | bbloom | but disk IO is different.... |
| 04:27 | bbloom | how many indexes do you expect to have? |
| 04:28 | augustl | bbloom: a bunch, there's one index per main domain object in my system |
| 04:28 | bbloom | augustl: so on the order of a dozen? |
| 04:28 | augustl | probably not more than hundreds or so per server though |
| 04:28 | bbloom | hm |
| 04:28 | augustl | s/server/process |
| 04:28 | bbloom | have you considered an agent per index with async writes? |
| 04:28 | augustl | go on :) |
| 04:29 | augustl | ah, I think I see what you mean |
| 04:29 | bbloom | you basically have one atom which is a map of domain object -> table manager |
| 04:29 | bbloom | the table manager is an agent which is basically the current state, read/write/etc |
| 04:29 | bbloom | and you send messages to the appropriate agent to perform IO |
| 04:30 | bbloom | this way you use a swap! on the db atom to load a table |
| 04:31 | bbloom | (send (@db :foo) some-write-operation bar) ; might be send-off, i can never remember which is which |
| 04:31 | augustl | hmm |
| 04:32 | bbloom | for reads, you can pass the agent a promise and then block on that |
| 04:32 | augustl | might as well make my lucene indexing eventually consistent :) |
| 04:32 | bbloom | queues and messages: damn good ideas that more people need to employ more often :-) |
| 04:34 | augustl | considering using elastisearch instead.. Spending time on lucene details is not important for my business :P |
| 04:35 | bbloom | also valid :-) |
| 04:35 | augustl | and it makes my system composed of simple services, yay |
| 04:37 | bbloom | i'm not sure i like the name "simple service" |
| 04:37 | bbloom | i'd call them "utility services" in the same vein as utility functions and utility programs |
| 04:37 | bbloom | :-) |
| 04:38 | augustl | hmm, I don't think of queues and full text search systems and databases as utilities |
| 04:40 | bbloom | well they certainly aren't simple! :-) |
| 04:44 | ro_st | complections? :-) |
| 04:45 | augustl | datomic 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:45 | augustl | so I suppose that means datomic complects my app with the datomic peer or something like that? :P |
| 04:47 | augustl | not 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:48 | tomoj | that sucks |
| 04:49 | augustl | I 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:49 | tomoj | seems like there should be a way to deal with that, which doesn't involve OSGI cus wtf is that |
| 04:50 | augustl | speaking of elastisearch. Are there any libraries I can use that manages the http details for me? Retries, keep-alive connection pooling, etc |
| 04:52 | tomoj | clj-http has both of those features |
| 04:53 | augustl | ah |
| 04:54 | augustl | hmm, 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:55 | augustl | sounds dangerous though, since then it probably applies to all calls to clj-http that might happen in libraries etc |
| 04:55 | tomoj | oi |
| 04:55 | augustl | so some out of sight pool would be nice |
| 04:56 | tomoj | and of course the only way to pass it in is with the dynamic var |
| 04:56 | tomoj | oi |
| 04:56 | augustl | :( |
| 04:56 | augustl | I hate it when libraries does that! |
| 04:57 | tomoj | fairly easy patch it seems though |
| 04:57 | augustl | I could just bind it on every call I do, since I have one thread per request anyway |
| 04:57 | augustl | like, (with-connection-pool my-global-pool do-stuff) |
| 04:57 | tomoj | except with-connection-pool is even less usable than that |
| 04:58 | augustl | I meant my own with-connection-pool, sorry |
| 04:58 | augustl | where I manually set the binding |
| 04:58 | tomoj | ah, I see, yeah |
| 05:00 | augustl | complects my system with ring handlers though.. I might not always have one thread per business logic operation, meh. |
| 05:01 | augustl | suppose I could just use the Java lib from apache directly |
| 05:03 | augustl | seems that irccloud.com is down :) |
| 05:03 | tomoj | I don't think it should be hard to patch clj-http to just accept a conn manager in the request |
| 05:03 | augustl | only problem would be if it already makes use of arity dispatch |
| 05:06 | tomoj | nah it's a big map https://github.com/dakrone/clj-http/blob/master/src/clj_http/core.clj#L179 |
| 05:06 | augustl | ah, nice |
| 05:06 | augustl | I'll put it on my TODO list for the evening :) |
| 05:08 | tomoj | would be nice to also split with-connection-pool up to make it easier to get ahold of a conn manager |
| 05:08 | tomoj | hmm |
| 05:08 | tomoj | https://github.com/dakrone/clj-http/blob/master/src/clj_http/client.clj#L726 |
| 05:09 | tomoj | wat? |
| 05:09 | clojurebot | For Jswat: start clojure with -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888 |
| 05:12 | augustl | tomoj: :D |
| 05:12 | augustl | hmm, just passing the connection manager in with the map makes sense, in order to not mess with arity |
| 05:13 | augustl | (http/post "http://foo.com" {:connection-manager my-manager}) |
| 05:14 | augustl | one of the lessions I've learned in my 4-5 months as a Clojure programmer, is that complex encapsulation really sucks. |
| 05:21 | ro_st | would you go back to your previous language(s)? |
| 05:25 | clgv | how do I "freeze a snapshot to [a] dated version" in leiningen? |
| 05:25 | augustl | ro_st: I still program a lot of user interfaces, mutable single threaded environments are still status-quo there.. |
| 05:25 | augustl | ro_st: building systems with OO would be extremely painful now though |
| 05:27 | ro_st | +1. |
| 05:27 | ro_st | to think i was going to use Rails for the backend -shudder- |
| 05:29 | augustl | I'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:33 | ro_st | condolences |
| 05:34 | fredyr | how are you integrating your rails app with the jvm? |
| 05:35 | fredyr | running a queue inbetween? |
| 05:36 | augustl | fredyr: yup |
| 05:36 | augustl | and the JVM stuff writes directly to the same postgres db |
| 05:36 | fredyr | nice |
| 05:36 | fredyr | which queue? |
| 05:36 | augustl | haven't decided yet :) |
| 05:36 | fredyr | i've been working with rabbit lately |
| 05:37 | ro_st | rabbit is nice |
| 05:37 | fredyr | i can recommend that one |
| 05:37 | fredyr | yeah definitely |
| 05:37 | fredyr | and the bindings for JVM and ruby are good |
| 05:37 | augustl | as long as it talks something like stomp, it's pretty portable anyway |
| 05:48 | fredyr | ok haven't looked at stomp |
| 06:12 | silasdavis | Could someone tell me why (map pretty-message (message/all)) works, (-> (message/all) (map pretty-message)) doesn't? |
| 06:13 | silasdavis | Don't know how to create ISeq from: pretty_message |
| 06:13 | silasdavis | ah I thought -> inserts as second argument |
| 06:14 | cemerick | no, -> is thread-first |
| 06:14 | cemerick | ->> is thread-last |
| 06:14 | silasdavis | ah it is the second element in the list which is hte first argument |
| 06:14 | silasdavis | thank you |
| 06:14 | cemerick | yup |
| 06:14 | cemerick | np |
| 06:14 | clgv | how do I "freeze a snapshot to [a] dated version" in leiningen? |
| 06:15 | silasdavis | is (->> seq (map f) (map g) (map h)) an idiomatic way of chaining maps? |
| 06:15 | silasdavis | is there a better way? |
| 06:16 | bpr | silasdavis: you could do (map (comp h g f) seq) |
| 06:17 | silasdavis | oh of course |
| 06:17 | silasdavis | thanks |
| 06:17 | bpr | sure thing |
| 06:18 | bpr | but on the other hand if there are reduces and filters, etc. the threading macro can be nice |
| 06:32 | acron^ | is there some short hand for this? |
| 06:32 | acron^ | .(map #(str %) (seq "Hello, World")) |
| 06:32 | acron^ | ,(map #(str %) (seq "Hello, World")) |
| 06:32 | clojurebot | ("H" "e" "l" "l" "o" ...) |
| 06:34 | acron^ | ,(split "Hello, World" "*") |
| 06:34 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: split in this context, compiling:(NO_SOURCE_PATH:0)> |
| 06:36 | cemerick | ,(map str "hello, world") |
| 06:36 | clojurebot | ("h" "e" "l" "l" "o" ...) |
| 06:36 | acron^ | facepalm |
| 06:36 | acron^ | thanks |
| 06:37 | silasdavis | I am getting an arity exception from ((fn [m] ([:li (pretty-message m)])) ({:edge 34})) |
| 06:37 | cemerick | you're invoking the map as a function with no arguments |
| 06:37 | silasdavis | but fine if I remove the anonymous function and insert the map |
| 06:41 | silasdavis | Oh i was trying to evaluate the vector |
| 06:41 | silasdavis | and the map |
| 06:55 | clgv | how about ##(seq "hello, world") |
| 06:55 | lazybot | ⇒ (\h \e \l \l \o \, \space \w \o \r \l \d) |
| 07:09 | acron^ | clgv: they aren't strings then |
| 07:09 | clgv | ahok. didnt know that was a requirement ;) |
| 07:09 | acron^ | :) |
| 07:10 | acron^ | turns out string/split is probably more suited to my needs anyway |
| 08:05 | augustl | what's a good way to do this transformation? https://gist.github.com/4352622 |
| 08:07 | augustl | updated it slightly, the original maps can have multiple keys |
| 08:10 | bpr | (reduce #(merge-with conj %1 %2) {} data) seems like a good start |
| 08:11 | augustl | oh neat |
| 08:11 | augustl | bpr: do I really need an initial empty map there? |
| 08:12 | bpr | no |
| 08:12 | bpr | i usually like to put an explicit initial value though |
| 08:13 | bpr | you may want: (reduce #(merge-with (comp vec flatten conj) %1 %2) data) |
| 08:13 | augustl | aww, that gives me (reduce #(merge-with concat %1 %2) queries) yay |
| 08:13 | augustl | just concat instead of conj |
| 08:13 | bpr | depending on your requirements for the values in the resulting map |
| 08:13 | augustl | thanks :) |
| 08:13 | bpr | oh or that lol |
| 08:14 | augustl | :D |
| 08:18 | bpr | the 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:18 | ro_st | just a sanity check: are jvisualvm/yourkit the best way to profile clojure? |
| 08:18 | augustl | bpr: ah |
| 08:19 | bpr | ro_st: i'm not a jvm pro, but i do know that this exists: https://github.com/hugoduncan/criterium |
| 08:19 | bpr | it's a clojure lib for benchmarking your code |
| 08:20 | ro_st | thanks, bpr! this looks handy once you've identified hotspots and you're now working to improve them |
| 08:21 | bpr | augustl: that said, my solution with flatten also walks the vector each time it's called too |
| 08:21 | bpr | ro_st: no prob |
| 08:22 | augustl | bpr: are there other data structures than vectors that are good for merging? |
| 08:22 | augustl | ordering doesn't matter so I could use sets |
| 08:22 | bpr | yeah, sets could be a good choice |
| 08:22 | bpr | the concern is the nesting though |
| 08:23 | augustl | and then use clojure.set/join probably |
| 08:28 | bpr | clojure.set/union |
| 08:28 | bpr | though i'm thinking there must be a way to accomplish that with vectors |
| 08:31 | bpr | (reduce #(merge-with (fn [a b] (apply conj a b)) %1 %2) data) |
| 08:32 | bpr | it's cleaner like this: (reduce #(merge-with (partial apply conj) %1 %2) data) |
| 08:33 | bpr | augustl: ^ (in case you missed it) |
| 08:34 | augustl | ah |
| 08:34 | ro_st | partial rocks |
| 09:05 | clojure-newb | hi 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:06 | weavejester | clojure-newb: The body of the request is a java.io.InputStream |
| 09:07 | ro_st | going to clojurewest, weavejester? |
| 09:07 | weavejester | clojure-newb: So you can use clojure.core/slurp, or clojure.java.io/reader with clojure.core/line-seq |
| 09:07 | weavejester | ro_st: Not sure. Maybe not - it's a long way away |
| 09:07 | ro_st | cmonnn i'm going, and i'm from Cape Town, South Africa :-) |
| 09:08 | clojure-newb | weavejester: thx I'll look into ways to work with an InputStream |
| 09:09 | weavejester | ro_st: When is it? March? |
| 09:09 | clojure-newb | weavejester: I'm currently doing (slurp (:body req)), and that way I'm getting all the Content-Type stuff I don't want |
| 09:09 | ro_st | yes |
| 09:11 | weavejester | clojure-newb: What do you mean? The content type is a header. |
| 09:17 | clojure-newb | weavejester: I've tried to capture the details in a paste : https://www.refheap.com/paste/7780 |
| 09:18 | clojure-newb | weavejester: I am probably not explaining myself very well |
| 09:18 | clojure-newb | but I'm trying to just get the csv content in my output |
| 09:18 | ro_st | don't need the reader |
| 09:18 | weavejester | clojure-newb: No, that paste gives me all the info I need |
| 09:18 | ro_st | just (slurp (:body req)) |
| 09:19 | ro_st | clojure-newb: what if you (println req) ? |
| 09:19 | weavejester | clojure-newb: With curl you're uploading a file as multipart form data |
| 09:19 | weavejester | But you're setting the content-type header explicitly as text/csv |
| 09:19 | clojure-newb | ro_st: thx, removed the reader form |
| 09:20 | weavejester | You need to first decide whether you're uploading data in multipart format |
| 09:20 | clojure-newb | weavejester: so my curl post is kinda mixed up |
| 09:20 | weavejester | Or whether you're uploading data directly in the HTTP body |
| 09:21 | weavejester | You're basically saying to curl, upload this as a multipart file, but tell the server it's a raw stream of data |
| 09:21 | weavejester | multipart data can be uploaded through a HTML form |
| 09:21 | weavejester | When you upload a file to a website, that's the format you're using |
| 09:22 | weavejester | The multipart stream also contains information about the file being uploaded |
| 09:22 | weavejester | Such as its content-type (as determined by the client) and the filename |
| 09:22 | weavejester | You can also upload data raw, just by sending the data directly as the HTTP request body |
| 09:22 | weavejester | Without any additional encoding |
| 09:23 | clojure-newb | weavejsester: so I am specifying something extra I don't need in my post ? from curl ? |
| 09:23 | clojure-newb | sorry, a little confused |
| 09:24 | weavejester | clojure-newb: The -F option tells curl to send the file as multipart data |
| 09:25 | weavejester | You need to decide whether that's what you want to do |
| 09:25 | weavejester | Put it another way: what is the intended use for this system? |
| 09:25 | clojure-newb | weavejester: 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:25 | weavejester | clojure-newb: You want the -d option |
| 09:26 | clojure-newb | weavejester: initially just to upload small csv files to import data into a system |
| 09:26 | weavejester | clojure-newb: So you can send it as a multipart form, using -F file=@sample.csv |
| 09:26 | weavejester | clojure-newb: Or you can send it as a raw data stream using -d @sample.csv |
| 09:26 | weavejester | Ring can handle either, but you need to make a choice :) |
| 09:28 | clojure-newb | weavejester: 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:29 | weavejester | clojure-newb: multipart data is a way of uploading one or more files as form data |
| 09:29 | weavejester | clojure-newb: Usually used in web browsers for uploading files to websites |
| 09:52 | clojure-newb | aww, 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:59 | bpr | use clojure.data.csv: https://github.com/clojure/data.csv |
| 10:11 | WokenFury | any guesses why I'm running into this stackoverflow with Noir? |
| 10:11 | WokenFury | Exception in thread "main" java.lang.StackOverflowError |
| 10:11 | WokenFury | at clojure.lang.PersistentHashMap.seq(PersistentHashMap.java:194) |
| 10:11 | WokenFury | at clojure.lang.RT.seqFrom(RT.java:480) |
| 10:11 | WokenFury | at clojure.lang.RT.seq(RT.java:475) |
| 10:11 | WokenFury | at clojure.lang.RT.keys(RT.java:503) |
| 10:11 | WokenFury | at clojure.lang.APersistentSet.seq(APersistentSet.java:45) |
| 10:11 | WokenFury | at clojure.lang.RT.seqFrom(RT.java:480) |
| 10:11 | WokenFury | at clojure.lang.RT.seq(RT.java:475) |
| 10:11 | WokenFury | at clojure.core$seq.invoke(core.clj:133) |
| 10:11 | WokenFury | at clojure.core$set.invoke(core.clj:3643) |
| 10:12 | WokenFury | at ns_tracker.dependency$seq_union.invoke(dependency.clj:13) |
| 10:12 | WokenFury | at ns_tracker.dependency$transitive$fn__19.invoke(dependency.clj:21) |
| 10:12 | WokenFury | at clojure.core.protocols$fn__5871.invoke(protocols.clj:76) |
| 10:12 | WokenFury | at clojure.core.protocols$fn__5828$G__5823__5841.invoke(protocols.clj:13) |
| 10:12 | WokenFury | at clojure.core$reduce.invoke(core.clj:6030) |
| 10:12 | WokenFury | at ns_tracker.dependency$transitive.invoke(dependency.clj:22) |
| 10:12 | WokenFury | at ns_tracker.dependency$transitive$fn__19.invoke(dependency.clj:21) |
| 10:12 | WokenFury | woops. meant to be a refhjeap link, sorry |
| 10:17 | phuff | Howdy. |
| 10:18 | phuff | I'm making my first clojure project. |
| 10:18 | phuff | And 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:18 | phuff | leinigen just loads clojure files for it's config, and I assume that's the preferred way of doing it. |
| 10:18 | phuff | But I thought I'd actually ask somebody first :) |
| 10:22 | dhm | phuff: can you say more about your goal? |
| 10:22 | hyPiRion | phuff: The easiest way is that way, yes. |
| 10:22 | hyPiRion | Have a map in a file, which you read in at runtime. |
| 10:23 | phuff | dhm: So, I'm making a little program that will go and fetch different types of data and make an ebook out of it. |
| 10:23 | phuff | dhm: And I think different users will want different types of data in their ebooks. |
| 10:23 | phuff | So 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:24 | hyPiRion | ,(-> "{:db {:pass \"secret\", :user \"bob\"}}" read-string (get-in [:db :pass])) |
| 10:24 | clojurebot | "secret" |
| 10:25 | xeqi | phuff: either ENV vars or a config file |
| 10:25 | dhm | phuff: 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:25 | xeqi | I've seen https://github.com/sonian/carica recently for config files |
| 10:25 | xeqi | though I've been using https://github.com/weavejester/environ for the ENV var way |
| 10:25 | phuff | dhm: Ah it's not dependencies so much as I need a place to store the things that the user wants |
| 10:25 | hyPiRion | dhm: Yeah, I read it that way as first, but the leiningen thing was an example |
| 10:26 | phuff | Though I suppose if my program gets really popular (hardy har har) then there might eventually be dependncies. |
| 10:26 | phuff | But 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:27 | phuff | (trying to find the part in leiningen's source where they read the project map) |
| 10:27 | hyPiRion | phuff: it's easier to read Raynes' Refheap way of doing it |
| 10:27 | hyPiRion | https://github.com/Raynes/refheap/blob/develop/src/refheap/config.clj |
| 10:28 | hyPiRion | and https://github.com/Raynes/clj-config |
| 10:28 | phuff | Oh that looks neat, hyPiRion |
| 10:28 | hyPiRion | It's very easy to use |
| 10:44 | hyPiRion | Wow, 1.2 certainly is old-fashioned. |
| 10:45 | hyPiRion | Strange defn-rules |
| 10:47 | TimMc | Such as? |
| 10:50 | hyPiRion | (defn ^:private foo ...) isn't allowed |
| 10:51 | hyPiRion | Has to hook it up like (defn foo "docstring" ^:private [params*] ...) |
| 10:54 | TimMc | Oh yeah. |
| 11:59 | frozenlock | I 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:01 | frozenlock | When still in swank, all I had to do was to `print' or `println' anything. In nrepl however, it's not the case :( |
| 12:01 | hyPiRion | frozenlock: So when you hit up a thread in nrepl and println from it, it won't show? |
| 12:03 | hyPiRion | You could try bound-fn - which will keep the bindings from where you define the function |
| 12:04 | hyPiRion | http://kotka.de/blog/2010/05/Did_you_know_IV.html |
| 12:05 | frozenlock | That'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:05 | frozenlock | "Did you know about bound-fn?" Well, no :p |
| 12:06 | llasram | frozenlock: This doesn't get you quite where you want, but should help verify the issue -- |
| 12:06 | llasram | frozenlock: If you start the nrepl server via `lein nrepl :headless`, then connect to it |
| 12:06 | llasram | Er, `lein repl :headless` |
| 12:06 | frozenlock | Hmm, rather than nrepl-jack-in? |
| 12:06 | llasram | The printed messages should end up on that process's stdout |
| 12:06 | llasram | Yes |
| 12:07 | frozenlock | Let me try that. |
| 12:07 | llasram | From emacs just do `M-x nrepl` |
| 12:07 | llasram | and provide the port the :headless process indicates it is using |
| 12:09 | hyPiRion | But yeah, from a web server, the bound-fn trick is probably hard to use without modifying the router and thread scheduler manually. |
| 12:09 | hyPiRion | I haven't looked at it though, so may be easier than what I anticipate. |
| 12:09 | silasdavis | What's the best way to dispatch in a functin depending on whether I get a single item or a collection? |
| 12:10 | frozenlock | No, nothing showing up. |
| 12:10 | hyPiRion | silasdavis: ##(if (coll? [1 2 3]) :coll :no-coll) |
| 12:10 | lazybot | ⇒ :coll |
| 12:11 | hyPiRion | If it's only a yes/no thing then that's the simplest to process for us humans. |
| 12:11 | hyPiRion | frozenlock: what are you using? compojure? |
| 12:11 | frozenlock | silasdavis: you might want to look `seq?' |
| 12:12 | frozenlock | hyPiRion: Noir... I'll switch to compojure after this. But it uses compojure in the background IIRC. |
| 12:13 | llasram | frozenlock: Huh. Nothing showing up on the process stdout? |
| 12:13 | hyPiRion | ,(map (juxt identity seq? coll?) ['(:list) [:vector] {:a :map} #{:set}]) |
| 12:13 | clojurebot | ([(:list) true true] [[:vector] false true] [{:a :map} false true] [#{:set} false true]) |
| 12:14 | hyPiRion | mm. |
| 12:14 | frozenlock | Nothing in eshell (where I started lein repl :headless), nothing in my *nrepl*, nor in *nrepl-connection*. |
| 12:14 | hyPiRion | What a tease. =| |
| 12:17 | frozenlock | hyPiRion: I just discovered pmap with your link, thanks :) |
| 12:17 | mthvedt | in core.clj, calling (concat) returns (lazy-seq nil) |
| 12:17 | mthvedt | why lazy-seq? |
| 12:19 | hyPiRion | I suppose it's because concat says it will lazily merge the lists it receives |
| 12:20 | hyPiRion | ,(map class [() nil (concat)]) |
| 12:20 | clojurebot | (clojure.lang.PersistentList$EmptyList nil clojure.lang.LazySeq) |
| 12:20 | mthvedt | ,(type (concat)) |
| 12:20 | clojurebot | clojure.lang.LazySeq |
| 12:20 | llasram | frozenlock: 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:20 | mthvedt | maybe it's to not break things that always expect a lazy seq |
| 12:20 | hyPiRion | mthvedt: yeah, I suppose it is. |
| 12:21 | ppppaul | i want to do HTTP mocking/DI in clojure... any ideas? |
| 12:21 | llasram | frozenlock: Do you get output with that? |
| 12:21 | technomancy | ppppaul: requests or responses? |
| 12:22 | frozenlock | llasram: yup |
| 12:22 | frozenlock | OMG |
| 12:22 | llasram | Well then. I have absolutely no idea into what limbo your other lines are going |
| 12:22 | frozenlock | stupid stupid stupid stupid stupid stupid stupid |
| 12:23 | frozenlock | When I did what you asked it showed all the received webhooks. Guess I wasn't flushing the lines... |
| 12:23 | ppppaul | response mocking |
| 12:23 | ppppaul | technomancy, |
| 12:24 | technomancy | ppppaul: have you tried using with-redefs on your HTTP client defns? |
| 12:24 | llasram | frozenlock: Oh! I wonder if running under eshell is affecting flushing behavior |
| 12:24 | ppppaul | technomancy, i haven't tried anything yet cept doing some google searching on http mocking with clojure |
| 12:24 | hyPiRion | llasram frozenlock, yeah, eshell != terminal when it comes to flushing |
| 12:24 | hyPiRion | at least with java |
| 12:25 | llasram | Ah, probably not providing it with a pty |
| 12:25 | frozenlock | Wow, thanks so much guys! It's aliiive! |
| 12:25 | technomancy | eshell doesn't affect flushing |
| 12:25 | technomancy | unless your java code is checking for TERM=dumb and special-casing it or something |
| 12:25 | frozenlock | I think my mistake was to use print instead of println |
| 12:26 | llasram | Oh! Well there we go then |
| 12:26 | llasram | Hmm. So: should nrepl servers alter-root-var to make make the root binding of *out* be the REPL output buffer? |
| 12:28 | technomancy | I added that to swank |
| 12:28 | ppppaul | technomancy, with-redef looks cool |
| 12:28 | technomancy | ppppaul: 90% of the time people ask mocking questions, the answer is with-redefs |
| 12:29 | technomancy | a common pattern is to close over an atom and redef the function in question to #(swap! received-atom conj %&) |
| 12:29 | technomancy | then once the code in question is run, the atom contains all the args the function has been called with |
| 12:30 | ppppaul | interesting |
| 12:30 | ppppaul | i haven't used atoms yet |
| 12:30 | technomancy | most people go wandering off looking for a "mocking framework" when everything they need is staring them right in the face |
| 12:30 | ppppaul | haven't used swap either |
| 12:30 | technomancy | they go hand in hand |
| 12:30 | ppppaul | can i only redef vars that i can see? |
| 12:31 | ppppaul | can i redef a var in a lib that isn't exposed? |
| 12:31 | technomancy | try it and see |
| 12:31 | ppppaul | ok |
| 12:31 | ppppaul | :) |
| 12:31 | ppppaul | have you heard of midje? |
| 12:32 | technomancy | yes |
| 12:33 | ppppaul | thoughts? |
| 12:34 | technomancy | I don't think it offers much advantage over clojure.test |
| 12:35 | bpr | ppppaul: 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:36 | llasram | ppppaul: 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:36 | technomancy | urgh; does it really have side-effects at load time? |
| 12:36 | ppppaul | hmmm interesting |
| 12:37 | ppppaul | lol |
| 12:37 | hyPiRion | I suppose it's good for TDD |
| 12:38 | ppppaul | technomancy, can you comment on weather this is a good example of using with-redefs to mock? https://gist.github.com/4354264 |
| 12:38 | hyPiRion | But I'm usually testing to check that the design of the library I design is okay |
| 12:38 | hyPiRion | It's good to find code smells. |
| 12:39 | technomancy | ppppaul: with-redefs-fn is lower-level; use with-redefs instead |
| 12:39 | technomancy | ppppaul: 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:39 | ppppaul | the only examples i have are at http://clojuredocs.org/clojure_core/clojure.core/with-redefs those any good? |
| 12:40 | technomancy | yeah that looks reasonable |
| 12:40 | ppppaul | ^_^ |
| 12:41 | ghadishayban | try this in your repl: (def ^{:foo (println "HA")} bar 42) |
| 12:41 | ppppaul | ##(def ^{:foo (println "HA")} bar 42) |
| 12:41 | lazybot | java.lang.SecurityException: You tripped the alarm! def is bad! |
| 12:42 | TimMc | Interesting. |
| 12:42 | TimMc | So, we've seen metadata get eval'd 0, 1, and 2 times. |
| 12:42 | ghadishayban | I just fixed it on CLJ-1137 |
| 12:42 | ghadishayban | yeah |
| 12:42 | ghadishayban | interesting follow up to last night |
| 12:43 | DaReaper5 | How do i check {"derp" true} for the existence of the key "herp" |
| 12:43 | TimMc | DaReaper5: contains? |
| 12:43 | DaReaper5 | contains? is throwing null pointer error |
| 12:44 | DaReaper5 | hmm this might be stupid but if i have nothing set for the else for an "if" that should nto cause an issue |
| 12:44 | TimMc | ,(contains? {:a 5} :a) |
| 12:44 | clojurebot | true |
| 12:44 | ghadishayban | ##(let [^{unresolved mysteries} foo 42] foo) |
| 12:44 | lazybot | ⇒ 42 |
| 12:45 | TimMc | DaReaper5: (if x y) is the same as (if x y nil) (or (when x y)) |
| 12:45 | ghadishayban | ##(let [^{:key (throw (Exception. "hurt me"))} foo 42] foo) |
| 12:45 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: foo in this context |
| 12:45 | ghadishayban | oh strange |
| 12:45 | technomancy | ghadishayban: clojure doesn't treat non-breaking spaces right IIRC |
| 12:45 | technomancy | " foo" |
| 12:45 | technomancy | I opened a bug for it and it was wontfix'd |
| 12:46 | TimMc | ,(let [^{:key (throw (Exception. "hurt me"))} foo 42] foo) |
| 12:46 | clojurebot | 42 |
| 12:46 | TimMc | technomancy: That's rather infuriating. |
| 12:46 | DaReaper5 | http://pastebin.com/m1zdctfM |
| 12:47 | DaReaper5 | there is a snipit of my code |
| 12:47 | DaReaper5 | (simplified kinda) |
| 12:47 | TimMc | clojurebot: nbsp is http://www.trygve.com/doomsday.html |
| 12:47 | clojurebot | c'est bon! |
| 12:47 | technomancy | TimMc: 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:47 | TimMc | Oh yeah, I think I remember that. Horrifying. |
| 12:48 | DaReaper5 | TimMc (contains? {"derp" true} "display") is causing my error |
| 12:48 | DaReaper5 | :/ |
| 12:48 | TimMc | ,(contains? {"derp" true} "display") |
| 12:48 | clojurebot | false |
| 12:48 | TimMc | Not by itself it isn't. |
| 12:49 | TimMc | ,(-> foo quote name count) |
| 12:49 | clojurebot | 4 |
| 12:49 | DaReaper5 | http://pastebin.com/3EjtEZ8n |
| 12:50 | DaReaper5 | hmm i might have an idea |
| 12:50 | DaReaper5 | if false then does the if return null |
| 12:50 | hyPiRion | Yeah, those spaces man |
| 12:50 | hyPiRion | ,(let [a 10, a 9] {a 1, a 2}) |
| 12:50 | clojurebot | {10 1, 9 2} |
| 12:50 | xeqi | any recommendations on a full text search library? |
| 12:50 | TimMc | hyPiRion: AAAAGGGHHH |
| 12:51 | hyPiRion | TimMc: ? |
| 12:51 | TimMc | DaReaper5: Check my message of 6 minutes ago. |
| 12:51 | DaReaper5 | TimMc i have only been here for like 3 min |
| 12:51 | DaReaper5 | i see now |
| 12:52 | DaReaper5 | dam |
| 12:52 | TimMc | hyPiRion: Somehow that was even more visually terrifying than the example I posted. |
| 12:52 | hyPiRion | I 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:53 | technomancy | http://dev.clojure.org/jira/browse/CLJ-419 |
| 12:53 | DaReaper5 | TimMc is there a way i can specify the if on else to do absolutly nothing? |
| 12:53 | DaReaper5 | not even pass null? |
| 12:53 | TimMc | hüÖíËíóñ° Í há®é ñó íðéá åháþ üóú´ëé þáøœíñg ábóúþ. °¥ |
| 12:53 | technomancy | xeqi: other than lucene you mean? |
| 12:53 | DaReaper5 | i think the null being passed is fucking up my parent method |
| 12:53 | DaReaper5 | ... which is actually just a sql query builder |
| 12:54 | TimMc | DaReaper5: It's an expression, just like (almost?) everything in Clojure. It has a return value. What shall the return value be? |
| 12:54 | xeqi | technomancy: as in I know very little about fts other then lucene,solr,and such exists |
| 12:54 | xeqi | and easy ways to use it from clojure / score things |
| 12:55 | TimMc | hyPiRion: ^ my keyboard is set up with an AltGr as well. |
| 12:55 | jkkramer | xeqi: I think elasticsearch or solr are the go-to solutions these days |
| 12:55 | jkkramer | xeqi: there's an elasticsearch clojure lib |
| 12:55 | technomancy | xeqi: lucene is pretty much the gold standard in the industry for full-text search |
| 12:55 | hyPiRion | TimMc: ←↓→ :D |
| 12:56 | technomancy | solr and elasticsearch are just ways of making lucene indices that span multiple machines |
| 12:56 | technomancy | "just" |
| 12:56 | hyPiRion | It's handy for those times i need a µ or a π without going to a character map |
| 12:56 | TimMc | Hmm, AltGr + space doesn't give me U+00A0. |
| 12:56 | hyPiRion | Which is possibly once a year. |
| 12:56 | hyPiRion | TimMc: lucky bastard |
| 12:57 | technomancy | M-x ucs-insert |
| 13:10 | hyPiRion | I 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:10 | technomancy | I bet useful has something |
| 13:11 | hyPiRion | Right, 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:11 | hyPiRion | Oh well |
| 13:13 | ppppaul | technomancy, 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:18 | technomancy | ppppaul: 1.7 is pretty outdated. who is it that's stuck on it? |
| 13:19 | DaReaper5 | TimMc ok i know exatly my issue right now, a third party library i am using cannot except nil. |
| 13:20 | DaReaper5 | I am trying to check a value and if it exists then i indicate a field to be used in a query |
| 13:20 | DaReaper5 | either i need a way of check and doing absolutly nothing if it does not exist |
| 13:20 | DaReaper5 | or i need a way of building an array |
| 13:21 | DaReaper5 | but i cant do that because data structure are immutable |
| 13:21 | DaReaper5 | Here is what i want to do in plain english: "If field exists, include/use field name" |
| 13:27 | ppppaul | technomancy, vmfarms. they aren't used to clojure |
| 13:28 | ppppaul | they think that 1.7 is the latest stable branch |
| 13:30 | technomancy | ppppaul: that's a technicality. if it helps you can send them to https://github.com/technomancy/leiningen/commit/14f566bd5738cba44e692131fb81cdfbc67f28b2#L1R83 |
| 13:32 | technomancy | or you can tell them I said they're wrong =) |
| 13:33 | technomancy | also relevant is that the only mention of 1.x on leiningen.org is a link titled "Still using 1.x?" |
| 13:35 | ppppaul | thanks a lot :) |
| 13:48 | bpr | technomancy: i'm glad you mentioned the "useful" library earlier. I'd never heard of it, and it contains some really cool stuff. |
| 13:52 | technomancy | yeah lots of good stuff in there |
| 13:53 | technomancy | amalloy_: are there docs for it? |
| 13:57 | hyPiRion | It's hard to dig through to try and find the fns you need |
| 13:57 | hyPiRion | Or well, it's not apparent |
| 14:09 | unlink | Is there a function/macro which is like: (fn [x & rest] x) i.e. that discards all arguments but the first (for side effects) |
| 14:12 | llasram | unlink: Oh, like Scheme/CL `prog1`? AFAIK there isn't one in the Clojure standard library, no |
| 14:13 | llasram | wtf, CL has `prog2`? When would you ever want that? |
| 14:15 | daimrod | llasram: retro-compatibility with older lisp dialects I guess. |
| 14:17 | technomancy | unlink: comp first list maybe? |
| 14:18 | technomancy | unlink: if you want a macro try doto |
| 14:20 | unlink | yeah, prog1 is what I want, not doto. |
| 14:20 | unlink | thanks. |
| 14:24 | technomancy | huh; apache's sshd is still maintained |
| 14:24 | technomancy | though its web page has no CSS applied |
| 14:26 | mehwork | anyone 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:26 | mehwork | in a repl i clearly can convert a long to a string |
| 14:26 | mehwork | ,(str 1) |
| 14:26 | clojurebot | "1" |
| 14:27 | amalloy | technomancy, 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:28 | technomancy | amalloy: ns-level docstrings? |
| 14:29 | amalloy | (ns ^{:doc "Functions for working with maps"} useful.map)? |
| 14:29 | amalloy | anyway, 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:29 | technomancy | at least use proper docstring syntax =) |
| 14:30 | llasram | mehwork: That's not the same thing. ##(symbol (str 1)) |
| 14:30 | lazybot | ⇒ 1 |
| 14:30 | llasram | mehwork: That's not the same thing. ##(symbol 1) |
| 14:30 | lazybot | java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String |
| 14:30 | llasram | Er, didn't mean to repeat "not the same thing" twice |
| 14:30 | llasram | But you get the idea |
| 14:31 | llasram | mehwork: Something which ultimately calls a java method expecting a particular type will throw a ClassCastException when getting the wrong type |
| 14:31 | hammer | this has to be so easy: how do i re-run my last statement in counterclockwise? |
| 14:32 | hammer | (yes, i tried hitting up arrow) |
| 14:33 | TimMc | hammer: Hmm, try ctrl-up? |
| 14:33 | TimMc | Or C-p I guess. |
| 14:33 | hammer | haha |
| 14:33 | mehwork | llasram: interesting |
| 14:33 | hammer | the ctrl -> command switch is still getting me |
| 14:33 | jlr | I'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:33 | hammer | (inc TimMc) |
| 14:33 | lazybot | ⇒ 28 |
| 14:33 | TimMc | hammer: Was C-up? |
| 14:33 | hammer | ctrl + up worked |
| 14:34 | technomancy | jlr: you would have to choose between seamless interop with existing elisp mutable types and having a proper equality predicate |
| 14:34 | technomancy | the two are mutually exclusive |
| 14:34 | TimMc | technomancy: No 2.x release yet? |
| 14:34 | jlr | ah, that's unfortunate |
| 14:34 | technomancy | jlr: I blogged more about it here: http://technomancy.us/159 |
| 14:34 | jlr | obviously everyone would love a Clojure based Emacs |
| 14:35 | jlr | thank you for the link, I will certainly read it |
| 14:35 | technomancy | TimMc: no, library maintainers aren't pushing their libs to the clojars releases repo |
| 14:35 | technomancy | slackers |
| 14:35 | jlr | Of course you and the other Relevance people have contemplated it already ;) |
| 14:35 | TimMc | technomancy: How does that block lein 2.x? |
| 14:35 | technomancy | I'm not a relevance guy |
| 14:35 | brainproxy | jlr: have you seen the deuce project? |
| 14:35 | jlr | oh, I thought you were |
| 14:36 | technomancy | nah I work for Heroku |
| 14:36 | TimMc | jlr: They *should* pay him. |
| 14:36 | jlr | I know who you are. Just assumed since you're one of the fundamental members of the community, you were part of relevance *laughs* |
| 14:36 | jlr | I would certainly agree. For lein and many many other contributions. |
| 14:36 | jlr | (TimMc) |
| 14:37 | technomancy | jlr: I don't actually work on Clojure itself |
| 14:37 | jlr | brainproxy: no, I'll google it. |
| 14:37 | jlr | I consider your contributions to its ecosystem very much fundamental :) But not Clojure itself eh? Interesting. Well your tools are great. |
| 14:37 | technomancy | TimMc: everything will break if people start dropping the clojars snapshots repo before the releases repo is populated |
| 14:37 | brainproxy | jlr: https://github.com/hraberg/deuce |
| 14:38 | brainproxy | "emacs under clojure" |
| 14:38 | TimMc | technomancy: Hmm, not familiar with this. |
| 14:39 | technomancy | IMO 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:39 | jlr | Ah 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:39 | technomancy | jlr: some people think it's possible and are trying to do it with Guile (which does have immutability) |
| 14:39 | jlr | (brainproxy. sorry - will address nicks properly. It's early) |
| 14:40 | jlr | Well, 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:40 | technomancy | that 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:41 | jlr | It'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:41 | brainproxy | technomancy: 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:41 | TimMc | technomancy: Found it: https://groups.google.com/forum/?fromgroups=#!topic/clojars-maintainers/d8HNd-R4uw8 |
| 14:41 | technomancy | jlr: people have tried to hoist it onto the CL runtime several times and they never got anywhere |
| 14:41 | jlr | I 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:42 | jlr | technomancy: I've read about those efforts. It's a tough thing for sure, people keep taking stabs at it and not succeeding |
| 14:42 | technomancy | a clj->elisp compiler would be much less work, but you'd have to add immutable lists and strings to the Emacs runtime first |
| 14:43 | technomancy | immutable strings in emacs are not completely out of the question according to the maintainers. |
| 14:43 | technomancy | I've asked them about it and apparently it wouldn't break much |
| 14:43 | technomancy | immutable lists are way harder |
| 14:43 | technomancy | plus elisp doesn't really have the means of abstraction to do a proper self-hosted thing |
| 14:43 | frozenlock | technomancy: any chance to see immutable strings in the next.. 2 years? |
| 14:43 | jlr | As 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:44 | technomancy | frozenlock: 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:44 | jlr | Hire a few of the best, maybe even try to get Relevance and Rich himself to consult some |
| 14:45 | technomancy | it's a lot of work for little benefit; without immutable lists it's not really that valuable |
| 14:45 | technomancy | jlr: there was a summer of code proposal for that, but it wasn't accepted |
| 14:45 | jlr | wow, that's sort of a tragedy.. |
| 14:46 | technomancy | I don't think it's a good idea |
| 14:46 | jlr | I still think given what we saw with Light Table it's not out of the question to kickstart it |
| 14:46 | jlr | really? |
| 14:46 | technomancy | you're never going to come close to competing with emacs for breadth of available libraries |
| 14:47 | frozenlock | Without counting everyone's personal code... |
| 14:47 | technomancy | who's going to port magit, org-mode, gnus, etc? |
| 14:47 | technomancy | gnus itself is larger than any public OSS clojure project in existence |
| 14:47 | jlr | I 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:47 | technomancy | and that's just a tiny slice of what's out there |
| 14:47 | jlr | Oh my gosh, they're that big, I see |
| 14:48 | ohpauleez | and it's going to introduce another barrier for adopting Clojure- "I have to learn this new editor if I want the best support?" |
| 14:48 | jlr | I 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:48 | jlr | Ah, good point as well |
| 14:48 | ohpauleez | Nonethelss, writing an editor is a great learning experience |
| 14:48 | ohpauleez | so if you're interested, totally go for it! |
| 14:48 | technomancy | it's an inconceivably huge amount of effort for a tiny community like clojure |
| 14:49 | jlr | I lack anything resembling the technical skill to succeed at writing a new Emacs ;) |
| 14:49 | jlr | I see. Well, perhaps some day. |
| 14:49 | technomancy | writing just an editor of course is feasible |
| 14:49 | jlr | Thanks for all that |
| 14:49 | technomancy | but you're talking about an entire OS |
| 14:50 | jlr | Exactly - an entire OS is precisely what I want, in Clojure. Heh. Yes, that is getting ahead of ourselves by a few years... |
| 14:57 | Netfeed | what's the best way to convert something like f(x) = x + x to something like (defn f [x] (+ x x))? |
| 14:58 | frozenlock | Netfeed: if it's for math/analytics stuff, incanter allows you to use infix notation |
| 14:59 | Netfeed | nono, parsing text |
| 14:59 | dnolen | Netfeed: write a parser? |
| 14:59 | dnolen | Netfeed: or use an existing Clojure parser - there are a few |
| 15:00 | Netfeed | alright |
| 15:00 | frozenlock | Big move... from Noir to compojure. Any advices/tutorials? |
| 15:01 | technomancy | frozenlock: did you see the refheap port raynes posted? |
| 15:01 | frozenlock | Looking at it now in fact. |
| 15:05 | bosie | does anyone have a lib/idea how to detect binary files? |
| 15:05 | bosie | or rather: a tool detecting html files? |
| 15:05 | frozenlock | *.html :-) |
| 15:06 | bosie | frozenlock: i don't have the filename ;) |
| 15:06 | amalloy | bosie: just use the unix `file` command |
| 15:07 | bosie | amalloy: that seems a bit counterproductive, no? |
| 15:07 | bosie | amalloy: in the sense you can't run it on windows anymore |
| 15:07 | bpr | i'd call that productive lol |
| 15:08 | bosie | haha |
| 15:09 | TimMc | There's always Apache Tika, I guess. |
| 15:09 | TimMc | I think it uses the same database as file. |
| 15:10 | bosie | hm |
| 15:13 | TimMc | echo "MOVIE REVIEWS" | file - ## /dev/stdin: Silicon Graphics movie file |
| 15:13 | lazybot | "MOVIE REVIEWS" | file - ## /dev/stdin: Silicon Graphics movie file |
| 15:13 | TimMc | Good times. |
| 15:15 | TimMc | Except some bloopers. |
| 15:15 | TimMc | *Expect |
| 15:18 | amalloy | for 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:18 | tgoossens | i 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:20 | llasram | tgoossens: Over what are you looping infinitely? |
| 15:20 | AimHere | ,(loop [] (recur)) |
| 15:20 | clojurebot | Execution Timed Out |
| 15:21 | tgoossens | it is still an unfinished function : https://gist.github.com/4355451 |
| 15:21 | tgoossens | experimenting |
| 15:22 | llasram | tgoossens: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html |
| 15:23 | frozenlock | tgoossens: at-at from overtone https://github.com/overtone/at-at |
| 15:23 | tgoossens | interesting |
| 15:24 | tgoossens | damnit! you/myself caught me again. On the fact that I did not search for existing solutions for that "rate" stuff |
| 15:24 | tgoossens | at at looks cool |
| 15:24 | llasram | frozenlock: Oh, nice. I like the REPL-friendly aspect |
| 15:26 | tgoossens | i should really train myself to sometimes stop, look at what i want to do, and search for similar / same problems and solutions |
| 15:26 | frozenlock | 20s on IRC can save weeks of development |
| 15:26 | tgoossens | yes |
| 15:26 | tgoossens | funny though |
| 15:27 | tgoossens | today a book arrived that i ordered |
| 15:27 | tgoossens | "how to solve it" |
| 15:27 | tgoossens | polya |
| 15:28 | bbloom | tgoossens: that top level loop isn't required |
| 15:28 | tgoossens | it addresses exactly the thing i just experienced |
| 15:28 | bbloom | functions are themselves loop targets |
| 15:29 | bbloom | ,(fn [] (recur)) |
| 15:29 | clojurebot | #<sandbox$eval53$fn__54 sandbox$eval53$fn__54@58ab3daf> |
| 15:29 | tgoossens | bbloom: can you recur on that? |
| 15:29 | bbloom | ,((fn [] (recur))) |
| 15:29 | tgoossens | ah yes |
| 15:29 | clojurebot | Execution Timed Out |
| 15:29 | tgoossens | i see what you mean |
| 15:30 | bbloom | also, when-not's body is an implicit do, so you don't need the do either |
| 15:30 | bbloom | (doc when-not) |
| 15:30 | clojurebot | "([test & body]); Evaluates test. If logical false, evaluates body in an implicit do." |
| 15:30 | tgoossens | wow |
| 15:30 | bbloom | that's the whole point of when vs if |
| 15:30 | tgoossens | ,(doc when) |
| 15:30 | clojurebot | "([test & body]); Evaluates test. If logical true, evaluates body in an implicit do." |
| 15:31 | tgoossens | mmyes |
| 15:31 | tgoossens | lol |
| 15:31 | tgoossens | this is getting embarrassing :p |
| 15:31 | bbloom | other than that: there's nothing wrong with an infinite loop for a simulation |
| 15:31 | bbloom | that's how simulations work! |
| 15:31 | bbloom | and tail recursion is the clojure way of looping |
| 15:34 | nDuff | ...well, _one_ clojure way of looping. :) |
| 15:34 | nDuff | There's also iterating over infinite lazy sequences. |
| 15:34 | nDuff | ...which I'd argue is actually more clojure-y |
| 15:36 | tgoossens | bbloom: btw this is the context (namespace) where that function is |
| 15:36 | tgoossens | https://github.com/tgoossens/robotclj/blob/master/src/robotclj/virtual.clj |
| 15:37 | tgoossens | its a first experiment. i'm still far from sure how i want to create the simulator |
| 15:37 | tgoossens | just playing aroud |
| 15:37 | tgoossens | *around |
| 15:37 | bbloom | tgoossens: nitpick: most clojure code uses 2-space indents instead of tabs |
| 15:37 | tgoossens | blloom: i know. But for some reason when i push it to git. it is screwed up |
| 15:38 | bbloom | ....what? that seems unlikely heh |
| 15:38 | tgoossens | in my sublimetext editor it looks fine |
| 15:38 | tgoossens | (2 spaces) |
| 15:39 | bbloom | tgoossens: (fn [simulator] false) -> (constantly false) |
| 15:40 | bbloom | why does your multimethod return functions? |
| 15:40 | bbloom | why not take the simulator atom as an argument? you can dispatch on the :type of the second argument |
| 15:41 | bbloom | er rather take the simulator *value* as an argument |
| 15:41 | bbloom | and return the new value |
| 15:41 | tgoossens | bbloom: 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:42 | mpan | would it be a good/bad idea to use zippers for an implicit search tree that isn't actually modifiable? |
| 15:42 | bbloom | why didn't a hash-map suffice? |
| 15:42 | tgoossens | a command is {:type ::drive :other keys} |
| 15:42 | bbloom | ah. |
| 15:42 | tgoossens | i needed a function based on the type |
| 15:43 | bbloom | i have a thing for this :-) https://github.com/brandonbloom/dispatch-map |
| 15:43 | tgoossens | ah. yes. i remember reading that on planet clojure |
| 15:43 | bbloom | but in reality, a multimethod is probably fine for what you need |
| 15:43 | tgoossens | i think i commented on the blogpost asking whether you don't lose "exentability" |
| 15:43 | tgoossens | *extendability |
| 15:44 | bbloom | ah |
| 15:44 | tgoossens | was that you? |
| 15:44 | bbloom | that's me |
| 15:44 | tgoossens | aight :) |
| 15:44 | tgoossens | cool |
| 15:45 | bbloom | i'm just not sure why your multimethod has 3 levels of indirection: the method, the (fn [simulator] ...) and then the :*-fn |
| 15:45 | bbloom | seems like you could collapse those all down |
| 15:46 | tgoossens | hmmm 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:47 | bbloom | i see |
| 15:47 | tgoossens | i'll be back in a minute. then i'll explain my intends with the simulator abit |
| 15:49 | ppppaul | is it possible for me to call private functions? |
| 15:50 | bbloom | ppppaul: private vars are callable: (#'the-ns/private-fn 1 2 3) |
| 15:50 | ppppaul | cool |
| 15:50 | ynniv | I 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:51 | amalloy | $google lein dependency xclusions |
| 15:51 | lazybot | [technomancy/leiningen · GitHub] https://github.com/technomancy/leiningen |
| 15:51 | amalloy | well, typo. anyway, check the sample project.clj for exclusions |
| 15:51 | TimMc | amalloy: I hadn't considered before either. I just wanted a really short example, and "-" *usually* works with GNU utils... |
| 15:52 | amalloy | well, usually - is optional |
| 15:52 | TimMc | In this case it is required, apparently. |
| 15:53 | ynniv | amalloy: is that a reply to me? I'm already excluding deps, but korma statically loads things that I don't want |
| 15:53 | amalloy | you're out of luck, then |
| 15:53 | TimMc | - appears to be an undocumented option to file. |
| 15:54 | tgoossens | bbloom: ok https://github.com/tgoossens/robotclj/blob/master/src/robotclj/core.clj |
| 15:54 | tgoossens | this will be the "dispatching" part |
| 15:54 | tgoossens | i need to send commands like, drive, turn, explore maze, to either a virtual robot or a remote (bluetooth) nxt robot |
| 15:55 | tgoossens | so for the simulator case, it will have to create commands and send it to the simulator |
| 15:56 | tgoossens | i'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:56 | tgoossens | in the simulator there is a key ":command" that contains the command (to be) being executed in the simulator |
| 15:58 | tgoossens | the simulator must start executing the command as long as the stopcondition returns false. |
| 15:58 | tgoossens | Or it should start executing another command if it gets swapped |
| 15:59 | tgoossens | bbloom: thats the general idea |
| 16:00 | mehwork | how 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:00 | dnolen | mehwork: apply |
| 16:00 | dnolen | (apply f some-list) |
| 16:00 | mehwork | although, if [& args] puts them back in a list i don't know why i can't just pass it as a list |
| 16:00 | mehwork | thanks i'll try it |
| 16:01 | dnolen | ,(str "a" "b" "c") |
| 16:01 | AimHere | Well how would the function know that you wanted to pass a list of arguments, rather than a list as your first argument? |
| 16:01 | ynniv | yeah, annoying to work around what seems to be unnecessary destructuring |
| 16:01 | clojurebot | "abc" |
| 16:01 | dnolen | ,(apply str (list "a" "b" "c")) |
| 16:01 | clojurebot | "abc" |
| 16:02 | mehwork | i don't want them to become a single string |
| 16:02 | dnolen | mehwork: I know, it's just an example |
| 16:03 | mehwork | i think the prob is that "a" "b" "c" is a concatentation on a string, so it's the same as saying "abc" |
| 16:03 | TimMc | mehwork: It's not. |
| 16:04 | mehwork | there needs to be the opposite where it splits "abc" to "a" "b" "c" |
| 16:04 | mehwork | oh you're right nm |
| 16:04 | mehwork | i guess that's only if you print it |
| 16:04 | mehwork | er |
| 16:04 | mehwork | what the heck it was just happening, now it's not :/ |
| 16:05 | seangrove | ,(type (str "a "b "c)) |
| 16:05 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading string> |
| 16:05 | mehwork | oh that does a b c |
| 16:05 | seangrove | ,(type (str "a "b "c")) |
| 16:05 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: b in this context, compiling:(NO_SOURCE_PATH:0)> |
| 16:05 | seangrove | hah |
| 16:05 | seangrove | ,(type (str "a" "b" "c")) |
| 16:05 | clojurebot | java.lang.String |
| 16:06 | TimMc | ,(str) |
| 16:06 | clojurebot | "" |
| 16:14 | mehwork | is there a way to convert a sequence ["a","b","c"] to just "a" "b" "c"? |
| 16:15 | technomancy | mehwork: that question doesn't really make sense |
| 16:16 | mehwork | technomancy: well i want to pass a variable list of arguments dynamically |
| 16:16 | bbloom | (doc apply) |
| 16:16 | clojurebot | "([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:16 | technomancy | oh, during function application specifically? |
| 16:16 | technomancy | yeah, that |
| 16:16 | mehwork | ok i guess i need to play with apply more, i couldn't get it to work yet |
| 16:17 | technomancy | ,(apply str "a" "b" ["c" "d" "f"]) |
| 16:17 | clojurebot | "abcdf" |
| 16:18 | mehwork | yeah 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:18 | mehwork | 3 sep args, not 1 |
| 16:19 | technomancy | apply only does its magic on the last argument |
| 16:19 | seangrove | Almost ready for our new release - 99% clojurescript: http://dl.dropbox.com/u/412963/zenbox/zenbox_preview_jan.mov |
| 16:19 | bbloom | ,(apply str (concat '("a" "b" "c") [1 2 3])) |
| 16:19 | clojurebot | "abc123" |
| 16:20 | seangrove | Just a tiny bit of glue javascript here and there, but overall extremely happy with clojurescript for production apps |
| 16:20 | mehwork | i feel stupid because i'm just not getting what you're saying :[ |
| 16:20 | bbloom | mehwork: read the doc string for apply again |
| 16:21 | amalloy | bbloom: the docstring for apply is not instructive at all |
| 16:21 | bbloom | then consider this function (fn [& args] (count args)) |
| 16:21 | bbloom | ((fn [& args] (count args)) 1 2 3) |
| 16:21 | bbloom | ((fn [& args] (count args)) 1 2 3), |
| 16:21 | bbloom | dammit: |
| 16:21 | seangrove | hah |
| 16:21 | bbloom | ,((fn [& args] (count args)) 1 2 3) |
| 16:21 | clojurebot | 3 |
| 16:21 | bbloom | ,(apply (fn [& args] (count args)) 1 2 [3]) |
| 16:21 | clojurebot | 3 |
| 16:21 | bbloom | ,(apply (fn [& args] (count args)) 1 2 [3 4 5]) |
| 16:21 | clojurebot | 5 |
| 16:21 | bbloom | ,(apply (fn [& args] (count args)) 1 2 [3 4 5] 6) |
| 16:21 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 16:21 | bbloom | ,(apply (fn [& args] (count args)) [1 2] [3 4 5]) |
| 16:21 | clojurebot | 4 |
| 16:21 | dnolen | mehwork: apply does what you want - give us an example (paste) where it's not working for you. |
| 16:22 | bbloom | does it make sense now? |
| 16:22 | mehwork | no but i'm playing with it in a repl till it does |
| 16:23 | bbloom | better yet: (fn [& args] args) |
| 16:23 | hyPiRion | when apply is given more than one arg, all but the latter is considered as singletons |
| 16:23 | bbloom | ,((fn [& args] args) 1 2 [3 4 5]) |
| 16:23 | clojurebot | (1 2 [3 4 5]) |
| 16:23 | bbloom | ,(apply (fn [& args] args) 1 2 [3 4 5]) |
| 16:23 | clojurebot | (1 2 3 4 5) |
| 16:23 | bbloom | ,(apply (fn [& args] args) [1 2] [3 4 5]) |
| 16:23 | clojurebot | ([1 2] 3 4 5) |
| 16:23 | bbloom | seangrove: neat. some kind of CRM tool? |
| 16:23 | mehwork | o wait |
| 16:24 | seangrove | bbloom: Kind of a meta-crm tool, yeah |
| 16:24 | bbloom | read |
| 16:24 | bbloom | er wrong window |
| 16:25 | seangrove | It 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:25 | bbloom | seangrove: sounds interesting |
| 16:26 | bbloom | gonna write up a cljs success story? :-) |
| 16:26 | mehwork | does apply not work on normal lists? |
| 16:26 | dnolen | mehwork: it does |
| 16:27 | seangrove | bbloom: 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:27 | seangrove | Both are reasonably interesting in hindsight |
| 16:28 | bbloom | seangrove: looking forward to them |
| 16:28 | mehwork | ,(apply (fn [& args] (count args)) ("a" "b" "c")) |
| 16:28 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn> |
| 16:29 | mehwork | ,(apply (fn [& args] (count args)) '("a" "b" "c")) |
| 16:29 | clojurebot | 3 |
| 16:29 | mehwork | ahhh now i get it |
| 16:31 | dnolen | mehwork: though that issue really has nothing to do w/ apply |
| 16:32 | dnolen | ,("a" "b" "c") |
| 16:32 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn> |
| 16:32 | jro_ | do yo write unit tests in your clojure development? or quickcheck style testing? |
| 16:33 | mehwork | jro_: what's quickcheck style? |
| 16:33 | ppppaul | when i set my :test-paths ["test"] in project.clj i get an error-> lein test |
| 16:33 | ppppaul | Error loading project.clj |
| 16:33 | mehwork | like manually running it to see if it seems to be working? |
| 16:34 | ppppaul | anyone able to point me to a url that'll help me get 'lein test' working on my project? |
| 16:34 | jro_ | combinatorial testing, like Haskell's QuickCheck. ClojureCheck seems to be similar |
| 16:34 | technomancy | ppppaul: :test-paths defaults to ["test"]; no need to add it |
| 16:35 | technomancy | weird that you're getting an error though; works here |
| 16:35 | dnolen | jro_: there's also the test.generative contrib library |
| 16:35 | ppppaul | when 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:35 | technomancy | jro_: most people just use regular clojure.test by a fairly wide majority |
| 16:40 | tgoossens | bbloom: your dispatch-map works great |
| 16:41 | ppppaul | when testing clojure do i have to call all my tests from core_test.clj? |
| 16:41 | bbloom | tgoossens: nice! :-) |
| 16:41 | tgoossens | still figuring out how to pass use the other fields of the command |
| 16:41 | tgoossens | (like my multimethod) |
| 16:41 | technomancy | ppppaul: you can scatter deftest forms all over your test/ directory as you like |
| 16:41 | technomancy | ppppaul: maybe it'd be helpful to look at an existing project as an example |
| 16:43 | tgoossens | bbloom is it even possible? |
| 16:43 | ppppaul | that could be helpful |
| 16:43 | bbloom | tgoossens: is that possible? |
| 16:43 | ppppaul | i have tests all over my test dir, but i haven't used lein test until now and it's failing bad |
| 16:44 | bbloom | tgoossens: s/that/what/ |
| 16:44 | tgoossens | bbloom: ? :p |
| 16:44 | bbloom | explain your question please |
| 16:44 | tgoossens | ah ok |
| 16:44 | hiredman | is there a write up of the core.logic deffact stuff? |
| 16:45 | hiredman | defrel |
| 16:45 | tgoossens | bbloom: the dispatch-map dispatches by applying a function to the given inputvalue. In my multimethods i can still use that inputvalue. |
| 16:46 | jro_ | lein2 run swallows my stdout |
| 16:46 | tgoossens | (defmethod command-map ::drive [command] (:blablab command)) |
| 16:47 | bbloom | oh, no that wouldn't make any sense for dispatch-map b/c the values in a dispatch map aren't necessarily functions |
| 16:47 | tgoossens | exactly |
| 16:47 | dnolen | hiredman: not really, do you have a specific question? I will say it's still a bit half-baked |
| 16:47 | tgoossens | so my "point" was that dispatch map is not really useful for what i'm trying to achieve |
| 16:47 | bbloom | (let [value ...] (partial (get (dispatch-map ...) value) value)) |
| 16:48 | bbloom | dispatch map is a building block |
| 16:48 | tgoossens | also possible is that my current design sucks and i should reconsider it |
| 16:48 | bbloom | one thing you can build with it is a multimethod :-P |
| 16:48 | tgoossens | :) |
| 16:48 | tgoossens | i totally get it now (compared to my comment on your blog :p ) |
| 16:49 | dnolen | ooh Nashorn source is out, http://blogs.oracle.com/nashorn/entry/open_for_business |
| 16:49 | tgoossens | g2g thanks and we speak again! |
| 16:49 | bbloom | dnolen: cool |
| 16:51 | hiredman | dnolen: 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:53 | dnolen | hiredman: 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:54 | hiredman | dnolen: 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:55 | francis | Is anyone aware of a clojure tool that removes unused dependancies from namespaces? |
| 16:55 | amalloy | $google lein slamhound |
| 16:55 | lazybot | [slamhound/lein-slamhound at master · technomancy ... - GitHub] https://github.com/technomancy/slamhound/tree/master/lein-slamhound |
| 16:56 | technomancy | francis: disclaimer: doesn't work all that well |
| 16:56 | francis | technomancy & amalloy: tried slamhound earlier, didn't work at all |
| 16:56 | technomancy | in 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:57 | technomancy | however, fixing slamhound would be easier than starting from scartch |
| 16:57 | technomancy | scratch |
| 16:57 | francis | technomancy: I'm considering doing that |
| 16:57 | technomancy | it's pretty well documented |
| 16:57 | francis | It's either that or write my own |
| 16:57 | technomancy | http://technomancy.us/148 |
| 16:58 | francis | groovy, thanks |
| 16:58 | ppppaul | i'm looking at how lein's project testing is set up |
| 16:58 | ppppaul | i find it a bit strange that there is a lein/test/lein/test/ dir structure... |
| 16:59 | technomancy | you mean for leiningen itself? |
| 16:59 | ppppaul | yes |
| 16:59 | technomancy | that might not be the best example; lein has some weird self-hosting things that make it atypical |
| 16:59 | ppppaul | i'm using it as an example of how to set up my project |
| 16:59 | technomancy | maybe clojars? |
| 16:59 | ppppaul | hmm |
| 17:00 | ppppaul | clojars-web / test / clojars / test / |
| 17:00 | ppppaul | seems the same |
| 17:01 | technomancy | ppppaul: the first test/ dir is there to keep test/ separate from src/ |
| 17:01 | technomancy | the second test/ is there because it's part of the namespace name |
| 17:02 | ppppaul | i see |
| 17:02 | ppppaul | i was able to progress after this realization |
| 17:02 | ppppaul | :) |
| 17:09 | jro_ | I've Emerick et al "Programming Clojure", and just ordered "Joy of Clojure". Could you recommend other books complement those? |
| 17:10 | technomancy | those are the best |
| 17:10 | ChongLi | Clojure Programming |
| 17:10 | technomancy | oh wait, yeah thats' what I meant |
| 17:11 | jro_ | yes, that is the Emerick's and others book |
| 17:11 | jro_ | I did like it |
| 17:11 | ChongLi | Programming Clojure is Halloway and Bedra |
| 17:12 | devinus_ | Clojure in Action |
| 17:12 | devinus_ | is in MEAP isnt it? |
| 17:12 | jro_ | my weakness now is to design bigger programs using clojure, maybe the language and its abilities are covered pretty well in these two |
| 17:13 | technomancy | jro_: a book won't help with that, you need to read code |
| 17:13 | ChongLi | I think SICP can help with that |
| 17:14 | jro_ | yeah, now I just no need to code... |
| 17:15 | jro_ | my first cloure app has so far 46,423 hits :-) and number of active user's are increasing all the time ;-) |
| 17:16 | jro_ | I very pleased about the robustness of the infrastructure: lein, compojure+ring, netty bridge |
| 17:22 | dnolen | hmm looks like Nashorn is going to be pretty serious about optimizing JS ... |
| 17:27 | bosie | http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/if-let it says: "If test is true"... what test is this? |
| 17:28 | xeqi | (if-let [.. test] .. ..) |
| 17:30 | bosie | xeqi: right |
| 17:30 | bosie | (if-let [a b]....) |
| 17:30 | bosie | it would only execute the .... if b is a truthy? |
| 17:31 | ucb | bosie: I'd like to think so |
| 17:31 | ucb | ,(doc if-let) |
| 17:31 | clojurebot | "([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:32 | bosie | ucb: i read the docs but couldn't make sense of it ;) |
| 17:32 | ucb | oh |
| 17:32 | xeqi | (if-let [a 5] 1 (throw (Exception.))) |
| 17:32 | bosie | ucb: i also dont get what "bindings => binding-form test" means |
| 17:32 | xeqi | &(if-let [a 5] 1 (throw (Exception.))) |
| 17:32 | lazybot | ⇒ 1 |
| 17:32 | xeqi | that means you can destructure the test result |
| 17:33 | xeqi | (if-let [{:keys [x y z]} {:x 1 :y 2 :z 3}] [x y z]) |
| 17:33 | xeqi | &(if-let [{:keys [x y z]} {:x 1 :y 2 :z 3}] [x y z]) |
| 17:33 | lazybot | ⇒ [1 2 3] |
| 17:33 | bosie | thats interesting xeqi |
| 17:34 | bosie | thanks |
| 17:45 | jballanc_ | is anybody doing sql migrations in Clojure? |
| 17:46 | technomancy | clojurebot: migrations? |
| 17:46 | clojurebot | I don't understand. |
| 17:46 | technomancy | clojurebot: migrate.clj? |
| 17:46 | clojurebot | unquote in project.clj is an escape hatch |
| 17:46 | technomancy | blargh |
| 17:46 | technomancy | jballanc_: here's what I use: https://github.com/heroku/buildkits/blob/master/src/buildkits/db/migrate.clj |
| 17:46 | jballanc_ | cool, thanks! |
| 17:47 | xeqi | for completeness theres https://github.com/budu/lobos and https://github.com/weavejester/ragtime as well |
| 17:47 | technomancy | lobos is really complicated though |
| 17:47 | xeqi | but clojars uses something like what technomancy linked |
| 17:47 | technomancy | and tries to pretend that it's possible to do nontrivial migrations that are portable across databases |
| 17:48 | jballanc_ | so, let's say someone was interested in adding something akin to DataMapper's automigrations to Korma... |
| 17:48 | jballanc_ | anyone know the state of Korma development? |
| 17:48 | technomancy | I would strongly advise against the development of any system which tries to do migrations in a db-agnostic way |
| 17:48 | technomancy | it's not possible to do well |
| 17:48 | jballanc_ | heh...understatement of the year |
| 17:49 | jballanc_ | hmm...ok, I'll think on all these |
| 17:49 | jballanc_ | thanks for the help! |
| 17:49 | dyba | does anyone know how to require a clojure contrib library? |
| 17:49 | xeqi | ~contrib |
| 17:49 | clojurebot | Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go |
| 17:49 | dyba | I've tried (:require clojure.contrib.math) |
| 17:49 | dyba | but that doesn't work |
| 17:50 | TimMc | technomancy: Naw, man, you just wait until I release my ORM that works across all SQL and NoSQL DBs and also between different runtimes. |
| 17:50 | TimMc | YOU JUST WAIT. |
| 17:50 | TimMc | We're pushing back our release date just a bit. 2035. |
| 17:50 | technomancy | dyba: contrib libraries aren't special; you would load them like any other library after adding them to project.clj |
| 17:50 | weavejester | dyba: https://github.com/clojure/math.numeric-tower |
| 17:51 | dyba | xeqi: thanks! I'll read up on that |
| 17:51 | weavejester | dyba: Add [org.clojure/math.numeric-tower "0.0.2"] to your project.clj deps |
| 17:51 | weavejester | dyba: And then (require '[clojure.math.numeric-tower :as math]) |
| 17:52 | dyba | thanks technomancy & weavejester! |
| 17:52 | dyba | I'll give that a try |
| 17:53 | technomancy | np |
| 17:59 | nDuff | Can agent send operations be forced to block beyond a given queue length? |
| 18:01 | llasram | nDuff: I don't believe there's any explicit support for that sort of thing |
| 18:02 | llasram | Hmm, although -- Agents do expose a public `.getQueueCount` method |
| 18:04 | amalloy | one 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:04 | technomancy | amalloy: yes please |
| 18:04 | technomancy | err--specifically letting you bring your own thread pool is what I was thinking of |
| 18:04 | amalloy | technomancy: i think you can do that in 1.5 |
| 18:05 | technomancy | no kidding? |
| 18:05 | technomancy | no more shutdown-agents-of-death? |
| 18:06 | amalloy | technomancy: (send-via executor agent f & args) |
| 18:06 | technomancy | oh |
| 18:06 | technomancy | I guess that's better than nothing |
| 18:06 | technomancy | there's still global defaults hard-wired in that are hands-off |
| 18:06 | amalloy | https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L1895 |
| 18:06 | amalloy | no, you can change those too |
| 18:06 | technomancy | oh sweet |
| 18:06 | llasram | Also `set-agent-send-executor!` if you're into mutating global state |
| 18:07 | technomancy | two features I actually care about in a single release! that hasn't happened since 1.1 or 1.2. |
| 18:07 | llasram | lol |
| 18:07 | llasram | reducers are pretty spiffy |
| 18:08 | technomancy | I appreciate them in theory but don't see myself using them in practice. |
| 18:11 | dnolen | feedback welcome on this one - http://dev.clojure.org/jira/browse/CLJS-448?focusedCommentId=30277#comment-30277 |
| 18:11 | dnolen | oops http://dev.clojure.org/jira/browse/CLJS-335 |
| 18:30 | dyba | by the way I was able to get that contrib library to work with my project |
| 18:31 | dyba | I will say that I would never have guessed to find the `abs` function in a namespace like clojure.math.numeric-tower |
| 18:32 | dyba | thanks again to technomancy, weavejester, and xeqi! |
| 18:33 | technomancy | there's a Math/abs |
| 18:33 | technomancy | but it doesn't work on all numbers IIRC |
| 18:34 | nDuff | Hrm. |
| 18:37 | dnolen | bbloom: applying your compiler patches, thanks |
| 18:37 | bbloom | dnolen: cool thanks! |
| 18:44 | dyba_ | ok, so I reached my level of know-how with Clojure after this exception: |
| 18:44 | dyba_ | 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:44 | callen | so 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:44 | dnolen | bbloom: done! |
| 18:44 | dyba_ | where would I begin to learn about locking? |
| 18:45 | callen | is 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:45 | callen | dyba_: lesson #1: Avoid it unless it's strictly necessary |
| 18:45 | dyba_ | I feel I might have to read up on promise/deliver since I used that in my code |
| 18:46 | dyba_ | callen: so if I'm getting a locking exception, I'm probably doing something wrong? |
| 18:46 | callen | dyba_: no I don't know your circumstances, but I'll put it this way |
| 18:46 | technomancy | callen: lib-noir isn't being abandoned |
| 18:46 | technomancy | just noir |
| 18:47 | callen | technomancy: 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:47 | callen | dyba_: locking and threading both get resorted to a lot more than they usually merit. |
| 18:47 | weavejester | callen: What sort of things did you keep doing over and over? |
| 18:47 | llasram | callen: dyba_ is getting that error I assume just running leiningen, not creating locks him/herself |
| 18:47 | callen | dyba_: 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:48 | callen | dyba_: if you're getting a locking exception just from running somebody else's code, I wouldn't sweat it. |
| 18:48 | technomancy | dyba_: do you have any concurrent operations going on for this index? |
| 18:48 | ibdknox | callen: weavejester: Raynes is going to do a lib-noir template and that should get 98% of the way there |
| 18:49 | technomancy | dyba_: 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:49 | weavejester | ibdknox: I was curious as whether it was a templating problem, or something else. |
| 18:49 | callen | ibdknox: 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:49 | dyba_ | technomancy: I don't think I do |
| 18:49 | weavejester | ibdknox: Some good templates would be nice :) |
| 18:49 | callen | ibdknox: I could turn the results of what I did into a quick-start Ring template. |
| 18:49 | dyba_ | I'm not very savvy with concurrent processes. I don't think I'm running anything in parallel |
| 18:49 | callen | in fairly short order, I think. |
| 18:50 | dyba_ | I was working on that fix I volunteered for in Leiningen |
| 18:50 | callen | the nice thing about templates is that they're easily fit to purpose. |
| 18:50 | ibdknox | weavejester: 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:50 | dyba_ | and then I decided to use promise/deliver to work with a stream of bytes I get when I run the search command |
| 18:51 | dyba_ | then for the input stream i use an atom to track the number of bytes read |
| 18:51 | dyba_ | I can provide a link to the code if anyone is interested in looking into it |
| 18:51 | technomancy | dyba_: sure |
| 18:51 | callen | dyba_: why are you using promise? |
| 18:51 | dyba_ | https://github.com/dyba/leiningen/blob/master/src/leiningen/search.clj |
| 18:52 | dyba_ | callen: I have no idea what I'm doing :/ |
| 18:52 | callen | dyba_: that's me every single day, just ask any of the others here. :P |
| 18:52 | dyba_ | phew, I just keep telling everyone I'm a newbie |
| 18:53 | technomancy | dyba_: I think promise is appropriate here if you're just trying to capture proxied .setFoo args |
| 18:53 | technomancy | dyba_: have you tried just deleting the index in question and trying again? |
| 18:53 | dyba_ | technomancy: how would I do that? you mean rm -rf .m2 ? |
| 18:54 | technomancy | dyba_: no, ~/.lein/indices rather |
| 18:54 | dyba_ | oh let me try that |
| 18:54 | bbloom | dnolen: awesome! one more while you're at it :-) http://dev.clojure.org/jira/browse/CLJS-424 |
| 18:55 | callen | one concern I have about publishing a template is that my base I'm using to fix up all my apps use hiccup. |
| 18:55 | callen | for the error pages et al |
| 18:56 | callen | I was hoping to avoid being overly opinionated to that end. |
| 18:56 | dyba_ | technomancy: hm, same problem |
| 18:57 | dyba_ | maybe if I get rid of that atom inside the input-stream-proxy function |
| 18:57 | dyba_ | ha, just realized I didn't share the right branch |
| 18:57 | dyba_ | https://github.com/dyba/leiningen/tree/progress-reporting-search-index |
| 18:57 | dyba_ | ugh |
| 18:57 | dyba_ | wrong file |
| 18:58 | dyba_ | https://github.com/dyba/leiningen/blob/progress-reporting-search-index/src/leiningen/search.clj |
| 18:58 | technomancy | dyba_: the lock error just means that multiple writers are trying to be opened on the same index |
| 19:07 | alex_baranosky | technomancy: 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:08 | dnolen | bbloom: will have to look at that later, I see have a backlog since I've been working on core.logic so much |
| 19:09 | dnolen | bbloom: is this still relevant? http://dev.clojure.org/jira/browse/CLJS-412 |
| 19:11 | bbloom | dnolen: let me think about CLJS-412 for a second |
| 19:11 | technomancy | alex_baranosky: that'd be tops. let me take a peek. |
| 19:12 | dnolen | bbloom: well I responded, I might jet so soon so leave a comment :) |
| 19:12 | bbloom | dnolen: i think the first comment was a typo |
| 19:12 | bbloom | shoulda been defn |
| 19:12 | dnolen | bbloom: yep I put that in, no warnings |
| 19:13 | technomancy | alex_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:13 | technomancy | alex_baranosky: does that make sense? happy to answer questions as they come up if I'm around |
| 19:13 | bbloom | dnolen: did you have warn on undelcared enabled? |
| 19:14 | technomancy | alex_baranosky: also you'll want to replace :use with :require :refer |
| 19:14 | technomancy | but I don't think that'd be difficult |
| 19:14 | dnolen | bbloom: that's the default for Rhino REPL |
| 19:15 | technomancy | alex_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:16 | technomancy | wish I had time to hack on it; that's a really fun codebase |
| 19:16 | bbloom | dnolen: hmm dunno about that first comment, but i def get the issue from the original body |
| 19:17 | bbloom | dnolen: https://gist.github.com/4356706 |
| 19:19 | dnolen | bbloom: yes but does that happen at the REPL or in a source file? |
| 19:19 | dnolen | bbloom: in anycase I have to go - I need a lot more information about what you are trying to do. |
| 19:19 | bbloom | dnolen: it happens when i use analyze |
| 19:19 | bbloom | but no not in the repl any more it seems |
| 19:19 | dnolen | bbloom: so an explanation of why not in the REPL & yet at analyze would be helpful. |
| 19:19 | dnolen | gotta run |
| 19:20 | bbloom | dnolen: cya |
| 19:23 | alex_baranosky | technomancy: 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:23 | alex_baranosky | but first thing is to make it work :) |
| 19:23 | alex_baranosky | technomancy: I've got to run, but will keep you posted |
| 19:27 | technomancy | alex_baranosky: I wouldn't bother with 1.3 support |
| 19:27 | technomancy | 1.3 is best forgotten |
| 19:27 | technomancy | plumbing configurability all the way through for such a minor feature isn't worth the complexity |
| 19:51 | bbloom | why 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:53 | callen | bbloom: the poltergeist of APL haunting us |
| 19:53 | callen | bbloom: also: LaTeX |
| 19:55 | bbloom | i 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:04 | llasram | bbloom: Are you reading the FrTime paper? |
| 20:11 | yedi | https://github.com/doo/process |
| 20:11 | yedi | pretty sweet |
| 20:13 | paultag | Anyone 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:14 | cemerick | paultag: that might require going straight for System/in |
| 20:15 | Raynes | If I need unbuffered in and out, I go straight for System/* |
| 20:15 | paultag | righto. thanks |
| 20:15 | Raynes | I couldn't get it unbuffered from *out*, so I expect the same would make sense in *in*. |
| 20:15 | paultag | what, that it's buffered still? |
| 20:15 | seangrove | What's GClosure? This https://github.com/rhysbrettbowen/G-closure ? |
| 20:15 | paultag | Ah, right. |
| 20:15 | paultag | Yeah, sorry took a seec |
| 20:16 | paultag | sec* thanks, y'all. |
| 20:16 | seangrove | dnolen recommended people use it to pass objects from potentially different contexts |
| 20:18 | paultag | is there something like `progn' in Clojure? |
| 20:18 | paultag | ah, do. right, nvmd. |
| 20:20 | scottj | seangrove: GClosure is Google Closure |
| 20:21 | seangrove | Ah. Wonder how that's related to passing object between contexts |
| 20:21 | Raynes | Telling someone GClosure can do what they want is like telling someone who is hungry that a grocery store can do what they want. |
| 21:10 | callen | Raynes: 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:11 | callen | a lot of their adops people are trying to push angular to replace a lot of the ajaxy functionality. |
| 21:17 | seangrove | callen: 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:17 | seangrove | Curious what you mean by it not being super useful |
| 21:17 | seangrove | Also really curious about people pushing for angular to replace the ajax parts and why that'd happen |
| 21:25 | callen | seangrove: the UI widgets aren't useful for most customer-facing development. |
| 21:26 | callen | seangrove: 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:26 | callen | seangrove: Angular is pretty nice, I think Goodreads did a write-up on building a mobile web app in Angular. |
| 21:27 | callen | Angular does a lot to prevent event/data spaghetti on the frontend, but is more generally applicable to a variety of problems than Backbone. |
| 21:28 | callen | weavejester: so is most of your contracting work Clojure work then? |
| 21:28 | weavejester | callen: All of it so far |
| 21:30 | callen | weavejester: 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:30 | callen | Supposedly this is partly what spurred Hickey on, beyond his ongoing language experimentation. |
| 21:31 | callen | weavejester: is it mostly backend, full-stack, new stuff or building on existing stuff? |
| 21:31 | weavejester | There's a few businesses in London starting using it. Forward and Likely spring to mind. |
| 21:31 | weavejester | callen: I've currently just had two contracts - I only started back in July :) |
| 21:32 | weavejester | callen: One was for a web service that was semi-client facing. |
| 21:32 | callen | weavejester: 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:33 | callen | weavejester: watching your talk on clojure web dev. Thanks for your work on Ring! |
| 21:33 | weavejester | callen: Another deals with big data - cascalog, hadoop, that kinda thing |
| 21:34 | weavejester | callen: You're welcome |
| 21:34 | weavejester | Now…. |
| 21:34 | weavejester | I gotta get to bed :) |
| 21:34 | callen | Cheers :) |
| 21:45 | ferd | can somebody point me to "substantial" open-source apps built in Clojure? |
| 21:46 | callen | ferd: gimme a specialization broskie |
| 21:46 | callen | ferd: I can help you but you need to tell me what you want to see. |
| 21:46 | callen | ferd: e.g. Web app, big data application, etc. |
| 21:46 | callen | data store library... |
| 21:47 | ferd | a web app would work |
| 21:47 | ferd | I'm looking for complete business apps (not specialized libraries) ... I want to draw ideas around how to structure non-trivial codebases |
| 21:47 | callen | https://github.com/Raynes/refheap go with my classic stand-by for checking for idiomatic patterns in Clojure web apps then. |
| 21:47 | callen | ferd: 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:48 | callen | I used to use Noir + Stencil, I'm switching to Ring + Hiccup. |
| 21:50 | ferd | Thanks |
| 21:50 | callen | ferd: np. let me know if you have any questions. My work tends to be along the lines you described. |
| 21:50 | callen | ferd: business and consumer facing web apps. |
| 21:52 | ferd | for 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:53 | callen | ferd: 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:53 | callen | which has been my way of learning Clojure. It's worked well for me, better than books. |
| 21:53 | callen | although I've been fond of a few. |
| 21:54 | callen | ferd: 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:56 | callen | arohner: your cofounder was suprisingly gracious about a relatively petty spelling-fix pull request. |
| 21:57 | callen | arohner: you wouldn't happen to be able to comment on how you guys use Dieter, would you |
| 21:57 | callen | pretend there was a question mark at the end of that. |
| 22:14 | technomancy | ferd: clojars is the most widely-used OSS clojure web app |
| 22:15 | technomancy | it's been around a while but I think for the most part exhibits good design |
| 22:16 | ferd | thanks... taking a look at it now... |
| 22:21 | sgeo_ | ,(resolve 'first) |
| 22:21 | clojurebot | #'clojure.core/first |
| 22:21 | callen | ferd: clojars is even bigger than refheap, technomancy makes a great suggestion. |
| 22:22 | ferd | yeap... excellent |
| 22:22 | technomancy | as long as you ignore the fact that it uses sqlite |
| 22:22 | technomancy | =) |
| 22:22 | ferd | :-) |
| 22:22 | callen | technomancy: I cringed. |
| 22:22 | ferd | I plan on using Mongo or Datomic |
| 22:22 | technomancy | callen: it was fine until we started to add background tasks |
| 22:22 | callen | ferd: do you have some reason for doing so? |
| 22:23 | callen | technomancy: oh yes, multiple writers to a single sqlite database. |
| 22:23 | callen | technomancy: always a great idea. |
| 22:23 | technomancy | callen: I originally thought that it was just multiple processes hitting the same DB that wouldn't work |
| 22:24 | technomancy | nope! it's threads. *facepalm* |
| 22:24 | callen | I 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:24 | callen | technomancy: well it's anything that means "multiple writers" |
| 22:24 | callen | technomancy: doesn't matter if it's threads, processes, whatever. |
| 22:25 | technomancy | the 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:25 | callen | that's why I specifically use the wording multiple writers so that people don't mistake implementation for semantics. |
| 22:25 | xeqi | as soon as I replace search I can see about changing the db |
| 22:25 | ferd | callen: yes... the app I need is very "document"-oriented |
| 22:26 | callen | ferd: 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:26 | technomancy | xeqi: you are a hero =) |
| 22:26 | callen | ferd: what do you mean by document oriented in this case? it's fairly application specific. |
| 22:26 | callen | xeqi: we love you. (use postgres) |
| 22:26 | callen | xeqi: how are you doing search perchance? that happens to be a knack of mine. |
| 22:27 | technomancy | xeqi: I hope to get an email out this weekend explaining the situation around promotion |
| 22:27 | technomancy | then maybe a preview11 after christmas |
| 22:27 | xeqi | callen: still trying to decide, could just use lucene on the premade repo indexes |
| 22:28 | ferd | well... 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:28 | callen | xeqi: could do that. I'd avoid using Lucene in the raw unless you have a specific reason for doing so though. |
| 22:28 | xeqi | but I don't see an easy way to score based on downloads with that |
| 22:28 | callen | xeqi: I understand there are some uncommonly good lucene libraries for clojure, but it's kinda rough for most use-cases. |
| 22:28 | ferd | so, definitely more natural to think of them as hierarchical "documents" than SQL tables |
| 22:28 | callen | xeqi: have you considered ElasticSearch? |
| 22:28 | technomancy | elasticsearch makes no sense for a corpus this size |
| 22:29 | callen | I regard ES as being fairly lightweight and easy to use as contrasted with using raw lucene indices. |
| 22:29 | technomancy | I mean, unless you're going to expose a rest API to 3rd party tools or something |
| 22:29 | callen | our non-programming data guy figured out how to set it up himself. |
| 22:29 | xeqi | I've only started digging into it today, os still in the exploration phase |
| 22:30 | technomancy | there's no need for dynamo-style clustering for a 5MB index |
| 22:30 | xeqi | never had to plug in fts myself yet |
| 22:30 | callen | technomancy: it's not about the clustering, it's about the high-level featues. |
| 22:30 | callen | technomancy: ES has a lot of nice high-level features for things like scoring. |
| 22:30 | callen | and dynamic sorting |
| 22:30 | seangrove | Why do we love xeqi? |
| 22:31 | callen | technomancy: 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:31 | seangrove | technomancy: and what does "promotion" mean in this context? |
| 22:31 | technomancy | I dunno; raw lucene was really pleasant for me to use when I wrote lein search |
| 22:31 | xeqi | seangrove: cause I spend freetime on clojars |
| 22:31 | ferd | callen: so, what are your main points against MongoDB ? |
| 22:31 | seangrove | Ah, thank you xeqi, you're awesome ;) |
| 22:32 | callen | ferd: sorry, hold on :P |
| 22:32 | technomancy | seangrove: clojars has a separate "releases" repo that only accepts packages that qualify around certain metadata criteria |
| 22:32 | callen | technomancy: clojars is a web app that's going to have concurrent clients, not a local-only command line service |
| 22:32 | technomancy | seangrove: so packages need to get promoted from the "classic" repo into "releases" |
| 22:32 | callen | technomancy: the needs are different and he wants to have intelligent human-facing scoring |
| 22:32 | seangrove | xeqi: Is there an open list of bugs/features others can work on? |
| 22:32 | callen | to use raw lucene here is the same sort of mistake as using sqlite for a public-facing webapp to begin with |
| 22:33 | technomancy | lucene works fine for concurrent reads |
| 22:33 | seangrove | I wouldn't mind taking a look at it sometime, maybe for a hackathon or something |
| 22:33 | callen | technomancy: step away from the specifics for a moment |
| 22:33 | technomancy | the indices are already generated asynchronously, so concurrency is a non-issue |
| 22:33 | callen | technomancy: how is going to efficiently do custom scoring with raw lucene? |
| 22:33 | callen | technomancy: he'll end up duplicating the effort Baron already put into ES |
| 22:33 | technomancy | callen: in the case of clojars, the indices already exist; they are published for Leiningen |
| 22:33 | xeqi | seangrove: https://github.com/ato/clojars-web/issues , but there needs some classification for easier tasks |
| 22:34 | seangrove | Yeah, was just looking through that, seems like some pretty specific stuff |
| 22:34 | callen | technomancy: if it's a case of reusing existing code and functionality, so be it |
| 22:34 | callen | technomancy: but more advanced user-facing features are going to be painful. |
| 22:34 | technomancy | xeqi: are you getting download counts from the nginx logs? |
| 22:35 | technomancy | need to enable logs on the S3 bucket too; hmm. |
| 22:36 | xeqi | technomancy: think _ato had some work that direction |
| 22:36 | callen | technomancy: 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:36 | technomancy | cool |
| 22:36 | callen | ferd: right, okay. |
| 22:36 | xeqi | was hoping to be able to plug that in to make search rankings better |
| 22:36 | xeqi | automatic canonical finding, etc |
| 22:36 | callen | ferd: usually you just want to use a SQL database, commonly Postgres unless you have a good reason to the contrary. |
| 22:36 | technomancy | callen: can you run ES entirely in-process? |
| 22:37 | technomancy | callen: 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:37 | callen | technomancy: yes, it's a thing that's done. |
| 22:37 | callen | technomancy: it's not an officially supported use-case, but that's definitely a thing. |
| 22:37 | technomancy | ok cool; when we were using it that was really hard to set up |
| 22:37 | technomancy | but that was a long time ago |
| 22:37 | callen | technomancy: at heroku or with clojars/lein? |
| 22:37 | technomancy | at my last job; http://sonian.com |
| 22:38 | callen | technomancy: 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:38 | callen | technomancy: besides that, we've got some fairly involved multi-cluster deployments |
| 22:38 | callen | you...don't want to know what cross-cluster data migration is like with ES. It's worse with Solr. |
| 22:38 | callen | it resembles Riak, actually. |
| 22:38 | technomancy | sure; it's not difficult to set up a separate server along side clojars while developing, but it's tedious |
| 22:39 | callen | calling it dynamo like really doesn't do it enough justice. It does a better job at rebalancing than other dynamo-likes like Cassandra. |
| 22:39 | ferd | callen: 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:39 | technomancy | little 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:39 | technomancy | callen: I agree it's very impressive at large scale. |
| 22:40 | callen | ferd: what I understand so far, it's not a great reason just yet to use MongoDB |
| 22:40 | technomancy | just a bit skeptical that it scales in the other direction =) |
| 22:40 | callen | ferd: 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:40 | callen | technomancy: I would be too. it's memory-hungry. |
| 22:40 | ferd | callen: 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:41 | callen | technomancy: it's very aggressive about keeping things in-memory to satisfy soft realtime constraints. |
| 22:41 | ferd | callen: is there any good reading (book, or deep articles) to help me ? |
| 22:41 | xeqi | callen: thanks for the pointers, had someone else mention ES before, I'll have to take a look at it |
| 22:41 | callen | ferd: it resembles JSON, but migrations, schema changes, and general modelling are harder not easier to do correctly in MongoDB. |
| 22:41 | callen | ferd: you should get a book on data modelling in SQL, learn to do it right there |
| 22:41 | callen | ferd: 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:42 | ferd | honestly, 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:42 | callen | ferd: if you don't already have very strong opinions and lots of experience with data modelling MongoDB is *not* the way to go |
| 22:42 | ferd | callen: I've been using sql for 15+ years... not an expert, but... no need to read more for now :-) |
| 22:42 | callen | if 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:43 | callen | ferd: 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:43 | callen | concrete* |
| 22:43 | technomancy | I would take couch over mongo any day. |
| 22:43 | seangrove | ferd: 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:43 | callen | xeqi: 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:43 | callen | technomancy: I would not @ couch. |
| 22:44 | callen | technomancy: couch is insanely irritating and slow. |
| 22:44 | clojurebot | Ok. |
| 22:44 | seangrove | technomancy: I would shoot couch any day |
| 22:44 | technomancy | callen: mostly because it doesn't set unrealistic expectations |
| 22:44 | seangrove | Second to mongo, no software has ever caused me to wake up more in the middle of the night than couch |
| 22:44 | callen | technomancy: CouchDB is a data roach motel |
| 22:44 | callen | "data goes in, but never comes back out" |
| 22:44 | ferd | I see couch, indeed, another alternative.... I though of Mongo just 'cause it seemed more popular and better supported |
| 22:45 | callen | couch is best for non-user-facing data archival and roll-ups |
| 22:45 | technomancy | ferd: are you sure it's not just "people blog about it more"? |
| 22:45 | seangrove | Couch could be alright, but in general everything seems wrong about it |
| 22:45 | seangrove | technomancy: Our post about CouchDB http://sauceio.com/index.php/2012/05/goodbye-couchdb/ |
| 22:45 | seangrove | Ot |
| 22:45 | technomancy | yeah actually couch's strengths like on the client side with putting the user literally in control of their own data |
| 22:46 | seangrove | It is - generally - very cordial given team sentiments |
| 22:46 | ferd | wondering if I'll find a DB that nobody will bitch about here :-) |
| 22:46 | technomancy | but I'd still take it over mongo =) |
| 22:46 | technomancy | ferd: postgres |
| 22:46 | callen | the three most common databases among founders that I encounter are MySQL, PostgreSQL, and MongoDB. |
| 22:46 | seangrove | ferd: postgres |
| 22:46 | seangrove | Especially on Heroku |
| 22:46 | callen | ferd: postgres |
| 22:47 | ferd | OK... I'm very familiar with postgres... so that's good |
| 22:47 | callen | postgres is blameless. It lives up to its mission and it's fine for 99% of projects. |
| 22:47 | callen | it's not flawless, it just does what it says. |
| 22:47 | seangrove | callen: I'd add more nines to that |
| 22:47 | callen | seangrove: I wouldn't, I work at a company that uses and needs MongoDB and ElasticSearch :P |
| 22:48 | seangrove | But yes, if you've outgrown postgres, then you've done an awesome job and are a good engineer, most likely |
| 22:48 | callen | takes less than you think |
| 22:48 | technomancy | seangrove: if you've outgrown postgres, you're probably not looking for DB advice on IRC =) |
| 22:48 | ferd | I was hoping to avoid tons of mappings from JSON to SQL entity-roots and an explostion of sub-entity tables |
| 22:48 | callen | highly sparse data schemas are pretty rough in tabular row-stores. |
| 22:48 | seangrove | technomancy: True, true |
| 22:49 | seangrove | I got an email from you guys accusing me of using env vars on Heroku as a database ;) |
| 22:49 | callen | incidentally 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:49 | seangrove | The last line was, "Have you ever heard of Heroku Postgres?" |
| 22:49 | technomancy | seangrove: haha; nice |
| 22:49 | callen | seangrove: 12-factor? |
| 22:49 | seangrove | I still can't figure out if it's a sarcastic line or not |
| 22:49 | technomancy | seangrove: pretty sure it is |
| 22:50 | callen | 12-factor deployments can often be mistaken for ENV var as a data-store. |
| 22:50 | seangrove | callen: Yeah, more or less |
| 22:50 | callen | I'm psychic. |
| 22:50 | seangrove | It was required as a shim for deploying to our own PaaS, dotCloud, Cloud Foundry, and Heroku, in order to do it seamlessly |
| 22:50 | callen | I consciously chose not to do 12-factor. |
| 22:50 | technomancy | seangrove: an object lesson in the importance of adding caps sooner rather than later =) |
| 22:51 | seangrove | technomancy: I suppose |
| 22:51 | seangrove | It wasn't abusive |
| 22:51 | technomancy | seangrove: for us, I mean |
| 22:51 | seangrove | And it was within the limits supported by linux's env, etc. |
| 22:51 | seangrove | Oh, yes, I know |
| 22:51 | seangrove | You guys are generally very good at that |
| 22:51 | seangrove | By the way, you're not out here in SF are you? |
| 22:51 | callen | technomancy: 12-factor apps can end up having hundreds of env vars. It's pretty typical for projects that are hyper aggressive about deployments. |
| 22:51 | technomancy | seangrove: 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:51 | callen | well, dev-ops, lets say. |
| 22:51 | technomancy | seangrove: nah; seattle |
| 22:52 | callen | I'm in MV. |
| 22:52 | seangrove | technomancy: Bummer, you guys have a great team out here |
| 22:52 | technomancy | callen: haven't seen it myself, but I have only deployed small apps on the platform |
| 22:52 | technomancy | seangrove: I visit every couple months, which is about the right amount of SF for me =) |
| 22:52 | seangrove | I've heard that clojure is more or less out of Heroku these days though, sadly |
| 22:52 | seangrove | Something about it being too hard to hire for |
| 22:52 | ferd | anybody 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:53 | seangrove | ... and yet you persist in using Erlang ;) |
| 22:53 | technomancy | seangrove: there was only ever one clojure app in use internally |
| 22:53 | seangrove | ferd: If it's for a production-level app, don't use Datomic |
| 22:53 | technomancy | though I might be introducing another; we'll see |
| 22:53 | seangrove | That must be some kind of universal law |
| 22:53 | seangrove | "Never use a database you don't have personal experience with as the foundation of your new production-grade business app" |
| 22:54 | seangrove | Always screw around with it first |
| 22:54 | technomancy | the 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:54 | callen | technomancy: did he make a post about why he switched? |
| 22:54 | technomancy | seangrove: there's no replacement for Erlang for what we're using it for |
| 22:54 | callen | as far as clojure hiring, I've always seen it as something you don't hire directly for. |
| 22:54 | technomancy | callen: no, but I know that he never used a repl when writing clojure |
| 22:54 | seangrove | Yeah, that was the turning point from what I heard, when even Mcgranaghan gave up |
| 22:54 | callen | Rather, somebody volunteers to teach the next hire that is interested in it. |
| 22:54 | technomancy | so it's no surprise he didn't mind writing Go |
| 22:54 | callen | and that scales up in a double-fashion quickly. |
| 22:54 | callen | technomancy: ...never used...a repl? |
| 22:55 | technomancy | callen: a victim of Textmate |
| 22:55 | callen | poor bastard. |
| 22:55 | seangrove | ouch |
| 22:55 | technomancy | maintaining his stuff was all "OK, you made a change; now deploy it to staging to see if it works" |
| 22:55 | technomancy | insane |
| 22:55 | callen | technomancy: I actually shied away from Go because the entire community told me I didn't need a debugger or a REPL. |
| 22:55 | callen | technomancy: not exaggerating. |
| 22:55 | seangrove | technomancy: Yeah, Erlang comment was tongue-in-cheek |
| 22:55 | technomancy | callen: yep. completely baffling. |
| 22:55 | technomancy | there's no excuse for ignoring interactive development. life is too short. |
| 22:55 | callen | technomancy: why did testing his code require abusing staging? no unit tests? |
| 22:56 | technomancy | callen: yeah that too |
| 22:56 | callen | technomancy: their counter-argument was that type signatures and documentation should be enough @ interactive development. |
| 22:56 | technomancy | so it's actually kind of relieving that app has been retired |
| 22:56 | technomancy | haha |
| 22:56 | technomancy | type signatures; the ones that are required because you have a crappy inference engine? |
| 22:56 | callen | LOL |
| 22:57 | callen | I 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:57 | callen | spend their whole lives in the stdlib. |
| 22:57 | callen | my contracting work was too vertical to be like that. |
| 22:58 | callen | incidentally Go's equivalent to ring is actually part of the stdlibs. |
| 22:58 | seangrove | go does allow for some pretty impressive code:functionality ratios, and stays readable |
| 22:59 | callen | seangrove: I *like* Go, that's why I said I shied away from after having to confront the rest of the community |
| 22:59 | callen | seangrove: they just lack taste. |
| 22:59 | seangrove | Heh, they're alright |
| 22:59 | technomancy | yeah and gofix is an amazing feat for a non-homoiconic language |
| 22:59 | seangrove | At least when comparing them to the CL community |
| 23:00 | seangrove | And yes, gofix is awesome |
| 23:00 | technomancy | but you have to draw a line somewhere |
| 23:00 | technomancy | and for me it's that I won't go back to punch cards |
| 23:00 | seangrove | Hrm, I wonder if community is the right word in CL's case... |
| 23:00 | seangrove | Warzone maybe? |
| 23:00 | callen | seangrove: dude. CL was my original serious PL |
| 23:01 | technomancy | I tried it with Mirah (where I had the excuse of wanting to target mobile) and said never again. |
| 23:01 | callen | seangrove: C# and Python, which came after CL for me, were like dying and going to heaven. |
| 23:01 | seangrove | Heh, I love CL in many ways, it's mind-blowingly cool |
| 23:01 | seangrove | But it's impossible to get any consensus in the community, and everyone is extremely hostile |
| 23:01 | callen | seangrove: I was trying to get work done. To that end, CL was painful in many non-trivial ways. |
| 23:02 | n_b | I went Java->Python->Ruby->JS->Clojure in learning order, every one has been a step up except for JS |
| 23:02 | callen | seangrove: 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:02 | seangrove | callen: CL's fine for getting work done, particularly with quicklisp these days |
| 23:02 | n_b | Clojure has the friendliest community, Python the broadest range of application+well-written code, Ruby the largest # of mono-lingual devs |
| 23:02 | seangrove | But yeah, its' difficult |
| 23:03 | n_b | I wanted to pick up CL or an ML next, but the communtiy aspect makes it daunting |
| 23:03 | technomancy | n_b: erhm; ruby more than Java even? |
| 23:03 | callen | seangrove: quicklisp makes it easy to get libraries you can't use to begin with :P |
| 23:03 | seangrove | n_b: Interesting's point about ruby mono-lingual devs... |
| 23:03 | n_b | technomancy: Yes, but that's a view shaped by only doing Java @ Google |
| 23:03 | callen | seangrove: try using a CL library written by a guy who read Let over Lambda, let me know how that goes for you. |
| 23:03 | seangrove | callen: And lots of them! |
| 23:03 | clojurebot | callen: 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:03 | technomancy | n_b: ah, that makes sense |
| 23:03 | seangrove | callen: I've written tons of them ;) |
| 23:03 | technomancy | callen: hah |
| 23:03 | seangrove | So I'm part of the problem, hah |
| 23:03 | callen | seangrove: see? this is why I'm here. |
| 23:04 | seangrove | LoL is amazing though... definitely enjoyed it |
| 23:04 | seangrove | Abused the hell out of it |
| 23:04 | callen | restraint 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:04 | seangrove | And I'm all better now... mostly |
| 23:04 | n_b | and 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:04 | seangrove | callen: Clojure's definitely in a nice spot for that so far |
| 23:04 | callen | seangrove: agreed. |
| 23:04 | n_b | callen: 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:05 | callen | restaint, taste, and power all in one package. |
| 23:05 | seangrove | But isn't Haskell more so? |
| 23:05 | callen | n_b: python is still my day job, I don't mind it, but OTOH, the codebase is my personal kingdom of functional programming. |
| 23:05 | seangrove | I've been increasingly impressed with some of the ideas behind Haskell these days |
| 23:05 | callen | seangrove: Haskell is BDSM incarnate. |
| 23:05 | n_b | FP in python is ehhhh |
| 23:05 | callen | Haskell was a great learning experience, but I'll never use it for anything I care about. |
| 23:05 | seangrove | Why's that? |
| 23:05 | n_b | seangrove: the restraint and academic background crimp its power in a number of places |
| 23:05 | callen | Haskell did a lot to improve my Python code. |
| 23:06 | seangrove | n_b: I'm not sure... |
| 23:06 | n_b | the default string impl, for one, is a linked list |
| 23:06 | seangrove | I think it may end up fulfilling the goals of Lisp in a more powerful way |
| 23:06 | callen | n_b: there a lot of reasons not to use Haskell, that's not precisely one of them. |
| 23:06 | callen | n_b: more importantly, there are 3 or 4 prominent string types that all work differently and seem to have half-overlapped use-cases |
| 23:06 | callen | for which any given 3rd party library can choose to use any mix of them they like |
| 23:06 | n_b | I'm aware, it's just one of the things that immediately springs to mind |
| 23:06 | callen | which means you end up doing a ton of typecasting all over your damn code |
| 23:06 | callen | *irritating* |
| 23:07 | callen | also cabal is a Lovecraft Horror of the first order. |
| 23:07 | n_b | my 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:07 | callen | cabal did a LOT to make me stop using Haskell. |
| 23:07 | n_b | Cabal2 is better! _we swear_ |
| 23:08 | callen | whenever 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:09 | n_b | Where'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:09 | TimMc | callen: 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:09 | seangrove | callen: You've certainly got a lot of reasons why you've stopped using languages ;) |
| 23:09 | callen | TimMc: yes, and it puzzles me when people claim you have to do so. |
| 23:09 | TimMc | Me too. |
| 23:09 | callen | Clojure is not difficult to learn and a lot of backgrounds are good for learning it. |
| 23:09 | callen | Python, Ruby, and Java people are all well suited to learning it, if they want to learn FP. |
| 23:10 | TimMc | That's one of my pet peeves: People overestimate the difficulty of learning languages and underestimate the difficulty of learning tools, libraries, and services. |
| 23:10 | callen | the O'Reilly book is well designed. |
| 23:10 | callen | TimMc: THANK YOU! Yes. That. |
| 23:10 | TimMc | I think it's because they usually only know one of the former and many of the latter. |
| 23:10 | callen | TimMc: that's why leiningen is so important to me. |
| 23:10 | callen | TimMc: tools can turn into a bigger time-suck than your problem you're solving in a hury. |
| 23:10 | TimMc | Because it's dead easy? |
| 23:10 | callen | hurry* |
| 23:10 | callen | TimMc: and well-designed, etc etc |
| 23:11 | TimMc | "Oh, you know Java? Good. Now let's get you up to speed on our 35 tera-LOC codebase." |
| 23:11 | callen | TimMc: incidentally I know a Java dev that is terrified of and refuses to use any other languages |
| 23:11 | callen | TimMc: I figured out why...he didn't really understand what he was doing |
| 23:12 | callen | he only understood IntelliJ and Spring |
| 23:12 | callen | and anything outside Spring and IntelliJ, he didn't understand a whit. |
| 23:12 | callen | Like say, basic unix principles. 0 comprehension. |
| 23:12 | n_b | I don't understand how that happens |
| 23:12 | n_b | I can understand knowing something else and not understanding Java |
| 23:12 | callen | n_b: I don't either, but this character is starting to build a picture for me as to how it happens |
| 23:12 | n_b | It took me a couple of books and tons of time in a code base to figure out the typical design patterns |
| 23:12 | callen | it seems to largely arise from complaceny and over-reliance on familiar tools. |
| 23:13 | TimMc | callen: Tab-complete your way to working software! |
| 23:13 | callen | TimMc: yeah that's actually how he codes. |
| 23:13 | callen | TimMc: it took ages to explain to him why I use Emacs. |
| 23:13 | TimMc | It's how *I* code. |
| 23:13 | TimMc | I mean, at work, when doing Java. |
| 23:13 | callen | TimMc: there's nothing wrong with it as long as you understand what's going on |
| 23:13 | callen | the problem is, the "helpers" were a crutch for him |
| 23:14 | renderful | they refer to these people as brogrammers |
| 23:14 | seangrove | n_b: Linux is a rabbit hole of knowledge |
| 23:14 | callen | renderful: kinda-sorta. Brogrammers is more of Ruby/Rails community archetype. |
| 23:14 | seangrove | It's not something you "just pickup" unless you're really banging away at it |
| 23:14 | renderful | callen: yes, because they rely too much on Rails magic |
| 23:14 | TimMc | I'm largely working with existing libraries, so it's not unreasonable. |
| 23:14 | renderful | which is similar |
| 23:14 | callen | seangrove: I learned Linux by using over 100 different distributions and just constantly breaking and reconfiguring shit. |
| 23:14 | callen | took years. pretty big timesink. |
| 23:14 | renderful | same for me callen |
| 23:15 | renderful | 15 years so far |
| 23:15 | seangrove | But that's my point |
| 23:15 | callen | if I didn't do a fair bit of dev-ops alongside my coding these days, it'd have been a pretty big waste. |
| 23:15 | seangrove | I've use it for years |
| 23:15 | callen | renderful: similar number of years here, I started with Red Hat 5 |
| 23:15 | seangrove | Wasn'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:15 | renderful | yar, slackware 3 i believe |
| 23:15 | TimMc | I 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:16 | callen | I started from a young age, so some of my time was misspent |
| 23:16 | seangrove | Point being, that I would in no way expect someone who says they "know Java" to "know linux" |
| 23:16 | callen | but I started with Linux in 1998 |
| 23:16 | seangrove | Heh, the glory days of wasted time |
| 23:16 | renderful | most of my time was misspent :) |
| 23:16 | TimMc | seangrove: Wait, where did Linux come into this? I think I missed something. |
| 23:17 | callen | seangrove: I guess, but my point is that he was unwilling to learn and was afraid of anything outside of his cocoon. |
| 23:17 | renderful | but i love all of that time that i spent doing bullshit and making mistakes |
| 23:17 | seangrove | callen: Ah, yes |
| 23:17 | callen | TimMc: what I said about the dude being clueless outside of generating java and XML in his IDE |
| 23:17 | ioexception | Using windows for Java dev, is a bit painful to me, no tools.. no grep, no less, no shell... |
| 23:17 | TimMc | Oh, I see it now. |
| 23:17 | n_b | seangrove: 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:17 | callen | seangrove: you should at least know some basic unix commands if you're deploying to Linux servers on a regular basis. |
| 23:17 | callen | what n_b said. |
| 23:17 | n_b | I'd expect someone to go from using Play! to Rails without issue |
| 23:17 | seangrove | It'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:18 | callen | n_b: agreed although Rails has a pretty deep rabbit-hole of conventions. |
| 23:18 | ioexception | n_b: high expectations, not the common human |
| 23:18 | TimMc | You can get surprisingly far in any computery thing with mimicry. |
| 23:18 | callen | Play! is a bit better designed. |
| 23:18 | n_b | Play! (1.0 at least) and Rails are fairly similar in terms of convention doing significant amounts for you |
| 23:18 | seangrove | ioexception: 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:19 | seangrove | TimMc: Well put! |
| 23:19 | callen | n_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:19 | callen | n_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:19 | seangrove | Meh, I love rails for what it's good at |
| 23:20 | renderful | agreed seangrove |
| 23:20 | seangrove | It'll be interesting to see if it can evolve from what it is now to where people are going though |
| 23:20 | callen | I prefer Django and Flask. more restraint, more obvious as to how it works, less magic. |
| 23:20 | renderful | magic is bad |
| 23:20 | seangrove | Never used flask, just Django and a fuck-ton of pylons |
| 23:20 | n_b | ioexception: 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:21 | callen | I went CLR -> Python professionally and I use Clojure a lot on my free time. |
| 23:21 | callen | it's been a similar Java/CLR -> Python/Ruby migration path for most startup people I know that have past experience |
| 23:21 | n_b | Rails 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:22 | callen | n_b: agreed |
| 23:22 | n_b | at least than the change/reload/recompile is faster while breaking stuff |
| 23:25 | seangrove | n_b: sounds right |
| 23:25 | seangrove | Only used GWT for two weeks in a side project years ago, and wrote the gwt-rails plugin at the time |
| 23:25 | seangrove | Was an absolute nightmare |
| 23:26 | squidz | seangrove: why is that? |
| 23:26 | n_b | GWT is a really great idea implemented poorly |
| 23:26 | seangrove | Mainly there wasn't any documentation at the time, almost at all. The tooling was beyond horrendous.. |
| 23:26 | n_b | , to the extent that it's not really a great fit for what people expect of modern applications |
| 23:26 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: to in this context, compiling:(NO_SOURCE_PATH:0)> |
| 23:26 | seangrove | (dec n_b) |
| 23:26 | lazybot | ⇒ -1 |
| 23:27 | seangrove | Sorry, had to happen |
| 23:27 | squidz | ouch |
| 23:27 | seangrove | (inc n_b_ |
| 23:28 | seangrove | (inc n_b) |
| 23:28 | lazybot | ⇒ 0 |
| 23:28 | squidz | seangrove: didnt know you could go negative |
| 23:28 | seangrove | Ok n_b, I hope you've learned your lesson |
| 23:28 | n_b | Don't split messages on clauses? |
| 23:28 | seangrove | Exactly |
| 23:28 | seangrove | At least not when the bots are watching |
| 23:29 | n_b | Time to whip up an irssi script that escapes any messages starting with a comma |
| 23:29 | callen | (inc n_b) |
| 23:29 | lazybot | ⇒ 1 |
| 23:29 | seangrove | (inc me) |
| 23:29 | lazybot | ⇒ 2 |
| 23:29 | seangrove | woo! |
| 23:30 | squidz | callen: what's CLR? |
| 23:30 | callen | squidz: .NET runtime |
| 23:30 | n_b | ,(identity n_b) ;;I assume this doesn't work |
| 23:30 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: n_b in this context, compiling:(NO_SOURCE_PATH:0)> |
| 23:30 | squidz | oh i see |
| 23:30 | callen | squidz: in a past life I was a code monkey for enterprise/insurance companies. |
| 23:30 | callen | now I'm a pirate for a bay area startup. whee. |
| 23:30 | squidz | lucky you |
| 23:31 | seangrove | callen: If you're out here anyway, why not drag arohner's cofounder out to drinks anyway? |
| 23:31 | n_b | Going to MS for the summer, will be my first experience somewhere that uses anything MS |
| 23:33 | seangrove | n_b: I've been impressed with all my friends that have worked at MS |
| 23:34 | seangrove | Though none of them were in the business area... |
| 23:34 | rbxbx | MS has a wonderful research department fwiw. |
| 23:35 | callen | seangrove: his cofounder hates me, haha. |
| 23:35 | n_b | Looking 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:35 | seangrove | callen: Really? That's impressive |
| 23:35 | TimMc | rbxbx: Can you develop on anything other than Windows in MS Research? |
| 23:35 | seangrove | He seems like a very chill guy overall |
| 23:35 | n_b | and I can stick around for Seajure :) |
| 23:35 | callen | seangrove: 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:35 | callen | seangrove: he is a very chill guy. |
| 23:35 | n_b | TimMc: they do tons of non-Windows stuff |
| 23:35 | rbxbx | TimMc I'm not sure... they seem to have a lot of Haskell/functional cats over there. |
| 23:35 | TimMc | I would not be able to go back to Windows. |
| 23:36 | seangrove | callen: That can't have been a "conversation" then... |
| 23:36 | rbxbx | I'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:36 | rbxbx | ie: F# or linq |
| 23:36 | rbxbx | (maybe other things as well) |
| 23:37 | squidz | Ive heard somebody say that Google uses bayes filtering the way MS uses if statements, but im not sure who said it |
| 23:37 | callen | seangrove: depends on how you look at it. it was a conversation about an IRC service that shut-down. |
| 23:37 | n_b | IME the people at Google and the people at Microsoft are equally capable at least as far as the rank and file are concerned |
| 23:37 | seangrove | callen: 'fess up, what did you say about his mother... |
| 23:38 | callen | seangrove: 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:38 | seangrove | Ah yes, grove |
| 23:38 | seangrove | You were one of the dicks he was referring to, presumably? |
| 23:38 | callen | I don't think I was even the main one. |
| 23:38 | callen | seangrove: amusingly, Raynes was one of the people he was arguing with as well. |
| 23:39 | callen | I described his position on the matter as "advocating for total unaccountability on the part of startup founders" |
| 23:39 | seangrove | Leah's certainly had a weird path at this point |
| 23:39 | callen | that's what really set him off. |
| 23:39 | callen | seangrove: throwing spaghetti at the wall is fine, that's not my problem. |
| 23:39 | seangrove | Yeah, he seemed very incensed at the time |
| 23:39 | callen | seangrove: my problem is doing it at the expense of paying (business!) customers. |
| 23:39 | callen | they 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:40 | callen | if she'd handled her past projects in a more professional manner, I doubt anybody would've noticed or cared. |
| 23:40 | seangrove | Yeah, we shutdown Bushido, and spent probably a week migrating everyone |
| 23:40 | callen | she didn't, so we noticed. Then rohner's cofounder got really mad. |
| 23:40 | callen | oh well. |
| 23:40 | seangrove | Not a single user complained in a way we didn't take care of... felt happy of that at least |
| 23:40 | callen | I'm mostly mad about my account getting hellbanned. I've been through like 4 or 5 HN accounts. |
| 23:41 | callen | seangrove: I'm otherwise sanguine about the matter. |
| 23:41 | callen | seangrove: are you in SF? |
| 23:41 | seangrove | I am |
| 23:41 | seangrove | Yourself? |
| 23:42 | callen | seangrove: MV |
| 23:42 | seangrove | I also like Paul a lot ;) |
| 23:42 | seangrove | Ah, I lived there for ~2 years |
| 23:42 | TimMc | Molybdenum Valley? |
| 23:42 | callen | I like Paul, he just holds opinions I'm not going to coddle or countenance seriously. |
| 23:42 | technomancy | sounds like a good preventative measure |
| 23:42 | callen | technomancy: you're too well known |
| 23:42 | seangrove | technomancy: I can have a word for you if you'd like... |
| 23:43 | callen | I actually heard about him originally because of his compiler work. |
| 23:43 | callen | I didn't really make the connection between his compiler work and CircleCI until he popped up in a discussion about HipHop |
| 23:44 | technomancy | I could be like giles bowkett and just redirect all HN-referred requests to a page telling them how they're jerk-faces |
| 23:44 | seangrove | arohner: There're a lot rumors about your cofoudner flying about |
| 23:44 | seangrove | You might want to squash them sooner rather than later |
| 23:44 | mehwork | how do you apply a symbol to each item in a coll? |
| 23:44 | seangrove | Rumors like he cared enough to comment on hiphop... |
| 23:44 | callen | technomancy: 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:44 | technomancy | callen: he's a remarkable man |
| 23:44 | callen | seangrove: 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:44 | technomancy | in good and bad ways |
| 23:45 | callen | technomancy: remind me why he did that? |
| 23:45 | technomancy | callen: 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:45 | callen | http://hyperdex.org/ <--- I use ES for a similar use-case as this |
| 23:46 | seangrove | ES? |
| 23:46 | clojurebot | https://github.com/dakrone/cheshire |
| 23:46 | callen | technomancy: the only threads that don't bring the worst out of HN are about Erlang. |
| 23:46 | callen | seangrove: elasticsearch |
| 23:46 | callen | technomancy: remember the day of Erlang? |
| 23:46 | seangrove | Ah, ok |
| 23:46 | callen | it was glorious. |
| 23:46 | mehwork | well actually how do you map symbols to things like so '("a" "b" "c") becomes {:foo "a" :bar "b" :baz "c"} |
| 23:46 | seangrove | mehwork: zipmap? |
| 23:47 | seangrove | ,(zipmap [:foo :bar :baz] ["a" "b" "c"]) |
| 23:47 | clojurebot | {:baz "c", :bar "b", :foo "a"} |
| 23:47 | mehwork | yeah zipmap works darnit my question stilli sn't what i mean |
| 23:47 | Raynes | callen: Who was I arguing with? |
| 23:47 | callen | mehwork: please elaborate. |
| 23:47 | seangrove | Raynes: technomancy over clojars |
| 23:47 | callen | Raynes: cofounder of CircleCI. The grove.io thread. |
| 23:47 | technomancy | callen: I must have missed that |
| 23:47 | Raynes | callen: Oh, yeah, that one-can-short-of-a-one-pack guy. |
| 23:47 | callen | Raynes: I'm the Gandalf of remembering HN threads. |
| 23:48 | Raynes | Yeah, that guy was about as smart as as box of hair. |
| 23:48 | callen | Raynes: LOL |
| 23:48 | seangrove | Hah, ouch |
| 23:48 | mehwork | zipap 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:48 | TimMc | Raynes: See, this is why Alabama is allowed. |
| 23:49 | Raynes | It'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:49 | TimMc | The South has some pretty good sayings. |
| 23:49 | Raynes | It's great for her startup lifestyle, not so great for users of said startups. |
| 23:49 | seangrove | TimMc: I sitll think it's a stretch to argue the existanace of the south is justified |
| 23:49 | callen | My position was identical to Raynes' |
| 23:50 | Raynes | seangrove: So what was I arguing with technomancy about clojars for? |
| 23:50 | seangrove | Raynes: sorry, just a bit of trolling |
| 23:50 | callen | Raynes: he was kidding |
| 23:50 | mehwork | the south deserves to exist. the people in it are another question ;p |
| 23:50 | TimMc | seangrove: It's also very scenic. |
| 23:50 | callen | Raynes: the argument mentioned was the grove.io thread. |
| 23:50 | Raynes | Well, I actually did complain about technomancy making the releases repo. |
| 23:50 | technomancy | we got bit by grove.io disappearing and are stuck on campfire =( |
| 23:50 | technomancy | it's ... not a good piece of software. |
| 23:50 | callen | technomancy: haha oh god, point proven. |
| 23:50 | seangrove | technomancy: Stripe might release their system |
| 23:50 | callen | technomancy: most people make-do with campfire by using propane. |
| 23:51 | technomancy | callen: unacceptable |
| 23:51 | seangrove | It's an irc server witha web frontend as well |
| 23:51 | Raynes | But 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:51 | callen | technomancy: if I made a grove.io clone, would your company pay for it? |
| 23:51 | technomancy | for many reasons, foremost of which is that it's not Emacs |
| 23:51 | Raynes | technomancy: I've yet to figure out why people don't just get a private channel on any given IRC network. |
| 23:51 | Raynes | Unless you're Red Hat. |
| 23:51 | technomancy | callen: 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:51 | callen | Raynes: my company did that initially. |
| 23:51 | Raynes | Who has like 400 IRC channels on their private network. |
| 23:51 | callen | technomancy: that's sad. Really sad. |
| 23:51 | technomancy | Raynes: because "freenode" isn't "free as in we host your infrastructure for you"? =) |
| 23:52 | callen | we actually switched away from freenode because it was too unreliable. |
| 23:52 | Raynes | technomancy: I set up an ircd once. I would not recommend it. |
| 23:52 | TimMc | Running a private IRC server is like... the easiest thing, right? |
| 23:52 | callen | TimMc: if you're competent at the whole unix and editing text files thing, sure. |
| 23:52 | technomancy | Raynes: we used subrosa (written in Clojure) at my last job and it was awesome. |
| 23:52 | Raynes | technomancy: 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:52 | TimMc | callen: Wait, there's no GUI? :-O |
| 23:53 | callen | technomancy: subrosa is abandoned, no? |
| 23:53 | Raynes | callen: If you're competent at editing text files with settings that seem nearly meaningless. |
| 23:53 | Raynes | But are super important. |
| 23:53 | technomancy | callen: it's not actively developed, but it's in active use every day by its author, which counts for something? |
| 23:53 | Raynes | Well, I'll be honest, setting up the server is fairly simple. Linking services and other servers with it is not. |
| 23:53 | callen | technomancy: fair enough. |
| 23:53 | technomancy | Raynes: the problem is using software that's not written in lisp. |
| 23:54 | technomancy | ugh; flashbacks to configuring znc--so horrible |
| 23:54 | Raynes | technomancy: The problem is using software with custom configuration languages. |
| 23:54 | technomancy | faux-xml |
| 23:54 | technomancy | is. the. worst. |
| 23:54 | technomancy | worse even than .ini files |
| 23:54 | Raynes | Dear people, you do not need a custom configuration language. Use a good language. |
| 23:54 | rking | Well, what's the solution to the config problem? |
| 23:54 | technomancy | Raynes: 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:54 | seangrove | Or use a non-deterministic config language |
| 23:54 | callen | I've actually been giving thought as to how to make a reliable distributed IRC network |
| 23:54 | rking | Raynes: OK so how do you get it from that language to your language? |
| 23:55 | Raynes | rking: In Clojure, my configuration language *is* my language. |
| 23:55 | rking | Everybody has to write configs in the language that's interpreting them? What does C do, then? |
| 23:55 | Raynes | I was kinda implying you shouldn't do it in C. :p |
| 23:55 | rking | Raynes: Do you have an example of software that uses Clojure as a config? |
| 23:55 | technomancy | inc |
| 23:55 | Raynes | rking: Plenty of my own software, and pretty much everyone elses. |
| 23:55 | Raynes | Did I offend you or something somehow? |
| 23:55 | seangrove | technomancy: dec |
| 23:55 | rking | Raynes: URL to config files? |
| 23:56 | callen | anyone seen Nginx or Varnish config files? |
| 23:56 | Raynes | I think I offended him. :( |
| 23:56 | mehwork | Django uses python as a config language |
| 23:56 | callen | it's a mini-language just for configuration. Hilarious. |
| 23:56 | amalloy | rking: every project.clj file ever, is leiningen's configuration, in clojure |
| 23:56 | technomancy | callen: nginx doesn't feel so bad just because it's usually compared with apache |
| 23:56 | TimMc | I write my Piet config files in Piet, what's the problem? |
| 23:56 | callen | technomancy: I know...god I hate configuring apache. |
| 23:56 | amalloy | (inc piet) |
| 23:56 | lazybot | ⇒ 1 |
| 23:56 | Raynes | rking: 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:57 | Raynes | I mean, I'm not sure what I have to prove. |
| 23:57 | callen | TimMc: I prefer Mondrian. |
| 23:57 | Raynes | Clojure is perfect for Clojure configuration. |
| 23:57 | Raynes | It's just natural. |
| 23:57 | Raynes | Python and Ruby and even Haskell can do it too. |
| 23:57 | TimMc | Raynes: My entire source tree is config for the JVM. |
| 23:57 | mehwork | "code being data" |
| 23:57 | Raynes | See xmonad for Haskell. |
| 23:57 | callen | TimMc: HAHAHAHA |
| 23:57 | callen | TimMc: the people who've worked in "enterprise" will get your joke :P |
| 23:57 | Raynes | But seriously, I promise, it's possible, people do it, it's better. |
| 23:57 | TimMc | My hard drive is source for the CPU. |
| 23:57 | TimMc | *config |
| 23:58 | Raynes | xmonad is a great example. |
| 23:58 | technomancy | seangrove: I actually think the suckless way is great for C programs |
| 23:58 | TimMc | callen: I'm not sure I get it from that perspective, jsut from a comp arch perspective. |
| 23:58 | Raynes | I'd also bet that you can even do something like it in C. |
| 23:58 | mehwork | if the world only makes sense to you in java/xml then the world might has well have just ended today afterall |
| 23:58 | rking | Hahaha |
| 23:58 | technomancy | seangrove: you want to reconfigure it? recompile it. it only takes 5s because it's small =) |
| 23:58 | rking | https://github.com/flatland/lazybot/blob/develop/.lazybot/config.clj |
| 23:58 | rking | *That's* supposed to be an end-user facing config lang? |
| 23:58 | technomancy | anything larger and you have no business using C =) |
| 23:58 | Raynes | Uh |
| 23:58 | mehwork | rking: that's what admin interfaces are for |
| 23:59 | rking | Sorry, I'm new enough to clojure that I didn't realize that was as good as it gets. |
| 23:59 | Raynes | I... |
| 23:59 | technomancy | json would be OK for config if it weren't for the insane refusal to support comments |
| 23:59 | Raynes | I didn't... |
| 23:59 | TimMc | rking: Looks fine to me. |
| 23:59 | ibdknox | Raynes: make better configs :p |
| 23:59 | ibdknox | geez |
| 23:59 | Raynes | I never said that was as good as it gets, Mr. Sir. Furthermore, end-user configurations? |
| 23:59 | TimMc | technomancy: Crockford is pretty weird about JSON. |
| 23:59 | rking | mehwork: Then the serialization format doesn't matter if you have an admin interface. Could be a gzipped wad of ints. |
| 23:59 | callen | rking: it would seem you haven't done much Clojure development. |