#clojure log - Aug 03 2013

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

0:05 futile: does this not already exist?

0:05 (defmacro do-in-background [& body] (doto (Thread. (fn [] ~@body)) (.start)))

0:05 callen: I know Clojure is a Lisp, but the way it's made immutable-by-default semantics palatable to my Common Lisp infected brain is quite impressive.

0:05 And in the process, is still even more concise, clean, and readable.

0:06 futile: callen: i looked at CL a few years ago. didnt seem any more special than ruby/python/etc, just had more parens (but only slightly more)

0:06 callen: futile: it's considerably more powerful than rb or py, being a proper lisp. It's just less 'nice'.

0:06 Clojure leapfrogs all of them in that dimension.

0:06 futile: heh

0:07 srsly though, is there no do-in-background built in?

0:07 callen: py and ruby are babyfood compared to Common Lisp.

0:07 futile: what do you mean?

0:07 futile: (defmacro do-in-background [& body] (doto (Thread. (fn [] ~@body)) (.start)))

0:07 callen: futile: you're not supposed to do that dude.

0:07 futile: why?

0:07 callen: futile: that's what futures are for.

0:07 clojurebot: futile: because you can't handle the truth!

0:07 callen: seriously, just use futures and promises.

0:07 futile: callen: i just want it to happen in the background

0:07 callen: a future will do that for you.

0:07 just use futures.

0:07 they're going to be faster in the common-case anyway.

0:07 futile: but they mean semantically different things

0:08 futures imply you get the value back at some point, right?

0:08 callen: what you're proposing is not idiomatic code and there's a reason it hasn't been baked into an idiom. Futures are better.

0:08 futile: but here i dont care about values.

0:08 ah

0:08 are futures built into clojure?

0:08 callen: ...yes

0:08 you shouldn't be chucking side effects around willy nilly either, but even leaving that alone, use a damn future.

0:09 I'm not sure how you missed futures and promises, they're one of my favorite Clojure features.

0:09 I use them to make Scala people jealous all the time (they integrate much more cleanly)

0:09 futile: googling now

0:09 soulman__: why?

0:09 clojurebot: why is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone

0:10 soulman__: ;-)

0:10 callen: stop saying why without targeting somebody and providing context, clojurebot will make manifest how silly your communication is otherwise.

0:10 futile: btw callen this is what im working on: https://github.com/sdegutis/dotfiles/blob/master/projs/zephyros/src/zephyros/core.clj

0:10 callen: I hate saying, "why what?"

0:10 soulman__: callen: that was just a test

0:11 futile: callen: oh neat, so my (do-in-background ...) can literally be swapped out with (future ...)

0:11 yay

0:12 callen: soulman__: you can /query the bot

0:12 futile: wow futures are cool

0:12 i think thats going to help simplify my api a LOT

0:13 so simple too

0:13 i think the trick to being a good programmer is just knowing all the tricks there are so that when a problem arises that is best solved with one you already have it up your sleeve

0:13 callen: futile: your ears should perk up whenever your code gets ugly. Usually means you're fucking up.

0:13 futile: i think thats all it takes.

0:14 callen: that's hardly sufficient, but it's a good thing to keep in mind.

0:14 futile: no, i think thats all it is.

0:16 callen: i almost wonder if futures could help me get rid of my map-of-concurrent-blocking-queues

0:17 i really hate that design because it means having to take the queue out of the map when im done with it.

0:27 soulman__: if i use binding to bind *out* to a FileWriter, will that be closed automatically?

0:29 callen: futile: probably.

0:29 futile: callen: no, i cant imagine how.

0:32 technomancy: futile: FWIW I agree with your inclination to cringe a bit at using futures without caring about their value

0:32 that said, I would still use futures

0:32 futile: technomancy: yeah i settled on using them and just saying 'meh its built in'

0:33 technomancy: I would cringe harder at using agents for that

0:34 callen: technomancy: I was half trying to get him to stop side-effecting

0:35 technomancy: I assumed there was an x-y type thing going on and that getting him to stop side effecting by dint of using futures would lead to other things getting cleaned up.

0:35 tl;dr I am manipulative

0:35 futile: callen: this is inherently side-effecty

0:35 im scripting my window manager in clojure

0:35 callen: it really doesn't have to be.

0:35 futile: the tcp conversation is side-effecty

0:36 i think ive made it pretty idiomatic clojure so far

0:36 amalloy: xmonad to the rescue??

0:36 lazybot: amalloy: Definitely not.

0:36 amalloy: oh well

0:36 futile: amalloy: this is for mac

0:52 technomancy: is it possible to make `lein run` not print the last thing -main returned?

0:55 amalloy: i'm pretty sure it would be impossible for lein run to have the behavior you're asking to change

0:56 well, i guess that's not true

0:56 but still, i don't think it actually does that

0:57 futile: oh

0:57 ok

0:59 is it a feature of Java that i dont see any exceptions that happen on background threads (in futures)?

1:00 amalloy: $google java uncaught exception handler

1:00 lazybot: [Thread.UncaughtExceptionHandler - Oracle Software Downloads] http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html

1:01 futile: thanks amalloy

1:13 welp, looks like setting the uncaught-exception-handler doesnt help, it never gets called (or at least it never prints to stdout)

1:20 ThatOneGuy: welp

1:30 futile: ,(last (repeat 3))

1:30 clojurebot: Execution Timed Out

1:33 futile: does (repeatedly) cache its stuff?

1:33 i mean, its return values

1:33 ThatOneGuy: uhhh

1:34 yes, I think it memoized.

1:34 * ThatOneGuy sends futile to google :P

1:34 futile: i wonder if thatll impact this negatively

1:34 (repeatedly #(.take queue))

1:34 ThatOneGuy: ,(doc repeatedly)

1:34 clojurebot: "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it"

1:35 futile: if i do (first f) (first f) on that, i wonder if the second one will return the cached version of the fn, or re-call it

1:35 ThatOneGuy: cached

1:36 futile: dang

1:36 ThatOneGuy: test it.

1:37 ,(do (first (repeatedly #(str "lawl its " (System/currentTimeMillis)))) (first (repeatedly #(str "lawl its " (System/currentTimeMillis)))))

1:37 clojurebot: "lawl its 1375507290121"

1:38 futile: um thats a bad test

1:38 ThatOneGuy: ,(do (first (repeatedly #(prn "lawl its " (System/currentTimeMillis)))) (first (repeatedly #(prn "lawl its " (System/currentTimeMillis)))))

1:38 clojurebot: "lawl its " 1375507316635\n"lawl its " 1375507316637\n

1:38 futile: ,(let [f (repeatedly #(println "foo"))] (first f) (first f))

1:38 clojurebot: foo\n

1:38 futile: dang

1:38 ,(let [f (repeatedly #(println "foo"))] (first f) (second f))

1:38 clojurebot: foo\nfoo\n

1:38 ThatOneGuy: thats a worse test

1:38 futile: nuh uh

1:38 mines better

1:39 ThatOneGuy: you won't know when something is cached or not because it returns the same thing every time

1:39 futile: i want it to call (f) each time

1:39 ok, that works.

1:39 yay thanks

1:40 ThatOneGuy: I think there are better ways to do what you wan't

1:40 want*

1:40 lawl

1:40 like (defn next-in-queue [] (.take queue)) that way it nots generating a seq and possibly memoizing it

1:41 futile: thanks

1:46 ThatOneGuy: or if you want to define the queue once. (def next-in-my-favourite-queue (queue-taker queue)) (defn queue-taker [queue] (fn [] (.take queue)))

1:46 the power of CLOSURES! :P in clojure

2:16 futile: is there a better way to keywordize map-keys than manually with into {}?

2:18 meh itll work

2:18 its short

2:25 Bronsa: futile: clojure.walk/keywordize-keys ?

2:25 futile: yeah that

2:25 thanks Bronsa

2:27 is there a less dumb way to do this?

2:27 (take msg-size (repeatedly #(.read socket)))

2:31 uh oh

2:31 these bytes im getting... they're utf8

2:32 but im doing this: (apply str (map char bytes))

2:32 i think thats why its messing up maybe.

2:36 how do you convert an array of utf8-encoded bytes into a utf8 string?

2:49 clj_newb_2345: when designing an editor; should line numbers / column numbers be 0 or 1-indexed? I thought it should be 0; but then I checked vim, which appears to be 1-indexed

2:49 is there any reason for this to be 1-indexed

2:49 (relation to clojure is that I'm writing my editor in Clojure)

2:49 by "editor" I really mean HTML canvas for displaying code

2:49 taht is slightly editable

2:53 futile: clj_newb_2345: i would do 1

2:54 clj_newb_2345: because it's right or beacuse everyone is used ot it?

2:54 futile: clj_newb_2345: both

2:54 clj_newb_2345: also have you looked at nightcode? https://github.com/oakes/Nightcode

2:55 clj_newb_2345: futile: nah, just finished learning hiccup (after ditching enlive) and garden

2:55 futile: k

2:56 clj_newb_2345: will look into this after I finish existing project

2:56 futile: clj_newb_2345: its a text editor/ide written in clojure

2:56 clj_newb_2345: updated 4 hours ago too, rather active :-)

2:56 futile: :)

3:22 r0bglees0n: is talking to Java a pro or a con when you want clojure to run on multiple runtimes? (.NET, Java), or is JVM so dominant that it doesn't matter?

3:24 clj_newb_2345: is htere a more idiomatic way to write "(map (fn [x] (gensym)) (range 100))" ?

3:24 where "100" is really meant to be an arbitray integer n

3:24 it seems kind of stupid to do (fn [x] (gensym)) which makes me think there aught to be a better solution

3:25 Bronsa: ,(take 3 (repeatedly gensym))

3:25 clojurebot: (G__31 G__32 G__33)

3:26 Bronsa: ,(map (constantly gensym) (range 3))

3:26 clojurebot: (#<core$gensym clojure.core$gensym@5f65a8> #<core$gensym clojure.core$gensym@5f65a8> #<core$gensym clojure.core$gensym@5f65a8>)

3:26 Bronsa: derp.

3:26 go with the first one.

3:33 poppingtonic: Hi, after running lein deps on a new project, how do I make sure nrepl recognizes the downloaded packages without restarting?

3:39 amalloy: Bronsa: (repeatedly 100 gensym)

3:39 futile: whoa

3:39 i just resized my window via clojure

3:50 Bronsa: amalloy: right, I always forget the second arity of repeat/repeatedly

3:57 futile: woooo https://github.com/sdegutis/zephyros/blob/tcp/libs/zephyros-clj/src/zephyros/api.clj

3:57 TEttinger: Bronsa, even without it you could do (take 100 (repeatedly gensym))

4:21 morrifeldman: Hello, I'm trying to use clojure.java.jdbc.ddl but when I require it as (require 'clojure.java.jdbc.ddl) I get a FileNotFoundException

4:22 clj_newb_2345: amalloy: nice; thanks, I thought there was something simpler

4:47 clojurenewb: hey guys, I'm trying to map a simple tree data structure into a hickory tree structure of nested ul nodes, can anyone point to similar examples ? I'm struggling conceptually

5:03 BlackBlock: member:clojurenewb - if you want to do it yourself, recurse through the tree conjing [:li] to an initial [:ul] for each child, check if that child has children & if so recurse with the current [:li] to conj to

5:04 …or you could use C2 unify

5:05 clojurenewb: BlackBlock: C2 unify ? is that a library which handles generic cases like this ?

5:05 BlackBlock: c2 is a library, unify is a function in it

5:05 clojurenewb: I'll have a look, thanks

7:00 app_80: hi all, i am trying to set up a clojure development environment on my android tablet. i have emacs working with clojure-mode and nrepl - but i cant start a repl because i dont have lein on my tablet.. and i dont seem to be able to connect to a repl running on a linux box either.. does anyone know of a version of lein that will run on android?

7:02 TEttinger: pmde, good question

7:03 can android even run jar files?

7:03 pmde: i'm not sure

7:03 there is a clojure repl for android

7:03 so i can write code and run it

7:03 in that repl..

7:09 clj_newb_2345: gah, is there a way to get clojure's split-line to not ignore trailing newlines?

7:09 (clojure-splitlines "a\n\n\n\n") returns ["a"]

7:09 whereas I'd preter ["a" "" "" "" ""]

7:14 pmde: oh the repl on my linux box is only listening to 127.0.0.1 :(

7:20 morrifeldman: seancorfield: I'm trying out the new API and I really like it. I'm confused on the difference between db-do-commands and execute!. When should I prefer one or the other?

7:22 scape: app_80 I'm not sure anyone has tried that before

7:25 IamDrowsy: pmde: ssh tunneling is your friend

7:28 scape: TEttinger: I was able to include my uberjar in android, it ran great actually

7:28 TEttinger: wow good stuff

7:28 scape: you need a static entry point in to the app from java

7:29 gen-class static method

7:29 i quickly wrote a post about it: http://blog.juncoapps.com/2013/07/31/running-libgdx-as-a-clojure-game-in-android/

7:29 may give some ideas for your app

7:32 TEttinger: `mail clj_newb_2345 (clojure.string/split "a\n\n\n\n" #"(?=\n)")

7:32 &mail clj_newb_2345 (clojure.string/split "a\n\n\n\n" #"(?=\n)")

7:32 lazybot: java.lang.RuntimeException: Unable to resolve symbol: mail in this context

7:33 TEttinger: I thought sending mail was a feature of lazybot

7:37 Bronsa: TEttingeri think it's $mail

7:37 TEttinger *

7:53 pmde: IamDrowsy: good idea.

7:54 i found there is a fix merged to master to allow you to specify the listen address at startup, but it is not in the latest release (2.2.0)

7:54 it allows - lein repl :start :host 0.0.0.0 :port 9999 for example

7:55 scape: maybe nrepl used directly in the project?

8:38 dbe: Can I do something like (def agent (agent 0)) (send agent <set value to the return value of (f))? I'm thinking if I can use agents like Golangs "go func()".

8:41 Found 'future', nevermind.

9:13 squidz: dnolen: saw your two new core.async posts. Really cool that your posting up cool stuff that you find. Thanks for your work

9:16 dbe: squidz, link?

9:18 gavri: I'd like what clojure.core/max-key does, but I'd like it to return multiple keys if more than one key corresponds to the maximum value. is there a function that does that?

9:18 squidz: http://swannodette.github.io/ here are his articles. The last three ones are recent and 'CSP is Responsive Design' is more in-depth

9:19 dbe: squidz, thanks.

9:19 edbond: ,(doc max-key)

9:19 clojurebot: "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest."

9:49 jtoy: i noticed there is no library for working with berkelydb , that is weird

9:49 are there any other key value databases that are jstu a single file alike sqlite for clojure to use?

10:11 scape: how would i call this in clojure? .glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); assuming the buffer bits are ints

10:11 i dont understand how to pipe them together

10:31 Okasu: scape: (.glClear obj (bit-or gl-foo gl-bar))

10:52 jonasen: dnolen: http://dev.clojure.org/jira/browse/CLJS-567

11:10 gavri: I load-file this file https://raw.github.com/gavri/show-of-hands/wip/extensions/show-of-hands-lib.clj in this one https://raw.github.com/gavri/show-of-hands/wip/src/show_of_hands/core.clj

11:11 but I'm unable to access the loaded files functions in core.clj

11:11 is this a namespace problem?

11:19 technomancy: jtoy: sure; you can use derby or that other one I forget the name of if you want sql. there are java libs for berkeleydb though; search for sleepycat.

11:20 IamDrowsy: gavri: try swapping the load-file and the ns form... i would think it loads the file and will then swap to the core ns (so not loaded there)

11:21 gavri: now I get a ClassNotFoundException for "show-of-hands.core"

11:21 IamDrowsy: ^^

11:23 shdwprince: I forgot function from clojure.core, it have 2 behaviors depending on which collection (vector or list) passed to it argument. Someone?

11:23 IamDrowsy: gavri: mh i don't know.. and i can't try it now.. sry

11:24 gavri: IamDrowsy: no problem. thanks

11:24 technomancy: gavri: using load-file is kind of an advanced topic; stick with require when starting out

11:26 gavri: none of the require examples involve loading files. they seem to be loading some kind of modules http://clojuredocs.org/clojure_core/1.2.0/clojure.core/require

11:26 do modules map one to one to files?

11:29 technomancy: gavri: except in weird cases, namespaces map directly to files, yeah

11:31 TimMc: gavri: In Clojure you work with namespaces, not files. The files representing them are laid out according to Clojure + JVM conventions.

11:38 gavri: require seems to be taking in a vector of symbols as parameters

11:38 all I have is a file path

11:38 and the symbols are dot-separated

11:38 like package names

11:39 at this point, I'm just looking for the equivalent of C's #include

11:44 I've added the contents of the second file in the first for now. I'll get around to learning about file and module inclusions later. thanks everyone

11:50 TimMc: gavri: I came in to this conversation late, so... what's your reason for wanting to do this in a non-standard way?

11:51 gavri: TimMc: I'm learning clojure and didn't want to get bogged down in understanding modules/packages, so I just included the util functions in the mail file

11:51 there's no reason really

11:51 I didn't want to get blocked because I don't know how to include files :D

11:51 TimMc: You'll probably have less trouble if you learn it now -- there's not much to learn.

11:51 gavri: in the *main file, I mean

11:54 TimMc: src/show_of_hands/core.clj should have (ns show-of-hands.core (:require show-of-hands.lib :refer :all)) at the top.

11:54 And then you can have src/show_of_hands/lib.clj with (ns show-of-hands.lib) at the top.

11:55 gavri: TimMc: thanks a lot. also, I was just reading this http://stackoverflow.com/a/2459611

11:55 TimMc: :refer :all is *generally* frowned upon, because it makes it harder to tell where functions are coming from by name, but it might be appropriate here.

11:56 Alternatively, in place of ":refer :all" you could have ":as lib" and then write lib/max-value instead of max-value in the main file.

11:56 or ":refer [max-value max-keys-based-on-value]" if you want to be explicit but not have a prefix.

11:58 llasram: gavri: Unrelated, you may also wish to examine `max-key`

11:58 &(doc max-key)

11:58 lazybot: ⇒ "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest."

11:58 gavri: thanks, TimMc

12:00 TimMc: gavri: My first recommendation is probably the best for getting started, but you'll want to avoid it as your program (and experience) grows.

12:00 gavri: llasram: max-key only returns a single result when there are multiple matches. I'd like all the matches to be returned. for example, in {:a 1 :b 2 :c 2}, I'd like to get back [:b :c] instead of just :b or :c

12:01 TimMc: got it. I'll do it the first way for now

12:05 MadFunk: anyone have any experience with clang or otherwise working with cljs+angular?

12:07 squidz: MadFunk: I started making an application with clojurescript and angular, but the so far I left the angular bits in javascript and otherwise used clojurescript

12:08 MadFunk: so you had them do their own thing without being aware of eachother

12:10 squidz: yeah so far

12:10 But I was planning on trying to move out as much as javascript as possible into clojurescript

12:10 I haven't used clan for example, but that looks interesting

12:11 MadFunk: yeah, it seems pretty awesome. but there's.. no real reference on it i can find, so i'm a bit wary of using it.

12:12 squidz: I think I would start keeping them seperate, but when you see a good situation where you could move some stuff out into clojurescript may be a strategy

12:13 MadFunk: i am still very new to clojure/cljs, so that's probably the best approach

12:14 squidz: any javascript that isnt angular/otherlib dependent would be good candidates. Which is usually logic of some sort

12:15 MadFunk: aye.

12:16 i get the sense for any stuff that would be pure js, it's usually better to write that in cljs instead

12:18 futile: is there a lein plugin that lets you run a single clojure file, which would be a mixture of a project.clj and the rest of the stuff you need?

12:18 er, a mixture of project.clj and the src file

12:18 (sorry for the insane wording)

12:21 samrat: futile: lein exec

12:22 futile: wooo thanks samrat!

12:22 can you specify a filepath somewhere on your system to be a dependency?

12:22 like, if i want to load "foobar" lib, but its not in maven/clojars, its really just at "/my/libs/foobar"

12:23 samrat: futile: there is a library for that too, by the lein exec's author I think

12:23 futile: yay!

12:23 you're making my day

12:27 technomancy: futile: add-classpath

12:27 is one way

12:27 not sure why you wouldn't just make an uberjar though

12:27 it's a lot simpler

12:27 MadFunk: squidz: thanks for the feedback btw

12:28 futile: technomancy: trying to simplify this: https://github.com/sdegutis/zephyros/blob/tcp/Docs/Clojure.md

12:28 technomancy: to make it more like this: https://github.com/sdegutis/zephyros/blob/tcp/Docs/Ruby.md

12:28 in terms of setup

12:28 technomancy: futile: yeah you definitely want an uberjar

12:29 futile: thanks :)

12:29 * futile will google what an uberjar is and how to use it

12:29 technomancy: no one's gonna want to install lein if they don't care about clojure

12:29 futile: technomancy: if they're using the clojure api to my app, i bet they've already got clojure installed

12:36 technomancy: lein-exec is a bit silly; you can do the same thing with lein run -m

12:41 last I checked anyway

12:53 futile: technomancy: the goal is to allow the user to have a single file (like a ruby or python script) which they can run somehow on its own, instead of a whole dir tree

12:53 technomancy: i think lein exec provides that, at least given the 4 seconds i spent skimming the page

13:12 TimMc: Well, depending on the user's setup, an uberjar is just that.

13:13 I think you can prepend a shell script to the uberjar file to make it executable from the command line as well.

13:24 futile: how would you debug figuring out why `lein doc` hangs?

13:25 onr: http://nightcode.info/

13:25 futile: onr: exciting isnt it?

13:26 onr: yup

13:55 shdwprince: I'm have IllegalAgrumentException: No implementation of method method1 of protocol protocol1 found for class record1, if protocol inside ns1, and record1 with this protocol1 inside another ns2. If I put protocol1 and record1 inside one ns, everything works. What I'm doing wrong?

14:00 squidz: shdwprince: you probably need to have a paste if you want help

14:02 shdwprince: squidz, I though it's a typical error becose I miss something in docs, but now I see it's not

14:06 kbidarka: squidz, I face something similar as above issue, need help please , here is the link http://pastebin.com/P37uXAXq

14:11 Can I get some help/suggestions on this error I face, http://pastebin.com/P37uXAXq

14:12 jtoy: if i know the exact item in list, waht is the simple way to get the next item in the list and loop around if its at the end?

14:12 I can use any structure to hold the list

14:12 so if i have 1 and the list is [ 1 2 3] and i want 2, if i have 3, i want 1

14:13 futile: technomancy: easier, see? https://github.com/sdegutis/zephyros/blob/tcp/Docs/Clojure.md

14:15 kbidarka: ok, this is the error that I get, IllegalArgumentException No implementation of method: :create of protocol: #'katello.ui/CRUD found for class: katello.Environment clojure.core/-cache-protocol-fn (core_deftype.clj:541)

14:16 jtoy: or is there a simple way to do [1 2 3] [2 3 1] just take first element and add it to the last?

14:18 futile: how do you block the main thread so background threads can work, without killing the cpu (which (while true) does)

14:20 jtoy: i guess i coudl do this:

14:20 &(let [l [ 1 2 3] f (first l) ] (concat (next l)[f] ) )

14:20 lazybot: ⇒ (2 3 1)

14:21 shdwprince: &(conj (vec (rest [1 2 3])) (first [1 2 3]))

14:21 lazybot: ⇒ [2 3 1]

14:22 jtoy: &(concat (vec (rest [1 2 3])) (first [1 2 3]))

14:22 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long

14:26 jtoy: how do I add arguments to a method call, I thought this should word? (apply (+ 1) [2])

14:27 TimMc: jtoy: apply isn't a macro, so that's (apply 1 [2])

14:27 shdwprince: &(apply (partial + 1) [2])

14:27 lazybot: ⇒ 3

14:27 TimMc: What you want is (apply + 1 [2])

14:28 shdwprince: humm

14:28 TimMc: Or that. :-)

14:28 jtoy: I see,I want partial in this case as I am passing in a function with some args but that needs more args later

14:56 futile: only one bug left!

14:57 bhauman: futile: I say that an average of ten times a day.

14:57 futile: has to do with utf-8 and either InputStreamReader or BufferedReader :(

14:57 bhauman: *knonk bug

14:57 *known

14:57 lol

14:57 bhauman: :)

14:58 TimMc: futile: 1. You can block by trying to dereference a promise (or several) that a background thread will deliver; 2. you can .start the background threads and then call .join on them to block on their completion.

14:58 There are other methods, but those come to mind.

14:58 futile: and thanks to samrat, the clojure API is way simpler: https://github.com/sdegutis/zephyros/blob/tcp/Docs/Clojure.md

14:58 TimMc: ah yes, good idea, thanks. @fut it is then.

14:58 *shall be

15:02 TimMc: .start/.join is more obvious to a reader, unless you're actually receiving data from those promises

15:05 futile: TimMc: good point

15:08 so, my server is rightfully sending 35 bytes of utf-8 data, but BufferedReader (which was initialized with an InputStreamReader which was initialized with the string "UTF-8" as the second arg) only gets 30 .read() calls

15:08 what could possibly be causing this?

15:15 arthurmaciel: hello

15:16 I'm very new to clojure and reading about its data-structures I could not figure out the difference between keywords and symbols. Could anyone explain me please?

15:19 wkelly: arthurmaciel: symbols can eval to anything; keywords eval to themselves and have fast equality tests

15:20 arthurmaciel: wkelly: could you please give me an example? 'anything' and 'themselves' are quite abstract to me.

15:22 wkelly: arthurmaciel: in the expression (let [x 1] x)

15:22 arthurmaciel: x is a symbol, right?

15:22 wkelly: x is a symbol, and it evaluates to the value of 1

15:22 arthurmaciel: ok

15:22 wkelly: keywords are kind of a special case of symbols

15:23 arthurmaciel: and is there any example on how to use them? I suppose they'd never be used on the above example, right?

15:23 wkelly: they will never evaluate to anything other than themselves, so they're typically used as keys in maps or

15:23 TimMc: futile: Are you sending only ASCII characters, or are there also multi-byte characters?

15:24 arthurmaciel: wkelly: and could I use symbols as keys in maps too? (sorry about the ignorance)

15:27 wkelly: arthurmaciel: you could, but it would not be idiomatic

15:27 (let [my-map {:keyword1 "value1" 'symbol2 "value2"}] ('symbol2 my-map))

15:27 that will return "value2"

15:28 you'd want to use a keyword there for the fast equality check

15:28 which is also why you'd use a keyword rather than a string, for example

15:30 futile: TimMc: its utf-8

15:30 its crashing on a string with non-ascii utf-8 chars

15:30 TimMc: i figured out why

15:30 i was wrapping my InputStream in an InputStreamReader

15:31 which meant i could no longer rely on the length the server gave me.

15:31 TimMc: *nod*

15:31 futile: so getting rid of it *should* solve that

15:31 but, it means i cant use BufferedReader

15:31 which means i have to roll my own (readline)

15:32 TimMc: Sounds like a solved problem.

15:32 futile: TimMc: no comprendo

15:32 TimMc: As in, someone has probably solved this already.

15:32 futile: ok thought thats what you meant

15:36 jtoy: if i have a function that takes 2 arguments, shouldnt I be able to do (partial ( my_method arg1) arg2) and that is the same as (my_method arg1 arg2)? when i try to do this it thinks i only send 1 argument, im not sure what im oing wrong

15:37 jonasen: jtoy: try ((partial my_fn arg1) arg2)

15:37 TimMc: jtoy: (partial (+ 1)) means "evaluate + with the argument 1, then give the result to partial"

15:38 jtoy: jonasen: i am doing it similar, liek this? (let [method_plus_first (myfn arg1)] ((partial method_plus_first) arg2))

15:38 (myfn arg1) will always be called together in variable, so im not sure how to do this

15:38 shdwprince: (partial method arg1) is something about (fn [arg2] (method *value-of-arg1* arg2)), I'm wrong

15:38 ?

15:39 jtoy: ((partial mthd_plus_arg) arg2)

15:39 TimMc: shdwprince: Close, but the resulting function can take any number of arguments.

15:39 $def partial

15:39 shdwprince: TimMc, shure

15:40 jonasen: jtoy: partial returns a new function. So you need something like (let [methd_plus_first (partial myfn arg1)] (method_plus_first arg2))

15:40 jtoy: jonasen: isnt that th sam as ( (partial myfn arg1) arg2) ) though?

15:40 jonasen: yes

15:41 jtoy: so that should work? hmm, ill test more, i think i am doing taht currently though

15:42 shdwprince: &( (partial + 1 2) )

15:42 lazybot: ⇒ 3

15:45 shdwprince: &(str (char 9829) " lazybot")

15:45 lazybot: ⇒ "♥ lazybot"

15:45 arthurmaciel: wkelly: thanks!

15:45 &(1)

15:45 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn

15:45 arthurmaciel: &1

15:45 lazybot: ⇒ 1

15:45 arthurmaciel: O.o

15:45 shdwprince: &1

15:45 lazybot: ⇒ 1

15:52 vmarcinko: hi, im reading clojure

15:52 joy of clojure in fact, and have one question, nothing important...

15:53 its stated there that to check if collection should be processed further, its idiomatic to use (when (seq coll) ...), and not (when-not (empty? coll) ...)

15:54 why is that idiomatic, because second way seems more intiutive to me?

15:55 LauJensen: Any kind of inspection I do with nrepl-inspect just shows an empty buffer. Are there some common reasons for this?

15:56 futile: ahhh

15:56 so close

16:00 clj_newb_2345: so I'm playing with parsec

16:01 and I want a way to integrate better error reporting, besides line number / column number

16:01 i.e. a way to encode a "stack" of the parsec combinators I'm currently embedded in

16:03 futile: how do you cast an int to a byte?

16:03 ,(byte 226)

16:03 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Value out of range for byte: 226>

16:12 gfredericks: futile: you've got to worry about signed vs unsigned here

16:12 ,Byte/MAX_VALUE

16:12 clojurebot: 127

16:12 futile: thx

16:26 gfredericks: when running the main clojure tests (`mvn test`), does something somewhere rebind #'clojure.test/report?

16:27 vmarcinko: I have no idea. That's one of my top 3 least favorite idioms.

16:27 clj_newb_2345_: can someone point me at a simple example of a defrecord implementing clojure.lang.IFn ? I've been playing with "invoke" and "applyTo", but keep on getting weird errors

16:31 bamford_: People, newbie question: I am trying to implement the webscraper seen in the famous "Video Tour of Go" http://research.swtch.com/gotour in Clojure. What I find difficult is the final revision where it times out after 1 sec. I'm trying the java ExecutorCompletionService but I can't find a way to implement the timeout.

16:32 si14: how would you accept a single HTTP request as a part of a function?

16:32 bamford_: I take results from the ExecutorCompletionService as they come with (.. ecs take get) but how can I implement the 1 sec timeout with this?

16:32 si14: I mean as a part of other workflow, blocking until the request is made

16:33 bamford_: si14: Oh, I simply use (slurp (.openStream (URL. urlstr)))

16:34 and then wrap this in a functiopn

16:34 si14: bamford_: no, the other way around. I need to *receive* a single HTTP request from uther

16:35 as a part of contrived OAuth workflow I open a browser with URL pointing at localhost, and then I need to get an HTTP request with access token in it's GET..

16:35 bamford_: si14: oh I think we're talking about two different things, I was talking about my own question, sry

16:35 si14: don't think that this deserves a full-blown Netty or something like this, I think

16:44 dark_element: How do I tell clojurescript compiler to exclude minifying functions from external libs?

16:46 futile: yay fixed it

16:53 gfredericks: okay CLJ-866 has a test now

16:53 dark_element: you use a somethings file

16:53 externs

16:54 dark_element: gfredericks ok checking

16:55 gfredericks: it's a gclosure feature

16:55 cljsbuild supports it

16:59 dark_element: gfredericks, cljsbuild config looks like this https://www.refheap.com/17182

16:59 gfredericks it's still not working for me. Does it have something to do with Three.js being minified ?

17:05 tieTYT2: i'm trying ot refactor some OO code into some functional code. It's a game and I've got a homing missile attack. This is pretty straight forward in OO because the attack simply has a reference to the target and every tick it recalculates its direction. But how can I do this functionally? I'm thinking the attack data needs a reference to the target. Some kind of key that uniquely identifies

17:05 the target. Is that a good way to design it?

17:08 noonian: is the target a model in a database? or just an object in memory?

17:08 tieTYT2: an object in memory

17:09 isaacbw: what's the paste site that people like here?

17:10 noonian: to do it functionally, you would want your game loop to do something like, (let [new-obj (missile-attack old-obj)] (recur new-obj)), basically instead of updating a reference, you replace it with a new one in the next execution of the loop/function

17:10 tieTYT2: ok but how do I find the old/new object?

17:11 isaacbw: I think it's refheap.com

17:11 refheap.something

17:11 isaacbw: tieTYT2: cool, thanks

17:12 so I wrote this (correct, spoiler alert) solution to project euler #7, which is to find the 10001th prime number, and I'm wondering if anyone would be willing to take a look and maybe give some advice for making it more idiomatic: https://www.refheap.com/17183

17:13 *st

17:13 noonian: i'm not sure how your game is implemented, but if you have an object like (let [my-ob {:hit-points 20}

17:13 (just have your missile-attack fn take its target as an argument, and return a new game-object with the effects applied to it

17:14 isaacbw: or as a bonus, maybe someone could show me how to turn it into a lazy sequence? I haven't wrapped my head around lazy sequences yet

17:14 tieTYT2: yeah but what I don't understand is how do I find the target each tick? I think I need an identifier that is stored in the missile data

17:15 shdwprince: tieTYT2, you'll need to pass every data that should be changed every tick into a function, that loops recursively

17:15 dark_element: gfredericks, ohh my bad. the externs needs to be inside compiler map.

17:15 noonian: yeah, it depends on how the game loop is happening, ideally you could pass an updated list of game objects to each iteration of the loop

17:15 shdwprince: function takes current objects, updates it, and call itself with new values

17:16 chrisrossi: another dumb noob question--how do i get a binary OutputSream that can write to stdout. I'm trying to output binary data.

17:17 tieTYT2: I think i'm asking a more specific question than you guys are answering. Imagine you've got 500 bad guys. How do I figure out between ticks that it was the 5th bad guy that the missile was headed towards?

17:17 isaacbw: check the missile's path against each bad guy

17:17 and you can do some space culling if you want

17:19 chrisrossi: nm. java.

17:19 noonian: you need some sort of physics code to detect when a collision happens, that would probably call a function like (handle-collision object missile), which would maybe dispatch on the type of the second argument and eventually call (missile-attack on the object) or some such, then you would have to search the list of game objects and replace the one that was equal to the old object with the new one or something similar

17:20 shdwprince: chrisrossi, yeah, java, try it's channel

17:26 isaacbw: any style recommendations for my post?

17:26 *paste

17:28 tieTYT2: I said headed towards, not hit

17:29 isaacbw: tieTYT2: do you understand the math to find whether the path intersects a bad guy?

17:29 tieTYT2: tick1: you were headed towards (3,4). Next tick the bad guy changed directions so he's at (4,5). How do I figure out the missile should now be headed towards (4,5)?

17:30 in OO, it's simple. You just give the Missile object a reference to the target. Done

17:30 isaacbw: are you asking conceptually or are you asking how to implement it, because the latter would amount to someone programming your game for you

17:30 tieTYT2: nm

17:31 i'll use an identifier

17:43 dark_element: can i pass compiler flags to cljsbuild ?

17:44 gfredericks: that would surprise me a little bit

17:45 I expect it wants you to put all options in the project.clj and then just specify which build you want

17:47 dark_element: gfredericks I am using three.js which uses ES5 way of defining getters and setters. This breaks externs and closure asks to use laguage_in compiler flag

17:52 gfredericks: dark_element: I think you've surpassed my knowledge on the subject, sorry

17:52 dark_element: gfredericks no problemo.

17:52 gfredericks: at worst you could hop into the cljsbuild code and see where it gets flags from; maybe a pull request if necessary

17:53 dark_element: gfredericks cool

18:00 jtoy: i have a fix for my problem from earlier, but it seems crappy, I was trying to do this earlier: (let [methd_plus_arg1 (partial myfn arg1)] (method_plus_arg1 arg2))

18:01 I just do: (let [method_plus_arg1 [myfn arg1]] (eval (concat method_plus_arg1 [arg2])) ) ; and this works

18:01 is there a better way? it seems bad that i am using eval

18:04 or is it ok the way I am calling this?

18:08 clj_newb_2345: alright, who here is using nightcode?

18:16 alright

18:17 https://gist.github.com/anonymous/c0874137348fac3c3e70

18:17 how do I make that work?

18:17 why can't make my record pretend it's a function?

18:18 turbopape: hi there...

18:18 aside with eclipse + CCW,

18:18 I am giving LightTable a try...

18:18 But I can't fine no licensing,

18:18 will it be open source ? free? commercial ?

18:19 thank you for enlightening my path :)

18:21 clj_newb_2345: it's javascript

18:21 you can always read the code

18:22 well, cljs compiled ot js

18:23 okay, so I just read https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java

18:23 and figured out wtf I was doing wrong

18:23 apparently "&" does not work very well when dealing with java interop

18:24 luxbock: I was trying to look through clojure-mode.el to find out how it replaces `fn' into a pretty f-sign, but couldn't figure out where that actually happens

18:25 any clue how it's done?

18:28 hiredman: it isn't in clojure-mode

18:29 if you are using prelude or emacs live or whatever they tend to do things like that

18:29 luxbock: ah yeah appears to be a part of the starter-kit that I'm using

18:45 isaacbw: anyone know why I might be getting a SocketException in lein repl when I try to run fireplace (foreplay) commands from vim?

18:45 SocketException: socket closed

18:48 soulman: hi

19:36 tried to use a record from another namespace, who's namespace contained a - (as in my-namespace)

19:37 the class cannot be imported, supposedly because the resulting package name is invalid in Java.

19:37 am I right there?

19:57 mattmoss: soulman: Check folder name corresponding to the namespace. Folder name should use underscores where the namespace has dashes.

20:10 soulman: mattross: better to leave the hyphen out in that case

20:12 mattross: it looks a bit strange, if you use the namespace with a hyphen and a line below the same namespace is used as package with an underscore.

20:16 noto2: soulman, some of clojure's package stuff isn't documented that well. I asked here a long time ago about how to access inner classes or enums declared in java code (like what Swing uses a lot); it's OuterClass$InnerEnum btw

20:17 soulman_: TEttinger, yes, i found that out too

20:17 TEttinger: #clojure is responsible for eliminating more of my coding headaches than any other channel

20:18 soulman_: :-)

20:19 I'm quite new to this channel, but clojure eliminates most of my coding headaches with introducing some new headaches ;-)

20:20 as how to handle complex entity graphs with immutable data structures

20:21 Raynes: Github is down. Hide yo wife hide yo kids

20:22 soulman_: I really like zippers for example, but I have not used them on complex graphs

20:23 callen: Raynes: jesus, again?

20:24 Raynes: it was down like a week ago.

20:24 Raynes: callen: Jesus probably didn't do it this time.

20:26 squidz: I heard they\re getting ddos'd

20:26 callen: it's not like they'd ever pay blackmailers, so why bother?

20:27 Raynes: I hate that so much.

20:27 You don't "i heard" something on the internet, man.

20:28 You very clearly read it somewhere you can link somebody to, or a friend in Github told you, but you don't just hear it through the grapevine on the street 5 minutes after it happened.

20:29 squidz: okay I 'read' it

20:30 Raynes: Where did you read it squidz. :P

20:30 Take me to your leader.

20:30 callen: probably on twatter.

20:30 squidz: I read it on reddit

20:31 Raynes: Oh dear

20:31 Must be true.

20:32 callen: I think reddit might actually be a worse source than twatter.

20:32 soulman_: github's back again

20:32 squidz: https://status.github.com/messages

20:44 callen: Raynes: it's always the same hacker news thread when github goes down.

20:45 Raynes: callen: OMG github went down for 5 minutes so what are the alternatives!?!?!?!

20:45 callen: Raynes: EVERYBODY BAIL TO ATLASSIAN'S SHITTY PRODUCT ASAP

20:47 squidz: bit bucket

20:50 clj_newb_2345: what is the easiest way to grab the stack frame at a particular line of code?

20:51 i.e. when a certain line of code is hit, I want to dump the entire stack frame

20:56 chrisrossi: weird, even when writing to System.out, which is a stream, not a writer, something's doing character translation somewhere and corrupting my binary data.

20:58 callen: clj_newb_2345: https://github.com/mmcgrana/clj-stacktrace

20:58 clj_newb_2345: you have access to Google right?

20:58 you're not in a place like China?

21:00 holo: hi

21:05 I'm trying to make `lein cljsbuild test` work, but I got `ReferenceError: Can't find variable: goog`. I followed the advanced example in lein-cljsbuild. error output: https://www.refheap.com/17189 . any idea of any cause?

21:12 timvisher: holo: are you loading up your clojurescript build output in resources/private/html/unit-test.html?

21:13 is there anything like ns-unmap for clojurescript? more specifically, is there anyway to undefine a test in cemerick's cljs.test?

21:14 i keep loading my file in and the tests keep getting added to the registry.

21:14 cemerick: timvisher: clojurescript.test has its own runtime namespaces (since cljs doesn't have them)

21:14 If the test vars in question have the same names, then reloading the file should *replace* prior tests, not be additive.

21:15 timvisher: cemerick: i'll have another go at it

21:15 cemerick: timvisher: You can blow away / modify the "namespaces" directly if you want to: https://github.com/cemerick/clojurescript.test/blob/master/src/cemerick/cljs/test.cljs#L22

21:15 timvisher: i'm executing the tests via C-x C-e on (t/test-ns) if that makes any difference

21:16 holo: timvisher, yes: <script src="../js/unit-test.js" type="text/javascript"></script>

21:16 timvisher: i just ran the tests and got 36 tests

21:17 and reloaded the file and got 44

21:17 with no source changes

21:17 does that sound like an issue i should file?

21:17 reloaded again got 52

21:18 cemerick: ^^

21:18 holo: are you requiring all the goog stuff you're using in the ns?

21:18 cemerick: ack

21:18 timvisher: yeah, that's a bug

21:19 timvisher: holo: i'm pretty darn new to this (2nd day clojurescripting) so i may be completely asking the wrong questions. :)

21:19 cemerick: timvisher: register-test! is conj-ing into a set though, so that's really odd

21:19 timvisher: cemerick: ok. what would be helpful to include in the report?

21:20 cemerick: [com.cemerick/clojurescript.test "0.0.4"]

21:20 holo: timvisher, I made a typo in unit-tests.js in <script>, and it made a different output error, so I guess the build output file was being loaded.. timvisher, I think those goog requires are under the covers. I didn't demand them directly

21:20 timvisher: cemerick: https://gist.github.com/timvisher/6148606

21:20 whoops. :)

21:21 cemerick: timvisher: Just a description will do, at least for now

21:21 timvisher: interesting. i've had a couple goog issues where i had to get explicit in my own ns about using it before it worked. but like i said, i'm green as can be.

21:21 cemerick: timvisher: or, a link to that gist :-)

21:21 holo: timvisher, can you show me such require?

21:21 timvisher: cemerick: cool cool. is there anything obviously wrong with the ns?

21:22 holo: https://gist.github.com/timvisher/6148612

21:23 holo: timvisher, i didn't try to require them, since the example in cljsbuild doesn't do it too, and my own version doesn't add more dependencies

21:23 timvisher: i've had a couple of phantom things going on though that wouldn't stay still so I have no idea how much of what i did was necessary. i was going for the snake slash ninja approach with hissing, know what i mean?

21:23 holo: timvisher, thanks. ok, doesn't hurt to try. thanks!

21:24 axle_512: cemerick: Hey, have time for a cemerick/friend question?

21:24 cemerick: axle_512: depends :-)

21:24 axle_512: cemerick: I've got a webapp using the interactive form workflow w/ bcrypt.

21:24 cemerick: I'm trying to log the last login time in a table

21:25 cemerick: I only want to log that time in my user table if the user successfully authenticates

21:25 cemerick: Is there a best practice to do that? Would I add another workflow function?

21:27 cemerick: axle_512: seems like a reasonable thing to do in your credential fn, or in something you compose around your credential fn

21:28 timvisher: cemerick: I was able to get them all to simmer down using https://gist.github.com/timvisher/6148606#file-reference_test-clj-L36

21:28 thanks for the tip.

21:29 fwiw: the registered-tests all print `#<[object Object]>`. Not sure if they match for equality or not.

21:30 axle_512: cemerick: doh, I see it now

21:30 cemerick: I can write a cred function that invokes your creds/bcrypt-credential-fn internally, etc

21:31 cemerick: thanks for your time, friend :-)

21:32 cemerick: yup :-)

21:33 timvisher: cemerick: issue filed :) https://github.com/cemerick/clojurescript.test/issues/13

21:33 you are a gentleman and a scholar!

21:34 akurilin: Does anybody know where clojure.contrib.seq-utils ended up? Is it still in the 1.2 contribs?

21:35 holo: timvisher. I had a hunch, and replaced optimization :none -> :whitespace, and guess what, it's working! ( ゚ Д゚)

21:35 akurilin: Doesn't look like it made it into modular contribs: http://dev.clojure.org/display/doc/Clojure+Contrib+Libraries

21:36 timvisher: holo FTW!

21:38 callen: holo: derferk.

21:39 holo: callen, you beat google. what does it mean?

21:40 soulman_: cemerick, I suppose you know a bit about class loading? :-)

21:41 I try to change the classpath of a console process

21:41 holo: callen, i got it. no need to explain :)

21:42 soulman_: got the following classloader hierarchy HIERARCHY (#<URLClassLoader java.net.URLClassLoader@5427ee05> #<AppClassLoader sun.misc.Launcher$AppClassLoader@47415dbf> #<ExtClassLoader sun.misc.Launcher$ExtClassLoader@1471cb25>)

21:43 and this URL in the URLClassLoader CL URLS (#<URL file:/home/soulman/devel/workspaces/gitWS/CljLibrary/build/unittest/classes/>)

21:44 but when I try to run the tests I get an error

21:44 Exception in thread "main" java.io.FileNotFoundException: Could not locate org/soulspace/clj/test/string__init.class or org/soulspace/clj/test/string.clj on classpath

21:44 any idea?

21:48 the string__init.class is there, btw

21:50 she_banshee: seriouslly clojure

21:50 whow

21:56 callen: she_banshee: who what?

21:56 soulman_: obviously it's not.

21:57 she_banshee: i was marveling at the sheer genious of the room name

21:58 who else are you talking to, i dont see anyone

21:59 callen: genius of the room name?

21:59 she_banshee: yah

21:59 technomancy: you mean the channel? AOL has rooms.

21:59 soulman_: ls build/unittest/classes/org/soulspace/clj/test/string__init.class

21:59 lazybot: dev etc home media selinux src

21:59 soulman_: build/unittest/classes/org/soulspace/clj/test/string__init.class

21:59 she_banshee: aw two geniuses in the room tonight

21:59 callen: she_banshee: you're aware that Clojure is a programming language and that this is Freenode IRC right?

22:00 she_banshee: nope

22:00 im not thgat smart

22:00 onr: lol

22:00 she_banshee: that*

22:00 callen: she_banshee: there's about 400-500 people in here generally.

22:00 she_banshee: all geniuses im sure

22:00 with big dongs

22:01 callen: she_banshee: you should /nick she_troll

22:01 more truthful labeling.

22:01 she_banshee: brb

22:09 cat got your tounge genius big willy?

22:11 brainproxy: trolling the #clojure channel on a Saturday night.. for fun?

22:12 i mean I could understand it on a Monday or Tuesday night, but Saturday?

22:13 onr: it's monday in some countries

22:14 brainproxy: good point

22:15 jack_rabbit: but seriously, why #clojure?

22:16 onr: easy to troll, obviously

22:19 seancorfield: onr: is it really Monday somewhere? surely only Sunday...?

22:20 I know it's Sunday in Australia right now (always confuses me chatting to my friends downunder since they're all off partying when I'm working Friday and they're all working again while I'm still partying on Sunday :) )

22:21 onr: seancorfield: hehe

22:21 she_banshee: its sunday where im at

22:21 chrisrossi: only if earth has spin 1/2

22:24 seancorfield: Sunday in Bosnia/Herzegovina?

22:25 onr: yes

22:25 in all Europe

22:26 seancorfield: I can't remember what TZ that is... It's about 2am in London I think?

22:26 I should just go look at the world clock site I suppose...

22:26 3am?

22:27 Yeah, 3am in London, 4am in Sarajevo... wow, thought it was further East than that...

22:30 callen: seancorfield: do Clojurians still use the wrappers for the XML configured logging or have people switched to Timbre?

22:33 seancorfield: callen: which wrappers?

22:33 I use tools.logging (and log4j - but that's because our host app was already using log4j)

22:35 callen: seancorfield: I usually use Timbre and I'm considering doing so for a library. Is it worth my time to offer anything other than the usual timbre stuff or should I break out log4j specfically?

22:35 seancorfield: After all the socket.io comments on the mailing list, I should probably report back on using netty-socketio wrapped in Clojure... although we haven't really exercised it at scale yet...

22:36 I'm not familiar with Timbre, sorry.

22:36 callen: seancorfield: you should probably exercise it to see what breaks.

22:36 seancorfield: I've been using http-kit for websocket support, why netty-socketio?

22:38 soulman_: gotcha ClassLoader!

22:38 ;-)

22:39 onr: seancorfield: you're gonna opensource clojure socketio?

22:39 axle_512: man, bitbucket and sourceforge both down. github had outage earlier tonight. DOS attacks galore going on

22:39 seancorfield: callen: we need full Socket.IO on the front end - multiple transports etc

22:39 soulman_: callen, I missed setting the new Classloader as context classloader for the current thread

22:39 callen: seancorfield: It's just weird to me to hear of non-Node.js users using SocketIO

22:40 seancorfield: http-kit is fine for bare WebSocket stuff but that isn't enough for us

22:40 callen: soulman_: why are you fucking with the classloader?

22:40 seancorfield: you just use a flash shim for backwards compat to WS://

22:40 seancorfield: netty-socketio supports WS, Flash and xhr long polling out of the box

22:41 callen: so does http-kit.

22:41 soulman_: because when running from console, the classloader is not a DynamicClassloader here but an AppClassLoader

22:41 callen: although the flash shim just turns into WS://

22:41 soulman_: Java 7 on Ubuntu

22:41 seancorfield: hmm, that wasn't clear from the docs callen... looked like it wouldn't support what we needed...

22:41 anyways, we have the netty-socketio solution in production now :)

22:42 callen: seancorfield: my only real problem with http-kit is the lack of thread affinity, but I'm the only person the world that cares about that.

22:42 seancorfield: we just don't have it enabled on any live sites yet

22:42 soulman_: and I don't konw the complete classpath at start time

22:42 callen: seancorfield: beyond that, it's a wonderful stack.

22:42 more people should use http-kit.

22:42 I'm trying to get yogthos to flip Luminus over to it from Jetty.

22:42 seancorfield: depending on what we see with netty-socketio, we may go back and re-evaluate http-kit but most of our stack is on tomcat right now

22:43 remember we mostly use clojure as the model of an existing (large) web app - this new piece is the first clojure end-to-end server component for us

22:44 callen: yeah I remember your stack being weird.

22:44 seancorfield: if i was building this system from scratch today, i'd approach it very differently than how the existing team had started building it in 2009!

22:44 callen: seancorfield: I was asking about libraries because I'm writing a tracing library for clojure.

22:45 seancorfield: as it is we're slowly picking apart the monolithic web app and trying to turn it into a series of collaborating processes in clojure...

22:45 callen: seancorfield: eventually I'd like to build it out towards something like zipkin with pluggable repeaters like Kafka, but for now...I just want tracing.

22:45 seancorfield: but it will take years given that we have 4M live users on the current app and we need to maintain that while we also take it apart :)

22:45 callen: seancorfield: SOA has the nice property of allowing you to evaluate and swap components out interchangeably without having to have one big migration

22:46 seancorfield: yeah, we have to decouple each internal component to move that way

22:47 As we decouple things so only the truly real-time stuff is in the main web app, we'll have a much nicer architecture and a much faster (and much more scalable) system!

22:47 callen: seancorfield: sounds like a solid direction to head in :)

22:48 seancorfield: I'm currently working at a 100% Python shop. I've been agitating to get us away from Mercurial and Python-all-the-time.

22:55 seancorfield: I was looking to bring Python in to solve our painful ant/shell build script problems!

22:55 But now I think I might just go whole hog on Clojure for that too...

22:57 callen: Raynes: I'm going to start calling you randomly.

22:58 seancorfield: I don't have a good story for scripting in Clojure yet. I still use Python, bash, and make for that.

23:07 supersym: netty-socketio... didn't know there was one, was about to try some http-kit websockets support later this week

23:13 callen: supersym: (pssst use http-kit)

23:14 onr: lol

23:14 callen: onr: lel

23:14 onr: what's valuable about socket.io/sockjs is client-side code

23:15 callen: people shouldn't be coding against an API not really made to be crossplatform.

23:15 onr: callen: btw, just found out your nickname is callEn

23:15 callen: they abandoned non-Node.js users a long time ago.

23:15 onr: sock.js's API is almost identical to websockets

23:16 callen: onr: my nickname is what?

23:16 onr: callen: i wrote to someone named callAn, wondering why you aren't replying :(

23:17 callen: onr: tab completion.

23:17 onr: what did you need?

23:17 onr: callen: just wanted to talk about girls and stuff :P

23:20 callen: onr: no but seriously, what?

23:22 seancorfield: callen: well then i consider it my duty to advocate non-Node.js back ends for Socket.IO! :)

23:22 callen: seancorfield: my point is that it's like being a Mono user.

23:23 seancorfield: the upstream overlords are just going to abuse you at will because they don't care about you.

23:23 seancorfield: I've just been having a conversation about F# so that's very timely :)

23:23 callen: F# is nifty, but I left the .NET world for a reason.

23:23 Most uninspired people I've ever worked with.

23:24 seancorfield: I've never been in the .NET world but I like F# and I think Type Providers are neat.

23:25 Maybe the F# folks could be persuaded to target the JVM? :)

23:25 callen: or we could just use a nice Lisp with good concurrency tooling on the JVM.

23:26 seancorfield: The type inference is nice... and clojure.typed isn't quite "there" yet! :p

23:26 But Type Providers on the JVM that we could use from Clojure would certainly be interesting...

23:27 callen: I'm starting to wonder if I use atoms a lot because they're available, or if I've just left a lot of really unstable software in my wake before I started using Clojure.

23:28 seancorfield: This netty-socketio-based app is the first one where I've used atoms much. Previously I only used them for infrequently refreshed caches.

23:28 Time to go feed the kids. Back later.

23:28 And that's the four-legged variety.

23:28 callen: seancorfield: cheers.

23:28 well I'm using atoms because I want my damn library to be thread-safe.

23:29 I'm not really super-duper interested in using mutexes...so...

Logging service provided by n01se.net