#clojure log - Nov 01 2013

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

0:06 * gfredericks uses flatten

0:08 amalloy: gfredericks: this isn't #clojure-confessions

0:08 keep your filthy habits to yourself

0:09 gfredericks: this is #clojure-confessions

0:09 everybody confess something

0:10 muhoo: forgive me rich, for i have mutated state

0:10 Bronsa: lol

0:10 muhoo: it's been 30ms since my last compile

0:11 brehaut: i dont write tests if i can help it

0:11 amalloy: i'm proud of my complex functions

0:11 brehaut: i like types

0:12 amalloy: yesterday i created a deftype instead of a vector, to hold a two-tuple, because i have an unrelated function that treats vectors specially

0:12 * technomancy barely restrains himself from invoking ~guards

0:12 muhoo: wow, i guess i'm the only one who survived catholic school. you guys are going all #dirtylittlesecrets instead

0:13 technomancy: I, um, actually enjoy elisp even though it's gross.

0:13 muhoo: hahaha

0:14 y'all know this channel is logged, right?

0:14 brehaut: haha

0:14 gfredericks: s/this channel/life/

0:14 muhoo: as for complex functions, i'm not sure that's a confession. ever looked at rich's code for codeq?

0:15 some of those lets are longer than the longest functions i've written

0:15 TimMc: I... I write swearjure.

0:15 muhoo: i have to woner how the hell you debug stuff like that, all that stuff buried inside a let where you can't test it

0:15 gfredericks: I've written (defn update [m k f & args] (apply update-in m [k] f args)) at least ten times

0:16 amalloy: haha

0:16 gfredericks: that's one of ninjudd's favorite functions in useful

0:16 brehaut: muhoo: the secret is not writing bugs to start with

0:16 gfredericks: amalloy: yeah the confession is mostly about not using a utility lib instead

0:16 muhoo: brehaut: right, like linus explaining why he never uses a debugger. because he has no bugs.

0:16 brehaut: exactly

0:17 TimMc: gfredericks: A short-hand for a single key update-in?

0:17 gfredericks: TimMc: yeah

0:17 muhoo: it's so annoying to forget that [] around the k

0:17 you get a lovely "cannot be cast to ISeq" or similar explosion

0:17 gfredericks: sometimes I :refer :all in production code

0:18 but only for honeysql

0:18 muhoo: gfredericks: wow, that's dirty

0:18 whoops, if it's #confessions i suppose i shouldn't judge

0:18 my bad

0:20 i guess my confession is: i suck at maths and have no fundamental understanding of what a factorial is or why it is "hello world" in every good language

0:20 brehaut: muhoo: hello world is the smallest program you can write that ensures you are invoking the compiler correctly and that you have an action occuring

0:21 +, +!

0:24 analognoise: It's an invocation to the programming gods that the most basic components are playing correctly

0:24 A point where you should check you can get to before you do anything else

0:25 The factorial is a function defined recursively, however more importatly it has a closed form solution that most people don't think about

0:25 gfredericks: I just copy-pasted

0:25 analognoise: It's closed form solution is the gamma function + or - 1, iirc

0:25 abaranosky: flatten really does suck

0:26 gfredericks: flatten is the java.util.Date of clojure

0:26 amalloy: haha

0:26 brehaut: i have (def flatten (partial mapcat identity)) in my user.clj

0:26 amalloy: well, except nobody is putting a gun to your head and making you use flatten. unlike Date

0:27 gfredericks: amalloy: weirdest muggers ever

0:41 muhoo: hmm, bishop and liberator seem to have nearly identical api's and functionality. why would i use one vs the other?

1:36 jergason: super noob question about maps: what is the difference between (get map :name) and (:name map)?

1:39 holo: jergason, one difference: the second is smaller

1:51 `cbp: bitemyapp: hi

1:52 bitemyapp: queries are like 90% tested now, still a couple weird cases. But now we're basically only waiting for your connection magic :-) + some cleanup on my part

1:54 ltw: jergason: (map :name) too

1:54 jergason: ltw: whoa neato

1:55 ltw: jergason: although I feel like someone showed me an edgecase for that one

1:56 andyfingerhut: ltw: Perhaps that if key :name is mapped to value nil, it will return nil, the same as if :name was not a key in the map?

1:57 ltw: ,(:foo {:a 1 :b 2})

1:57 clojurebot: nil

1:57 ltw: ,({:a 1 :b 2} :foo)

1:57 clojurebot: nil

1:58 ltw: that's the same in (get {:a 1 :b 2} :foo) as well

1:59 there must be a paranoid accessor for maps?

1:59 Apage43: You can specify a default

1:59 ,(:foo {:foo nil :a 1} ::actually-missing)

1:59 clojurebot: nil

2:00 Apage43: ,(:bar {:foo nil :a 1} ::actually-missing)

2:00 clojurebot: :sandbox/actually-missing

2:02 ltw: Apage43: still, is there nothing that errors by default?

2:04 Apage43: something like (defn get-or-die [in key] (let [sentinel (Object.) result (get in key sentinel)] (if (not= result sentinel) result (throw (ex-info "Key not found!" {:in in :key key})))))

2:06 (but in general no, you're either using clojure's ILookup or the java.util.Map interface, which specify that null/nil is returned for not found)

2:13 technomancy: gfredericks: almost spewed drink over "weirdest muggers ever" thanks

2:15 * Raynes mutters profanity whilst mopping up technomancy's dribble.

2:26 * andyfingerhut finally realizes the power to override arbitrary functions in clojure.core with alter-var-root

2:29 Raynes: And in heaven, an angel dies and his bones fall to earth and become sadness and pain among a civilization.

2:30 All because andyfingerhut used alter-var-root on a clojure.core function.

2:30 andyfingerhut: I'd kill a puppy for this feature.

2:30 I'm a little surprised more libraries don't do this.

2:32 Raynes: I'm going to send you to a base in Antarctica with no internet access if you keep talkin' like dis, man.

2:33 andyfingerhut: OK, I wouldn't kill a puppy for real for this, but why complain about changes to core that you personally like not getting in if you don't have to wait, and don't even have to build your own modified clojure.core to do it?

2:33 I realize that it could cause infinite pain and frustration if misused, but still.

2:35 Raynes: Oh Andy, if you give them this power, I fear they will use it to destroy us! Be careful what you wish for, my friend, I plead!

2:36 andyfingerhut: :-) It's already been given. I just didn't see it before.

2:36 Raynes: Knowledge is power.

2:38 andyfingerhut: Or on a less havoc-causing level, it would be easy for someone to release a library that replaces all core doc strings with others, no changes to core required.

2:51 amalloy: andyfingerhut: isn't that basically what ambrosebs did by releasing some kind of project that adds type information to the functions in core.clj?

2:53 andyfingerhut: If you mean core.typed, my understanding (hearsay only) is that it is a lint-like tool, with no effect during runtime.

2:55 I just grep'd through all contrib libraries, and the only ones I see that use alter-var-root are core.contracts, java.data, tools.namespace, tools.nrepl, and of course tools.trace for implementing its main feature

3:18 mercwithamouth: can someone tell me how to turn on vim keybindings in light table? i'm not seeing it in the docs

3:19 or is it just the basics...saving/quitting?

3:36 Jarda: If I have a function that takes two parameters, like (def foo [item, options] ...)

3:37 and I'd like to pass that to map

3:37 should I do (map (fn [itm] (foo itm opts)) col) ?

3:37 or is there a better way

3:39 andyfingerhut: Jarda: There are almost certainly other ways, but that is clear and correct.

3:40 You could shorten it slightly to (map #(foo % opts) col) if you wish

9:26 silasdavis: mdrogalis, does he ever appear on here?

9:26 I was thinking I could have a go...

9:27 presumably it would just be a case of sucking the docstrings out of 1.5 in the first instance...

9:27 mdrogalis: I haven't see him. He's responsive on Twitter though.

9:27 And the examples.

9:27 teslanick: So maybe there's a right way to do this that's not super-imperative: I have a vector of digits, and I want to create from it a new vector in a particular way. So maybe I want to move index 0 to 4 and 4 to 5 and 5 to 12.

9:28 mpenet: mdrogalis: he is antares or antares_ on freenode I think

9:28 teslanick: I was thinking about creating a mapping object and a function that does the transformation. But it seems like that might already exist somewhere

9:28 silasdavis: so updating those where necessary and copying them to the the 1.5 entries?

9:29 yeoj___, not sure what you mean by a lazy replacement for doall...

9:30 mdrogalis: mpenet: Ah, did not know that.

9:30 jkkramer: silasdavis: mdrogalis: babilen: https://github.com/clojuredocs/web

9:31 mdrogalis: jkkramer: That'

9:31 's the one.

9:32 silasdavis: ah hah

9:32 jkkramer: looks like most of the hard part is done, just the boring web and UI work :)

9:32 silasdavis: perhaps I can make myself useful then

9:33 rather than just being a giant answer spunge

9:35 yeoj___: silasdavis: i did it with for... basically i wasn't interested in side-effects but wanted to eval a sequence (a jdbc resultset) lazily

9:35 silasdavis: i think it worked. i'm going to run it on a million rows and see if my laptop catches fire again.

9:56 tbaldridge: I'm going to assume I'm missing something here. Why on earth was emacs nrepl renamed to cider?

9:56 mdrogalis: tbaldridge: I just started wondering that last week.

9:57 I was told to differentiate between nrepl and nrepl.el

9:57 babilen: mdrogalis: Yes, based on the assumption that the Clojure community at large is more likely to work/support a clojure/clojurescript project than a Ruby one. (nothing else really and no prerequisite at all)

9:57 jkkramer: Ah, thanks :)

9:58 tbaldridge: I'm going to assume I'm missing something here. Why on earth was emacs nrepl renamed to cider?

9:58 bleh, accident repost.

9:58 mdrogalis: tbaldridge is broken D: Someone reset it.

10:35 squidz: does anybody know why dommy doesn't recognize the 'onChange' event. Am I missing something? Or is there a way to create the event if it isn't provided? I don't know enough about javascript to figure it out

10:37 dnolen: squidz: gist please

10:37 squidz: if you adding it via JS event listener handler fn the event is "change"

10:42 silasdavis: is (lazy-cat (rest coll) [(first coll)]) any different to (concat (rest coll) [(first coll)])?

10:43 squidz: dnolen: https://www.refheap.com/20363 here a simplified version

10:46 cemerick: dnolen: it occurs to me that you probably have github notifications off; looking for info @ https://github.com/clojure/clojurescript/commit/b261447e598dd9463ace406337c9f2d1a02bb799#commitcomment-4487530

10:48 dnolen: squidz: sanity check w/ (.addEventListener el "change" (fn [e] (. js/console (log e))))

10:48 cemerick: I get notifications, commented

10:51 cemerick: dnolen: thanks, sorry for the noise

10:52 squidz: dnolen: hmm that seems to do nothing either

10:52 cYmen: Hi guys

10:53 squidz: I used (.addEventListener (sel1 "#power-to") "change" (fn [e] (. js/console (log e))))

10:56 cYmen: I have a LAMP server, how easy is it to replace php with clojure?

10:57 mdrogalis: cYmen: Depends on your situation. I do it here. It's not fun.

10:58 squidz: dnolen: okay using a different target element seems to work, so I suppose something is up with the input element that I was trying to use

10:58 the input is a jqueryUI datepicker so that may have something to do with it

10:59 cYmen: mdrogalis: Damn, then I won't do it.

10:59 How about using ring-clojure and compojure or something like that?

10:59 As long as it is reasonably stable and secure I don't mind not going through apache.

11:02 silasdavis: am I right to think there is no bounds to the memory used by a memoized function?

11:03 squidz: dnolen: clicking on the input brings up a visual datpicker. After clicking on that datepicker the input is changed, so I suppose I may be using the wrong listener type.

11:03 CookedGryphon: silasdavis: use core.memoize

11:03 silasdavis: obviously it is bounded by some function of the number of possibly inputs

11:04 squidz: dnolen: yes, blur seems to do the trick

11:04 silasdavis: CookedGryphon, that's one I'm asking about yep

11:04 CookedGryphon: silasdavis: you can pick your cache type (fifo, lu, ttl, etc) and how big

11:04 jkkramer: cYmen: i've worked on projects that house php and clojure on the same domain, using stuff like apache proxypass

11:04 CookedGryphon: silasdavis: not clojure.core/memoize, but org.clojure/core.memoize

11:04 silasdavis: CookedGryphon, oh...

11:04 cYmen: jkkramer: and your experience with that was...?

11:04 CookedGryphon: separate library, more comprehensive memoization based on core.cache

11:05 silasdavis: ah nice thanks

11:05 jkkramer: cYmen: worked reasonably well

11:06 cYmen: with shared site style, it's pretty transparent to end users

11:06 cYmen: thanks

11:36 akrajan: /set irc.look.smart_filter on

11:36 moratti: quit

11:43 seangrove: dnolen: I'm not sure where the analyzer.clj placeholder tests are in the clojurescript repo, any pointers so I can write tests that verify the default-warning-handler behavior?

11:44 dnolen: Ah, or do you mean the comment block at the bottom of all of the files? :)

12:03 l4u: what's nice about the prefix notation in clojure/lisp? when compared to a pipeline operator

12:04 or -> in clojure

12:12 justin_smith: l4u: prefix is easy to work with in automated ways

12:12 silasdavis: where does sine and cosine live currently?

12:12 justin_smith: ,(Math/cos 1.0)

12:12 clojurebot: 0.5403023058681398

12:13 justin_smith: ,(Math/sin 1.0)

12:13 clojurebot: 0.8414709848078965

12:13 l4u: justin_smith what do you mean by automated ways? any examples?

12:13 justin_smith: l4u: macros, for example

12:13 dnolen: seangrov1: tset/clj/cljs/

12:13 seangrov1: oops, test/clj/cljs/

12:13 justin_smith: -> would have been harder to implement without prefix notation

12:14 seangrove: dnolen: I think undeclared var warnings is turned off by default, isn't it? https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/analyzer.clj#L33

12:15 dnolen: seangrov1: it probably not be, vestige of the early days

12:15 probably should not be

12:16 justin_smith: l4u: also, if you look at a compiler's internal representation for the code (the form it takes before optimization and assembly / bytecode output) pretty much any compiler produces somthing very much like lisp prefix notation (what they call a parse tree), by having a syntax that is closer to that format, programmatic access to the code structure is simpler

12:16 l4u: justin_smith sometimes when I write an expression, i tend to rewrite it with -> operator. because it looks more like unix pipes. is it common or weird?

12:16 seangrove: dnolen: Just wondering why it warns in script/repljs. If I set `:undeclared-var true` in my patch I get a ton of errors, and then it works: https://www.refheap.com/20364

12:17 Maybe something about loading core.cljs?

12:17 justin_smith: l4u: beyond 3 nested calls I like to either make things into intermediate let values (if they deserve names) or break them out to a -> call

12:17 that is normal

12:17 seangrove: I'll track it down, just trying to understand existing behavior

12:18 Ah, :warn-on-undeclared in script/repljs

12:18 l4u: justin_smith ok maybe I should look into let usages thanks

12:21 cemerick: dnolen: is ana/namespaces intended to be read-only from macros, or is it a free-for-all?

12:22 dnolen: cemerick: ana/namespaces is meant to be used by macros, tools, etc.

12:23 cemerick: we could design an api but I really don't see the point

12:24 cemerick: dnolen: yeah, I get that. I'm backing the compiler env into it, and just want to know if it needs to support writes (swap!) or just reads (@).

12:24 I can do both, but the latter is far simpler.

12:25 dnolen: cemerick: I can't see any value in writing to it.

12:25 cemerick: dnolen: that's what I figured as well; we can start with that

12:26 FWIW, only macros should find ana/namespaces useful. External tools will likely have the compiler-env in hand already, and can/should just look there for namespaces information.

12:27 Tools that don't do this will end up getting the same race conditions that the compiler suffers from right now.

12:28 dnolen: cemerick: yep

12:46 vpak:

12:46 .n

12:49 help

12:49 ops sorry just trying to learn irssi

12:50 TimMc: vpak: Commands are prefixed with a "/", such as /quit and /join.

12:50 vpak: :) thanks

12:50 rasmusto: ., .n, a call for help

12:51 vpak: .n

12:51 ./

12:51 .,

12:51 TimMc: Um...

12:51 rasmusto: /join #devnull

12:51 TEttinger: take out the space

12:52 dnolen: this probably only of interesting to people writing extremely perf sensitive JS, but I'm thinking about adding implements?, it is like satisfies? but it doesn't bother with the slow check for natives.

12:52 s/JS/CLJS

12:53 mercwithamouth: how would one go about...populating or creating a key/map from a list of items?

12:53 rasmusto: mercwithamouth: what's the list look like?

12:54 TEttinger: ,(doc into)

12:54 clojurebot: "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."

12:54 TEttinger: (into {} '(:a 1 :b 2 :c 17))

12:54 ##(into {} '(:a 1 :b 2 :c 17))

12:54 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword

12:54 TEttinger: uhhh

12:55 rasmusto: ,(into {} (partition 2 '(:a 1 :b 2 :c 3)))

12:55 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry>

12:55 rasmusto: ,(apply into {} (partition 2 '(:a 1 :b 2 :c 3)))

12:55 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: core$into>

12:55 rasmusto: brb, coffee

12:55 TEttinger: ##(into {} (vec '(:a 1 :b 2 :c 17)))

12:55 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword

12:56 mercwithamouth: rasmusto: just general

12:56 rasmusto: ,(into {} [[:a 1] [:b 2]])

12:56 clojurebot: {:a 1, :b 2}

12:56 mercwithamouth: TEttinger: hmmm

12:57 into.

12:58 ok i'm going to play with that for today...

13:00 dobry-den: What does it mean when this launches when you :require/:import a library? https://dl.dropboxusercontent.com/spa/quq37nq1583x0lf/8oy9dnb-.png

13:00 (a java app)

13:01 Sometimes I get a few of them over the course of a work session

13:01 muhoo: dobry-den: maybe that whomever wrote the library screwed up?

13:01 dobry-den: or something is weird in your setup maybe

13:02 Raynes: muhoo's first suggestion, but not quite as mean.

13:02 dobry-den: it seems to happen with libs that provide a function that pop up a jpanel. like lamina.viz

13:02 Raynes: If you for some reason load javax swing stuff, that happens.

13:03 dobry-den: that's it

13:03 Raynes: Only way to make it not happen is to not load swing stuff or use -Djava.awt.headless=true

13:04 TEttinger: mercwithamouth, herp derp I'm not very good yet

13:04 ##(apply hash-map '(:a 1 :b 2))

13:04 lazybot: ⇒ {:a 1, :b 2}

13:05 muhoo: Raynes: i say that because recently i stupidly forgot to wrap (fn []) around something and the body was exec'ing at compile time. took me a while to figure out what was going on.

13:05 Raynes: :p

13:05 dobry-den: Raynes: i imagine that headless also prevents the graphics from showing up

13:05 Raynes: dobry-den: I don't think that is true.

13:05 But I could be wrong.

13:05 dobry-den: i'll try it out

13:05 Raynes: I'm interested in knowing the answer, so do let me know please. :)

13:06 dobry-den: also, it seems i usually have to run funcs that call swing stuff from a repl outside emacs

13:06 muhoo: there's crap you can do with DISPLAY=:0.0 etc

13:07 fun X tricks: getting GUI windows to show up anywhere you want, even on other machines over ssh, etc.

13:08 dobry-den: lost me at X

13:08 muhoo: Xwindows

13:08 dobry-den: er, fun X

13:09 spacefugitive: hai! Is this a place for noob clojure questions ?

13:09 dobry-den: yeh

13:10 muhoo: dobry-den: if you don't have to dive deep into xwindows, you can consider yourself lucky. then again if you don't have to deal with swing in java, you can probably consider yourself just as lucky.

13:12 spacefugitive: @dobry-den was for me ?

13:12 dobry-den: spacefugitive: yeah just ask m8

13:12 llasram: spacefugitive: Also, no need to @-prefix people's nicks. IRC convention is to just mention people by bare name

13:12 TimMc: muhoo: I <3 X-forwarding.

13:12 spacefugitive: ok thanks :)

13:13 Im trying to run my first clojure program and spec

13:14 dobry-den: muhoo: i never used swing but id like to play with seesaw. unfortunately the last time i tried, iirc it couldnt even require into clojure 1.5.x

13:14 spacefugitive: I am trying to return a hash from a fcn and bind it to a let variable

13:14 (defn init-rover

13:14 [planet]

13:14 ([{:x 0 :y 0 :heading "N"}])

13:14 )

13:14 dobry-den: spacefugitive: if you have some code related to the problem, you can throw it up on refheap.com

13:15 ([{}])

13:16 TimMc: spacefugitive: Let me guess, that throws an arity exception?

13:16 spacefugitive: yeah

13:16 TimMc: ([...]) says "call this vector as a function with zero arguments"

13:16 rasmusto: spacefugitive: it looks like you wrap a map in a vector and then try to call it (without any arguments)

13:16 TimMc: (x y z) almost always means call x with arguments y and z

13:17 [x y z] is the vector of x, y, and z

13:17 So you just want {:x 0 :y 0 :heading "N"} on that line.

13:17 spacefugitive: okay. I kinda want to kind it to a local let vairable ?

13:18 dobry-den: within the function?

13:18 spacefugitive: within the spec

13:18 https://www.refheap.com/20368

13:19 TimMc: Oh, you want the rover to be a map within a vector?

13:19 Just drop that one set of parentheses, then.

13:20 jared314: why are you making it a vector, then destructuring it back into a value?

13:21 dobry-den: maybe it's a budding CES engine

13:21 spacefugitive: okay - thanks!

13:22 jared314 : Thats something I tried to change when I was returning a fucntion that returns a map. I thought it work work somehow.

13:23 jared314: spacefugitive: ah, ok

13:31 dnolen: if anybody wants to get their hands dirty with some impactful CLJS optimizations around protocols I added a bunch of enhancement tickets http://dev.clojure.org/jira/browse/CLJS

13:31 xeqi: cemerick: would you be interested in some PRs to piggieback / austin that will send javascript w/ inline sourcemaps for the repl?

13:33 cemerick: xeqi: you know I would be :-)

13:33 I don't use source maps, but I might if they "just worked".

13:34 xeqi: would you actually need to touch piggieback? It should be pretty darn porous. FWIW, if there's a barrier in there w.r.t. configuring compilation/analysis/etc, I'd much rather eliminate them entirely rather than poking holes for source maps.

13:35 dondani: n00b question: why is 'pr-str' called like that instead of 'pr-string'? the corresponding read function is called 'read-string' after all, right?

13:35 TimMc: I don't think there's a good reason.

13:36 jared314: I would add why is str not called string

13:36 noonian: naming things is hard

13:36 teslanick: That and cache invalidation

13:36 noonian: exactly

13:36 jared314: and what about string? and not str?

13:37 edoloughlin: Does anyone using emacs know how I get the nrepl-server buffer window to scroll automatically with my log output?

13:37 TimMc: Oh, and concurr -- not to mention off-by-one errors -- ency!

13:38 xeqi: cemerick: hmm, I need to pass in a replacement for cljs-eval. It looks like I can do that through (cljs-repl ...), though thats in my server.clj stuff. I'll clean it up and see what happens

13:39 cemerick: TimMc: well done

13:39 xeqi: wow, surprised it requires so much?

13:39 teslanick: TimMc: I had a problem and thought to use threads. has Now I problems. two.

13:40 TimMc: :-)

13:42 cmiles74: I have quick clojure.async question: Is it reasonable to want to call dosync to, say, update a ref from inside a call to go? For instance, update a value if a particular message shows up.

13:43 xeqi: cemerick: well, my current version replaces cljs.repl/evaluate-form in order to generate a source map as part of emit and then append it on whats sent to the browser. I was hoping to pull it up into one of the others since I'm not sure it belongs there

13:44 stuartsierra: cmiles74: Just FYI, "dosync" has nothing to do with "asnyc", despite the name.

13:44 And yes, you can use `dosync` to modify a Ref inside a `go` block.

13:45 xeqi: though then it would require implementing something similar for other repls.. hmm

13:45 cmiles74: stuartsierra: Thank you. :-) Perhaps something else is happening, I'm getting a weird exception when compiling: "No such var: clojure.core/runInTransaction". I was wondering if it was just disallowed. Maybe I have an old version of the library.

13:46 stuartsierra: cmiles74: Don't know what that is. Maybe a bug in the implementation of the `go` macro, which is complicated.

13:47 cmiles74: stuartsierra: I bet it is!

13:47 stuartsierra: One thing I expect you can't do is use any non-blocking core.async operations like <! >! alt! inside a `dosync`.

13:49 cmiles74: stuartsierra: That makes sense. I'm loading an index with data and, when complete, I want to swap out the pointer to the old index with the new... It looks like this bug was, literally, fixed yesterday. http://dev.clojure.org/jira/browse/ASYNC-24

13:49 mlb-: How can I redirect pprint output to a file? Further, how can I format my timbre log output with pprint?

13:49 rasmusto: ,(with-out-str (prn "foo"))

13:49 clojurebot: "\"foo\"\n"

13:50 jared314: rebind *out*

13:51 jcromartie: more specifically, rebind *out* to a Writer that writes to your file

13:51 rasmusto: mlb-: don't know about the second part

13:51 mlb-: jcromartie: ah, I see, cool. Thanks

13:51 jcromartie: like (with-open [w (clojure.java.io/writer "file.clj")] (binding [*out* w] (pprint whatever)))

13:51 stuartsierra: mlb-: Be aware, pprint is very slow compared to regular print. May have an impact on logging.

13:52 mlb-: stuartsierra: No doubt, but I'd find it useful with timbre's "spy"

13:52 stuartsierra: sure

13:57 justin_smith: does partial force the creation of new anonymous functions at runtime? that is to say, is it a performance hit compared to a proper anonymous function if you know how many args are going to come in?

14:00 cYmen: Why is (= 3) => true? Shouldn't that be an error?

14:01 patchwork: cYmen: it is equal to itself

14:01 You can pass any number of args into =

14:01 and it checks the equality of all of them

14:01 Same with < and >

14:02 fizruk: ,(=)

14:02 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$-EQ->

14:02 patchwork: So if you have one arg, it is trivially equal to itself

14:02 ,(= 3 3 3 3 3)

14:02 clojurebot: true

14:02 patchwork: ,(3 3 3 3 3 3 3 4)

14:02 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

14:02 patchwork: ,(= 3 3 3 3 3 3 4)

14:02 clojurebot: false

14:03 cYmen: That sounds like an excuse. :) Equality is just not a unary relation.

14:03 tbaldridge: ,(reduce = [3]) ; would be nasty if this didn't work

14:03 clojurebot: 3

14:03 cYmen: tbaldridge: True...

14:03 amalloy: tbaldridge: well, more like (apply = [3])

14:04 reduce doesn't make any sense for =

14:04 cYmen: ,(apply = [])

14:04 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$-EQ->

14:04 cYmen: Then again...

14:04 patchwork: cYmen: You are expecting strict mathematical equality

14:04 tbaldridge: amalloy: yeah, you're right

14:04 patchwork: clojure has practical equality : )

14:05 It works for any value, not just numbers

14:05 cYmen: I don't know... I consider both (=) and (= 3) to be the same kind of error and would have liked the compiler to catch them.

14:05 patchwork: You can always define your own mathematical equality: (fn [a b] (= a b))

14:05 dnolen: hmm, reiddraper simple-check for testing core.async deadlock?

14:05 patchwork: That will fail for one arg

14:06 TimMc: tbaldridge: I think >2-arity = *uses* reduce.

14:06 justin_smith: (source =)

14:06 TimMc: Oh hmm, not quite.

14:06 liszt: cYmen: I don't know why you have a problem with this.

14:06 justin_smith: ,(source =)

14:06 clojurebot: Source not found\n

14:06 amalloy: TimMc: highly unlikely

14:06 justin_smith: meh

14:06 TimMc: http://clojuredocs.org/clojure_core/clojure.core/=

14:07 amalloy: Yeah, thinko.

14:07 reiddraper: dnolen: that'd be awesome, erlang quickcheck can do some similar things with a tool called PULSE

14:07 cYmen: liszt: It's not a serious problem I just actually made the mistake of missing one argument and it ran fine and gave weird results. :)

14:07 liszt: cYmen: "All of my arguments are equal to one another" is a completely consistent definition of =.

14:07 TimMc: It does it pairwise, anyhow.

14:07 dnolen: reiddraper: would simple-check need tweaking for async testing?

14:08 arun: liszt: (=) => true would have been cool :)

14:08 reiddraper: dnolen: I'd need to dwell on that for a bit, certainly some things you could test with no changes

14:08 liszt: arun: Yep.

14:08 tbaldridge: oh...async simple-check...yes please

14:09 dnolen: reiddraper: k, I've been wanting to do a post on simple-check on my blog, I think demo'ing simple-check for deadlock detection in ClojureScript core.async would be *killer*

14:09 patchwork: arun: Agreed. that would make it fully consistent

14:09 Rich probably has a reason though ; )

14:09 dnolen: reiddraper: it's main source of incidental complexity, and be able to get a minimum sequence of messages would be amazing

14:09 akrajan: ,(+)

14:09 clojurebot: 0

14:10 sandbags: anyone know why cljsbuild would, apparently, lose track of the core Clojure functions like "ref". I'm getting "Use of undeclared Var" errors for core stuff like ref, dosync etc..

14:10 reiddraper: dnolen: right, that's probably going to be nontrivial, but I'll give it some thought. The erlang one works by taking over the scheduler

14:10 akrajan: (=) => true would have served as a identity function

14:10 stuartsierra: Is there any written documentation on CLJS source maps?

14:10 I'm looking for references for our training course.

14:10 amalloy: uhhh, i don't think those exist in cljs, sandbags

14:10 tbaldridge: sandbags: clojurescript is single threaded, why on earth would you need STM?

14:10 patchwork: I feel like it is a zen koan: "Is nothingness equal to itself?"

14:10 sandbags: ah crap

14:11 reiddraper: dnolen: well, actually it rewrites your code, we might could just use a macro for that...

14:11 sandbags: i failed to engage brain

14:11 i didn't notice that all those things were async constructs

14:11 dnolen: stuartsierra: only how to use it - https://github.com/clojure/clojurescript/wiki/Quick-Start

14:11 sandbags: thanks

14:11 `cbp: tbaldridge: can I ask you something?

14:11 dnolen: stuartsierra: and it's not fully baked quite yet - we still need the ability to relative URLs for CJLS + webserver case

14:12 tbaldridge: `cbp: no, never

14:12 `cbp: tbaldridge: :-(

14:12 stuartsierra: dnolen: OK, thanks, good to know.

14:12 dnolen: s/relative/relativize

14:12 tbaldridge: `cbp: go ahead

14:13 `cbp: tbaldridge: On your youtube videos I noticed you sent blocks of code from your source file to your nrepl. How do you do that?

14:13 repl*

14:14 stuartsierra: hah

14:16 tbaldridge: I got it from code I stole from stuartsierra.

14:17 benmoss: does anyone know where clojurescript is supposed to be able to find clojure "1.6.0-master-SNAPSHOT"?

14:17 stuartsierra: `cbp: here it is https://github.com/stuartsierra/dotfiles/blob/8dc9a38e74f7c47927b7a98c0635ce30c303be9a/.emacs.d/local/init.el#L276-L301 but I don't think it works with the new "cider"

14:17 benmoss: http://dev.clojure.org/display/community/Maven+Settings+and+Repositories

14:17 Raynes: stuartsierra: How's things, hair color, etc

14:17 stuartsierra: Raynes: Brown.

14:18 dnolen: benmoss: CLJS doesn't need 1.6, that because of the 1.6 profile in CLJS's project.clj

14:18 Raynes: stuartsierra: You're living on the edge, man.

14:18 `cbp: nice, nice

14:18 tbaldridge: `cbp: yeah it doesn't work with cider. yet, but it's really nice, I don't know why it doesn't come standard with the lib

14:18 dnolen: benmoss: I think you just need to specify the 1.5 profile (i don't know how to do that)

14:18 stuartsierra: SLIME didn't have it either, as I recall.

14:19 tbaldridge: stuartsierra: I don't care who didn't have it. I just want it :-P

14:19 Raynes: Heh, aphyr changed his twitter name to 'Twitter'.

14:19 benmoss: dnolen: hmm, just trying to run "lein test-all" which runs against both profiles

14:19 Raynes: "Retweeted by Twitter"

14:19 stuartsierra: Yeah, maybe I should just submit that to nrepl.el, only now it's all different.

14:19 tbaldridge: I don't know why by default cider would send stuff to the "echo" buffer, or whatever it's called. I love clojure in emacs, I just don't understand it sometimes.

14:20 stuartsierra: tbaldridge: C'mon man, know your Emacsisms! It's "minibuffer."

14:20 dnolen: benmoss: which you don't want or need to do

14:20 benmoss: also `lein test` doesn't do anything yet, there are no compiler infrastructure tests at the moment, only tests for CLJS code itself.

14:21 benmoss: dnolen: gotcha, yeah i was trying to run the test suite to see that i had everything setup before modifying

14:21 dnolen: cemerick: 649, I don't like the sound of more options :)

14:22 cemerick: dnolen: yeah, I don't either really, but :libs is not easy to understand at all. A big part of that is the conflation of two totally different types of entries. *shrug*

14:23 I don't really grok the filesystem case; is it realistic to expect people to enumerate all of their js libs?

14:24 especially with the (hacky, but neat) magic of discovering js libs that have goog.provides and requires in them (but _only_ on the classpath!)

14:24 dnolen: cemerick: I was confused about :libs, it seems you are right that you can specify directories or files. The classpath is the real issue, but people just don't understand this part

14:25 cemerick: everything that's going to be a part of your project needs to be on the classpath

14:25 cemerick: dnolen: you _can't_ specify directories

14:25 stuartsierra: Is it still true in CLJS that you can only catch js/Error and not, say, strings?

14:26 jcromartie: do you think Clojure is modern or postmodern?

14:26 dnolen: stuartsierra: atm the moment yes, been hoping to get some word from Rich about cross platform catch all

14:26 stuartsierra: dnolen: OK, thanks.

14:26 * jcromartie might have gone off the deep end

14:26 cemerick: dnolen: I'm 100% fine with everything needing to be on the classpath. That's how I work, but there's always (apocryphal, AFAICT?) usage of e.g. command-line cljsc by people that don't grok classpath, etc.

14:27 shaungilchrist: jcromartie: postmodern for sure

14:27 dnolen: cemerick: I don't consider educating people about the classpath a problem we need to solve

14:28 stuartsierra: happy to revert the try/catch change until it gets settled, it was low level compiler enhancement in the first place.

14:28 stuartsierra: I'm assuming you're interfacing w/ some lib that throws strings?

14:28 cemerick: dnolen: Yup. Well, if you're up for it, we can put dropping filesystem support for :libs up for consideration at some point in the future...

14:28 stuartsierra: dnolen: It's not a problem for me, this is for teaching.

14:29 dnolen: stuartsierra: gotcha

14:30 cemerick: oh, I haven't look at :libs code, so are you saying it tries both io/resource and io/file or something?

14:30 benmoss: dnolen: now trying to run ./script/test with v8, is the suite pretty instantaneous? seems like nothing is being run. I see "Tested with 1 out of 3 possible js targets", but the whole script takes 136ms

14:30 dnolen: benmoss: v8 is magic

14:31 benmoss: but double checking run time on my machine one moment

14:32 benmoss: takes ~1.3-5 seconds on my machine, so something is up w/ your setup

14:32 benmoss: great

14:35 ah, my core-advanced-test.js is empty

14:38 and that is probably related to "Error: Could not find or load main class clojure.main"

14:39 dnolen: benmoss: did you run the bootstrap script?

14:40 benmoss: er, no

14:40 dnolen: benmoss: ./script/bootstrap

14:40 benmoss: cool, thanks

14:46 cYmen: Hm...how do I tell filter to stop on the first non-match? Basically how do I make (filter #(< % 100) (range)) not run forever? :)

14:47 S11001001: cYmen: use take-while, not filter

14:47 cYmen: thanks

14:47 This may be a good point to ask how to properly search for functions?

14:47 cemerick: gah, that search for js files that contain goog.provide is too clever for anyone's good :-P

14:48 S11001001: cYmen: cheat sheets, source of core.clj

14:48 rasmusto: cYmen: http://clojure.org/cheatsheet

14:48 cemerick: dnolen: Re: filesystem *and* classpath, oooh yes. :libs is gnarly, and I'd very much like to "fix" it, for some definition thereof we can agree on. The system property lookup is the biggest WTF IMO https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/closure.clj#L146

14:48 cYmen: thanks

14:50 cemerick: That'll keep javascript files from being picked up anytime the compiler is running in any env using classloaders for anything, e.g. via pomegranate, in immutant, etc.

14:50 cYmen: Hm...How do I memoize a recursive function?

14:51 justin_smith: cYmen: (memoize (fn f-name [...] .... (f-name ...)))

14:52 cYmen: That works? :o

14:52 justin_smith: yeah, you can give a name to an fn

14:52 S11001001: though you won't get memos for the subcalls

14:52 cYmen: Yeah, but how does it know to replace the inner calls to f-name with calls to the memoized version?

14:52 S11001001: it doesn't

14:52 cYmen: S11001001: ah :)

14:54 I'm not picky...can it be done using declare or something?

14:54 Bronsa: if you def it it should work though (def x (memoize (fn [] .. (x))))

14:54 S11001001: cYmen: I think the obvious way would work

14:54 as Bronsa says

14:56 hiredman: Bronsa: that won't work

14:56 oh, sorry it will

14:56 too fast, I am thinking of defn

15:01 jcrossley3: cemerick: dnolen: there is https://github.com/tobias/dynapath, but ideally clojure/java.classpath would subsume it.

15:01 cemerick: jcrossley3: we don't even need that; it should just be enumerating all resources from the context classloader, done.

15:02 jcrossley3: cemerick: i c

15:04 jkkramer: seancorfield: ping

15:09 Morgawr: http://havamal.morgawr.com/owncloud/public.php?service=files&t=bc281860de4b911431db2e8c628c745d woo finally it arrived :D

15:09 Jarda: dnolen: so I need to actually snail mail the contributor agreement to rich hickey? :)

15:10 dnolen: re: http://dev.clojure.org/jira/browse/CLJS-536

15:11 dnolen: Jarda: yep

15:12 Jarda: ok, so I'll just find me an envelope and drop it in a box. No idea when it might reach rich though :)

15:12 dnolen: cemerick: I don't get understand the point of that code

15:13 Jarda: they processed by Cognitect

15:13 get processed

15:13 cemerick: dnolen: it's walking all jars in the classpath finding javascript files that contain goog.provide and/or goog.require

15:14 going about it in a very failure-prone way, but that's what it's doing

15:14 dnolen: cemerick: yes but I'm confused *why* it needs to do this

15:15 cemerick: dnolen: Hrm, not sure how far up the chain to go. :-) Necessary in order to load javascript libraries via (:require) et al., fold them into optimization, etc.

15:16 dnolen: cemerick: it doesn't seem neccessary for js lib loaded via :require to me.

15:17 cemerick: dnolen: how else would it find the source of the file to fold into optimization given (:require foo.bar)?

15:17 dnolen: cemerick: actual goog libs are organized in dirs based on their namespace

15:17 cemerick: ah

15:18 dnolen: (io/resource "goog/base.js")

15:18 cemerick: sure

15:18 dnolen: cemerick: for everything else you have a direct file ref

15:18 i.e. :libs

15:19 cemerick: dnolen: well, I've taken some non-goog libs and made them goog-capable, but didn't want to disturb the upstream file organization, so the goog.provide discovery was very useful

15:19 I've been going on the assumption that you simply can't expect anything in particular w.r.t. js file/project organization, so the discovery made sense to me when I saw it.

15:19 dnolen: cemerick: this falls into :libs :foreign-libs, I don't see the problem here

15:19 or why we need to walk jars like that

15:21 cemerick: dnolen: :foreign-libs is simply a PITA, and are impossible to distribute with a library to downstream consumers. It's not a useful mechanism except for Application development.

15:22 dnolen: cemerick: ok, it seems to me because of :libs we don't need jar walking

15:22 cemerick: dnolen: you mean, you think direct filesystem references are sufficient?

15:23 dnolen: cemerick: yes, for goog and cljs stuff we already have a sane layout

15:23 cemerick: for other random goog style stuff, :libs does the job

15:23 I see no use case for jar walking except convenience probably best handled elsewhere

15:23 cemerick: gotta stop saying just :libs, since it implies classpath/jar walking :-P

15:25 dnolen: cemerick: sorry I'm not familiar with the closure.clj convenience details, are you saying it walks to jar to attempt to find the lib you specified?

15:26 cemerick: dnolen: ah, also, even libs with goog-style file layout on the classpath aren't loaded based on the name. That only applies to libs shipped as part of Closure itself.

15:26 dnolen: cemerick: like what?

15:27 cemerick: dnolen: i.e. if you put foo/bar/baz.js on your classpath, a (:require foo.bar.baz) would not bring in that js file, even if it had a goog.provide("foo.bar.baz")

15:27 seancorfield: jkkramer: you rang sir?

15:28 dnolen: cemerick: seems like something easily fixed

15:28 cemerick: and it probably should be

15:29 jkkramer: seancorfield: is the vec call here necessary? seems like it prevents results from being processed lazily when :as-arrays? option is given https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L647

15:30 Jarda: hmmm. btw has someone been able to use goog.net.XhrIo to send multipart form posts (file uploads)

15:31 spacefugitive: can someone give me some feedback on my specs - why does it only run my last spec? Should I be writing my specs differently ? https://www.refheap.com/20377 (my first clojure program)

15:32 jkkramer: seancorfield: this was a theoretical concern for me when writing a lib based on java.jdbc, but looks like someone may have run into it for real: http://stackoverflow.com/questions/19728538/clojure-java-jdbc-query-large-resultset-lazily

15:32 seancorfield: jkkramer: that's by design if you ask for arrays - you'd have to check the original JIRA issue for why

15:33 cemerick: dnolen: so you're suggesting: (1) load goog-style js files from where they "should" be on the classpath, (2) make :libs support complete filesystem paths only?

15:33 seancorfield: and remember that by default (query ..) uses doall anyway to realize the result set before the connection is closed

15:34 if you want a lazy result set, you must a) keep your connection open long enough yourself and b) not use as-arrays? - by design

15:35 dnolen: cemerick: yes, the other thing I would like to nuke - walking the directory putting all cljs source into the build.

15:36 cemerick: really we should specify a main file and dependencies should be solved based on the entry point.

15:36 cemerick: ah

15:36 I don't think I have any opinions on that

15:36 dnolen: is there any harm in the sources walk?

15:37 jkkramer: seancorfield: ok, i'll see if i can find the case. that seems less than ideal, though. that means it's impossible to process results lazily AND guarantee preserved column order (or avoid overhead of map processing)

15:37 hiredman: cemerick: there are a lot of assumptions built in to that

15:37 cemerick: hiredman: do enlighten me

15:37 hiredman: cemerick: given ClassLoader, how can that be done efficiently?

15:38 seancorfield: jkkramer: i'm open to tickets / patches offering better alternatives

15:38 dnolen: cemerick: it's just doesn't make much sense, files get revisited over and over again for analysis and compilation

15:38 seancorfield: but remember that (query ..) is generally "atomic" in that you call it (with a db-spec) and you get a result (and the connection is closed)

15:39 cemerick: hiredman: oh, you're talking about the classpath walk?

15:39 dnolen: Yeah, ok. I'll make some issues enumerating the things-to-be-done.

15:39 hiredman: cemerick: it seems to me they are connected, if you have a proper graph of requires you don't walk

15:40 uh, walk isn't the right word

15:40 you don't try and scan everything on the classpath

15:40 cemerick: hiredman: well, I think we just agreed to ditch the classpath walk entirely, and assume goog/java/clojure-style layout

15:41 hiredman: cemerick: ok

15:42 jkkramer: seancorfield: right, understood; i'll look over the issues when i get a chance. so far it's not causing me any problems personally

15:42 hiredman: I don't really clojurescript and people presuming things about classloaders is just a peeve of mine

15:46 loliveira: hi. does somebody know how to use the clause in with clojure.jdbc?

15:46 cemerick: hiredman: then you shouldn't look at what's being done now :-)

15:48 hiredman: cemerick: I avoid looking at things for exactly that reason

15:49 it is just going to upset me, and I don't have enough energy to do anything about it

15:49 jkkramer: seancorfield: even with the default doall for result-set-fn, it's calling (doall (cons (first rs) (vec (map row-fn (rest rs))))), making the vec superfluous, no?

15:49 Jarda: anyone used cucumber with clojure? In my clojure step definition files, should I use atoms for shared state between steps?

15:51 hiredman: I rewrote the clojure part of cucumber-jvm once, because I thought I might use it and made the mistake of looking under the hood, and after rewriting and opening a pr I never ended up using it

15:51 seancorfield: jkkramer: please read the specific JIRA ticket that introduced as-arrays? for the justification for this - users specifically wanted a vector result

15:51 you could argue the doall is superfluous for as-arrays? (but since it can be overridden by users, it could be anything)

15:51 Jarda: hiredman: yeah I'm not interested what's there under the hood :)

15:52 edoloughlin: I upgraded leiningen (2.3.?) and now it's looking for a boot.clj in my classpath. This is a ring/compojure project. How do I tell it to use core.clj? I can't find a reference to boot.clj from google.

15:52 jkkramer: seancorfield: seems like if they want a vector, they can ask for one with :result-set-fn. calling vec explicitly prevents any other choice

15:52 hiredman: Jarda: sure, I am just using it as an example of looking and being upset, and the outcome of that

15:52 wheel spinning and nothing useful

15:54 amalloy: spacefugitive: i'm not familiar with whatever testing lib you're using, but it's probably the case that "it" and "should" are not side-effecting, but just produce a function or something, which describe uses. (let [...] x y z) evals x, then y, then z, then returns z; so unless x and y have some side effects, it's the same as (let [...] z)

15:56 additionally, as a style pointer, it is never the correct style to have a line containing only closing delimiters like ), ], or }: they should all just bunch up together on the same line

15:56 spacefugitive: Thats amalloy , thats very helpful, I figured that was happening since I posted. I am using speclj.

15:56 *Thanks

15:58 ohcibi: hi i want to iterate over a list working with 3 elements in each loop.. so the first loop should use the last, the first and the second element, the second loop the first the second and the third, and so on.. i'm thinking about (map-indexed) and then (get) the neighbors of the current element from the list.. but it feels kinda ugly.. anyone has an idea how to do this "nice"? 8-)

15:58 amalloy: so for your current example, i would just pull the describe inside of both lets, so that it reads (let ... (let ... (describe (it ...) (it ...))))

15:58 which looks like what speclj wants

15:59 algal: Hi. Does anyone happen to know if there's a ring adapter that lets you serve some routes as plain HTTP, while wrapping others in SSL so they are served over HTTPS?

16:00 spacefugitive: amalloy : awesome. Thanks! Also for the style tip !

16:00 algal: The ordinary ring-jetty-adapter seems to be all or nothing, but the underlying jetty library seems to support this by allowing one Server to handle multiple Connectors..

16:00 llasram: edoloughlin: boot.clj isn't a file which is normally handled specially. Something in your project.clj or profiles.clj must be referencing it / a namespsace ending in `boot`

16:00 amalloy: ohcibi: ##(partition 3 1 '(a b c d e))

16:00 lazybot: ⇒ ((a b c) (b c d) (c d e))

16:00 spacefugitive: I was just duplicating my inits - this is much better thanks!

16:01 ohcibi: amalloy: i'm stunned

16:03 amalloy: the two ## are syntax for the bot, right?

16:03 amalloy: indeed

16:05 rasmusto: ohcibi: #(partition 2 1 %) and I are good friends

16:07 Raynes: cemerick: You know, I still have that Postbox bug that causes all of my emails to have your picture attached to them.

16:07 This has been going on for like 8 months.

16:08 cemerick: postbox?

16:08 Raynes: $google postbox email client

16:08 lazybot: [Postbox — Awesome Email] http://www.postbox-inc.com/

16:08 cemerick: Raynes: I'm there with you, always.

16:08 Raynes: It's an otherwise fairly spectacular email client

16:08 But it just really likes to put your face on everything I get.

16:08 amalloy: plot twist: cemerick has hacked your mail client and has been intercepting and re-authoring every message you receive

16:08 cemerick: I wish I were so leet.

16:08 Raynes: Not that your face is unpleasant. It's just that sometimes I like to see other people's faces.

16:08 cemerick: traitor

16:09 bummer its only mac/win

16:09 Raynes: Yeah. It's a nice alternative to thunderbird which is mostly unsupported these days.

16:09 It's actually a fork of it iirc.

16:09 cemerick: oh? Been using thunderbird for some months, updates seem to come along at a reasonable clip.

16:10 TimMc: cemerick: I stopped using Thunderbird when it started corrupting my mail.

16:10 Raynes: "On July 6, 2012, a confidential memo from Jb Piacentino, the Thunderbird Managing Director at Mozilla, was leaked and published to TechCrunch.[27] The memo indicated that Mozilla would be moving some of the team off the project and further development of new features would be left up to the community. The memo was slated for release on July 9, 2012. A subsequent article by the Mozilla Foundation Chair, Mitchell Baker, stated Mozilla's decision to

16:10 make a transition of Thunderbird to a new release and governance model"

16:10 cemerick: ^

16:10 TimMc: Claws is slow and cranky but it stores each email as a separate file.

16:11 amalloy: cemerick: for srs? i've been using thunderbird for years, and for a year or two it's been telling me it's unsupported

16:11 llasram: Emacs gnus 4eva

16:11 muhoo: mutt ftw

16:11 lazybot: Woof!

16:11 muhoo: haha

16:11 seancorfield: jkkramer: as-arrays? returns a completely different format result and was a common enough request that it should be in the library as a native format

16:11 amalloy: haha yes. gotta be the first time anyone's ever triggered that easter egg

16:12 seancorfield: remember: you do not have to use as-arrays? if you want different behavior!

16:12 cemerick: amalloy: dunno, I just get update notifications with all the other ubuntu stuff

16:12 seancorfield: but, yes, one of the key aspects of as-arrays? is guaranteed column order (which is why it needs to be native in the library)

16:12 Raynes: ls

16:12 lazybot: bin boot dev etc lib lost+found opt src swap

16:12 jcrossley3: llasram: +1 for gnus

16:12 jkkramer: seancorfield: i'm not sure how that relates. i prefer to use as-arrays myself, but i don't think realizing *all* results should be necessary to do so. the vec call forces full realization regardless of the :result-set-fn

16:12 Raynes: $botsnack

16:12 lazybot: Raynes: Thanks! Om nom nom!!

16:13 seancorfield: again, (query ..) is deliberatly not lazy by default so that it can manage the connections internally

16:13 you can't return a lazy result and still close the connection

16:13 jkkramer: seancorfield: i understand results must be processed within the scope of the connection, but realizing all results *at once* should not be necessary

16:14 the vec call forces all results to be realized regardless of :result-set-fn

16:14 seancorfield: if you don't want that behavior, don't use as-arrays? and pass in your "work" as a row-fn

16:15 as-arrays? is new behavior, added specifically for users who wanted that behavior

16:16 jkkramer: seancorfield: then you must process maps, which is superfluous work and doesn't preserve order

16:17 zerokarmaleft: ohcibi: looking a bit more closely at the loop you described earlier...I think you actually want something like ##(let [v [:a :b :c :d :e]] (partition 3 1 (take (count v) (drop (dec (count v)) (cycle v)))))

16:17 lazybot: ⇒ ((:e :a :b) (:a :b :c) (:b :c :d))

16:18 edoloughlin: llasram: Thanks. I think there might be a problem with my project config...

16:20 dobry-den: Is there a way to refer to a symbol that has no root binding because it's supplied by the user when the func is invoked?

16:20 or would you just declare nil root bindings for such vars in the ns where such a func exists

16:20 ohcibi: zerokarmaleft: the number of partitions must be equal to the number of elements in the vector, so something is wrong... c,d,e and d,e,a are missing

16:21 dobry-den: for instance, I have funcs that expect *host* and *port* to be bound when they're invoked by the user

16:21 ohcibi: zerokarmaleft: i just (flatten [(last list) list (first list)])

16:21 amalloy: dobry-den: so far everything you've described works fine

16:22 zerokarmaleft: ohcibi: ##(let [v [:a :b :c :d :e]] (take (count v) (partition 3 1 (drop (dec (count v)) (cycle v)))))

16:22 dobry-den: amalloy: I just realized that I believe this is what declare is for

16:22 lazybot: ⇒ ((:e :a :b) (:a :b :c) (:b :c :d) (:c :d :e) (:d :e :a))

16:22 dobry-den: amalloy: (declare ^:dynamic *host*, ^:dynamic *port*)

16:23 amalloy: ohcibi: in many states, using flatten is considered devil-worship

16:23 llasram: dobry-den: Or just `def` 'em to `nil`

16:23 ohcibi: amalloy: how come?

16:23 amalloy: ~flatten

16:23 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

16:24 amalloy: in your example, suppose your list were, instead of '(a b c d e), actually '((a 1) (b 2) (c 3) (d 4) (e 5))

16:25 ohcibi: amalloy: i see your point, but the function that deals with flatten only takes list with atomic elements...

16:26 amalloy: you'd say i should (concat [(last list)] list [(first list)])?

16:26 amalloy: sure, that's a fine choice

16:26 or use cycle and take like zerokarmaleft suggested

16:27 like, why write your function with flatten, which makes your function brittle and forms bad habits, when so many convenient and correct approaches exist?

16:41 TimMc: &(flatten 17)

16:41 lazybot: ⇒ ()

16:43 TimMc: If flatten didn't have that call to rest, I think that would work as expected.

16:43 &(filter (complement sequential?) (tree-seq sequential? seq [[[17]]6]))

16:43 lazybot: ⇒ (17 6)

16:43 TimMc: &(filter (complement sequential?) (tree-seq sequential? seq 17))

16:43 lazybot: ⇒ (17)

16:48 hiredman: flatten is just bad, so don't use it and don't change the behaviour, just leave it laying there rusting

16:49 dead to you as those who use it are dead to me

16:56 stuartsierra: Is there actually a bug in `flatten`?

16:57 hiredman: if you don't use it, does it matter?

17:00 mikerod: sounds like the "if a tree falls in the woods and no one is around, does it make a sound?" argument :)

17:01 ironically, anything the tree falls on would be flattened too

17:04 jared314: i read somewhere you can connect to an nrepl server with telnet. Is this still true?

17:06 justin_smith: jared314: you can, but you have to send a very specific kind of message to make it do anything interesting

17:07 jared314: justin_smith: message format or encoding?

17:07 justin_smith: format, it expects a map literal iirc

17:08 it just disconnects if it doesn't understand what you are sending, no error message

17:08 lein repl :connect is much easier

17:09 jared314: i'm trying trying to write my first nrepl middleware so I actually want to know that format

17:10 i tried a map literal with keyword and quoted strings, nothing

17:11 justin_smith: jared314: https://github.com/clojure/tools.nrepl this page has an example

17:12 {:op "eval" :code "\"hello\

17:12 ")

17:12 hit return too soon

17:13 jared314: tried that first

17:14 it doesn't close, but it doesn't respond either

17:14 does lein repl allow a tty transport?

17:20 justin_smith: jared314: you can launch an nrepl from your app and specify tty

17:20 also, it looks like middleware are expected to take and return those maps with :op and such in them

17:24 algal: Are there any clojure-specific issues to be aware of, when it JVM options for what's supposed to be a long-running ring app?

17:27 justin_smith: set aside plenty of permgen, clojure makes lots of little classes

17:27 there is probably more

17:28 algal: justin_smith: Thanks. I know zero about JVM tuning so every pointer is helpful.

17:34 mikerod: calling `str` on a lazyseq gave me "clojure.lang.LazySeq@f2143067"

17:34 I would have expected that to always cause the lazy seq to be realized instead, hmm

17:36 jared314: mikerod: you need to use apply

17:36 mikerod: actually, I guess that makes no sense, have to seq or something first

17:36 swarthy: @mikerod, @jared314 beat me to it

17:36 mikerod: thanks, makes sense. don't know what I was thinking

17:37 justin_smith: sometimes pr-str works better

17:37 jared314: or just reduce with str

17:37 justin_smith: pr-str has the advantage that it can work on collections or individual values

17:37 ,(pr-str 8)

17:37 clojurebot: "8"

17:37 justin_smith: ,(apply str 8)

17:37 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

17:38 jared314: ,(pr-str (range 1 5))

17:38 clojurebot: "(1 2 3 4)"

17:38 jared314: ,(apply str (range 1 5))

17:38 clojurebot: "1234"

17:38 justin_smith: so yeah, often pr-str is better in my experience

17:38 notofi: Is there a function already for assoc'ing ONE value to a bunch of keys?

17:39 justin_smith: (apply assoc m (interpose keys (repeatedly val))) maybe?

17:40 notofi: . (apply assoc {} (interleave [:a :b :c :d] (repeat 1)))

17:40 , (apply assoc {} (interleave [:a :b :c :d] (repeat 1)))

17:40 clojurebot: {:d 1, :c 1, :b 1, :a 1}

17:41 nightfly: , 2

17:41 clojurebot: 2

17:41 notofi: I thought that maybe there is a function that already does this

17:47 dnolen: ,(zipmap [:a :b :c :d] (repeat 1))

17:47 clojurebot: {:d 1, :c 1, :b 1, :a 1}

17:53 * Raynes cemerick: Hahaha, my lawn. Not bad.

17:53 Raynes: cemerick: I don't have a lawn. Joke is on you.

17:54 cemerick: Raynes: stone frontice, whatever you west-coasters do

17:56 leif-p: I'm trying to figure out how to make batch inserts go faster using c.j.jdbc. Inserting the same rows takes korma < 1s, c.j.jdbc ~50s. Anybody ever run into this, and have a workaround?

17:59 benmoss: is anyone here have vim-fireplace expertise?

17:59 *does

18:01 amalloy: ~anyone

18:01 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

18:02 Apage43: benmoss: I use it

18:02 what up?

18:49 biggbear: (= java.lang.Integer (type 1)) -> false

18:50 mtp: (type 1)

18:50 ,(type 1)

18:50 clojurebot: java.lang.Long

18:54 ta479: is clojure faster than scala for functional programming? Does it do more optimizations with purity?

18:55 mtp: try it and see?

18:55 define "faster"

18:55 define optimization

18:55 what is your workload?

18:56 in short, you are asking a misleading question and i have no context with which to answer

18:56 ta479: no mutating variables

18:56 optimizations done by the compiler when optimizing that

18:57 in scala, lists won't be fused so a double filter takes twice as long as a filter with the predicate fused

18:57 because scalac can't be certain side effects won't factor in

18:58 what's clojure's situation?

18:59 bbloom: that particular optimization is known as "stream fusion"

19:00 clojure's core lazy sequence primitives do chunking, which is a different, but related optimization

19:00 however, the clojure.reducers does something similar to stream fusion & better

19:00 see http://clojure.com/blog/2012/05/08/reducers-a-library-and-model-for-collection-processing.html

19:01 compare with GHC's http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/rewrite-rules.html

19:01 ta479: so do you know if FP clojure is faster than FP scala?

19:01 bbloom: ta479: i won't even attempt to answer that question

19:02 gws: tell me more about imperative clojure

19:02 bitemyapp: ta479: silly question.

19:11 xuser: ta479: Scala is faster obviously, its on pair with Java

19:11 beppu: s/pair/par/

19:12 xuser: beppu: thanks

19:12 ta479: the reason is the Scala compiler generates Java bytecode


19:13 llasram: ...

19:13 Um, what do you think the Clojure compile does?

19:14 compiler, even

19:14 Raynes: xuser: The fact that Clojure code isn't usually compiled ahead of time isn't really a huge performance factor.

19:15 xuser: You can make the Clojure compiler compile to bytecode ahead of time, but it *always* gets compiled to bytecode, even if it is on the fly.

19:15 xuser: llasram: ^^

19:15 was referring to that

19:15 Raynes: It still isn't as big a factor as you think it is.

19:16 cYmen: I'm trying to generate an integer range with end included. Is there something more idiomatic than (range (+ 7 0.1))?

19:16 Raynes: You can write Clojure code that is on par or close to it. The problem is that that code is unpleasant to read, write, and work with a lot of the time.

19:19 xuser: Raynes: oh ok, I though that was huge performance hit actually, the big performance hit is on startup then?

19:20 Apage43: hm

19:20 Raynes: Startup time is a problem, yes, but still not the reason Clojure isn't usually as fast as Java. There are lots of things that go into that.

19:20 Apage43: how can I test if something is a byte array?

19:20 ,(into-array Byte/TYPE [1 2 3])

19:21 clojurebot: #<byte[] [B@1bfc699>

19:21 Apage43: got one of those, want to make sure that's what i have

19:21 Raynes: Reflection (which can usually be eliminated with type hints for sometimes substantial speed improvements), and while persistent immutable data structures are blazing fast, sometimes mutating an array is faster.

19:22 The reason Clojure isn't usually as fast as Java is because people don't want to write the Clojure code necessary to make it as fast as Java, because it tends to chip away at the benefits of using Clojure instead of Java in the first place.

19:23 xuser: Raynes: you mean like non idiomatic Clojure code?

19:23 Raynes: Yes.

19:23 xuser: or calling Java a lot

19:23 bitemyapp: xuser: writing fast Clojure code typically means avoiding clojure.lang.RT and using hot-loops with tight data structures.

19:23 it can end up being on par with or faster than Java at that scope.

19:23 Raynes: dnolen has a blog post on what bitemyapp just said.

19:23 bitemyapp: it won't be faster than java in the more abstract code, but who cares?

19:23 Raynes: And goes as far as to call it 'idiomatic' because all mutation occurs in an isolated environment.

19:24 `cbp: Apage43: type?

19:24 Raynes: And I don't really disagree.

19:24 bitemyapp: I'm meh on that. Haskell users do the same thing and box their mutation in with monads.

19:24 the compiler output is tight either way.

19:24 Raynes: schmir: Piiiiing

19:24 Apage43: `cbp: i went and read byte-streams. It grabs the result of (class (byte-array 0)) and then uses instance?

19:25 =P

19:25 `cbp: ,(= (Class/forName "[B") (type (into-array Byte/TYPE [1 2 3])))

19:25 clojurebot: true

19:26 Apage43: (let [byte-array-class (class (byte-array 0))] (instance? byte-array-class (into-array Byte/TYPE [1 2 3])))

19:26 ,(let [byte-array-class (class (byte-array 0))] (instance? byte-array-class (into-array Byte/TYPE [1 2 3])))

19:26 clojurebot: true

19:26 Apage43: rather

19:26 `cbp: if it works it works

19:26 Apage43: Either works, I guess

19:26 gws: Apage43: http://stackoverflow.com/questions/14796964/how-to-check-if-a-clojure-object-is-a-byte-array

19:27 xuser: Raynes: bitemyapp: thanks

19:27 * Apage43 roundtripping clojure<->erlang data with the erlang JInterface

19:28 * Raynes gives Apage43 a hug.

19:28 Raynes: I'm so sorry.

19:28 Apage43: thx

19:28 `cbp: bitemyapp: hi! You think we could get a release out this weekend?

19:28 Apage43: this is not the first time i've written this >.>

19:28 bitemyapp: `cbp: if my drinking last night doesn't finish killing me, sure.

19:29 `cbp: :-(

19:29 bitemyapp: `cbp: I've got a pretty bad headache. I'm pondering retry logic right now.

19:29 Apage43: but the first time was like > 3 years ago and I don't have it handy anymore

19:31 `cbp: bitemyapp: okies. Most of the rdb api is implemented and passes tests now, just 1-2 with odd results + the time stuff is a bit weird. If you could spare a minute sometime to check those failing tests that'd be awesome

19:31 bitemyapp: `cbp: hum. connections branch or master?

19:31 `cbp: bitemyapp: connections

19:31 bitemyapp: hokey-dokey.

19:33 `cbp: The time stuff fails because it compares 1.2123123123E9 vs 1.2123123123E9 (written)

19:38 xuser: Raynes: bitemyapp: so clojure.jar calls javac?

19:38 Raynes: javac compiles java to jvm bytecode.

19:38 Clojure.jar compiles Clojure to JVM bytecode.

19:38 Java is not an intermediate step.

19:41 xuser: Raynes: so it doesn't really compiles Clojure to JVM bytecode but calls the bytecode in clojure.jar as it parses a clojure source code right?

19:44 S11001001: xuser: it compiles to jvm bytecode

19:46 xuser: for realsies

19:47 xuser: S11001001: interesting, so clojure.jar actually produces java bytecode from java bytecode

19:47 S11001001: it produces java bytecode from clojure source code

19:48 there is no intermediate step!

19:48 llasram: xuser: Try playing around some with ASM

19:48 S11001001: as Raynes and bitemyapp mentioned, slowness typically comes from the fact that the JVM penalizes good practice and rewards bad practice. Everything else is the same.

19:49 xuser: S11001001: yeah, what I mean is the clojure compiler clojure.jar which is in java bytecode is use to produce java bytecode from clojure source

19:50 S11001001: is that right?

19:51 S11001001: xuser: yeah, but javac is no different in that regard

19:51 xuser: llasram: yeah, that would probably help

19:54 bja: I think I need a pending state for my user interface

19:54 something after the user interacts, but before the server responds

19:59 xuser: S11001001: yeah, I though producing the bytecode on the fly was the big performance issue

20:05 S11001001: Raynes: bitemyapp: thanks for clearing up this for me ;)

20:05 allenj12: hey does anyone know a good prop logic library i can use?

20:14 ta479: xuser: I don't think functional scala is very fast. Imperative scala is on par with java but I think clojure does better FP optimization

20:17 xuser: ta479: yeah, I was confused, I though clojure code was interpreted by clojure.jar but clojure.jar is a actually a compiler

20:17 ta479: maybe is has to with the JVM being tuned for Java

20:17 ta479: I don't really care for startup performance, just runtime performance

20:18 xuser: ta479: altough I don't know how much of a penalty is incurred by producing bytecode on the fly, Raynes says is not really much

20:29 ta479: no state of clojure 2013 survey?

20:45 xeqi: ta479: I believe cemerick is planning to do one soon

20:52 bbloom: xuser: it's created on the fly when the code is *loaded* not run

20:53 it's practically zero time for a server application & since most folkss do incremental live coding w/ a repl, it's a total non-issue for all major use cases

20:55 Morgawr: is it possible to have an atom inside an agent? does it make sense to do so? I know agent communication is asynchronous and I have no guarantee on how immediate an action can be performed on an agent (only that it's going to be ordered)

20:55 tbaldridge: Morgawr: everything can be inside everything (when it comes to clojure), but like you said, probably not a good idea

20:55 Morgawr: so I was thinking, since atoms are immediate (as in, not queued), would it make sense to store an atom inside an agent's state and then swap! that atom for instant communication/state-change?

20:57 tbaldridge: the only difference between atoms and agents is that with atoms you atomically change the state of some shared data in a concurrent way

20:57 whereas for agents you have a separate thread change that state, right?

20:58 is there a way to have an agent act like an atom?

20:59 xuser: bbloom: yeah, saw that in http://clojure.org/compilation , thanks

21:03 bbloom: Morgawr: take a step back and describe your goal, not some hypothetical solution to a problem you decided you have :-)

21:03 xuser: bbloom: interesting to see their are plans for a clojure compiler in clojure http://clojure.org/todo

21:04 bbloom: xuser: that's pretty old. clojurescript came out of it & there are several projects in project to produce a selfhosted compiler. Bronsa's is most promising

21:05 seangrove: bbloom: Oh? I thought clojurescript-in-clojurescript was where the selfhosted compiler was most likely to come out of

21:05 Morgawr: bbloom: the idea is that I am designing a situation where I have a lot of independent threads operating on a lot of independent data structures (like the Hickey's ant simulation) and I am using agents to do so

21:05 seangrove: Building on all of Bronsa's work, of course

21:05 Morgawr: agents receive functions to manipulate their data independently in a totally asynchronous way

21:05 however agents have to queue events

21:05 bbloom: seangrove: *shrug* either which way. it's not an official project & the direction is in flux

21:06 biggbear: how to execute multiple tasks in the body of a function "(defn fun [] ((task1)(task2)(tark3)))"

21:06 Morgawr: and sometimes I need to issue "immediate" events (imagine a soft realtime simulation)

21:06 (events are just data transforms)

21:06 bbloom: ah, i see. you have both async AND synch events?

21:06 Morgawr: ideally everything should be async

21:06 so that's not a problem

21:06 but for some stuff (like collision detection for example in a videogame) it needs a fast response

21:06 bbloom: but you want a priority queue?

21:06 seangrove: bbloom: Yeah, I thought it was dead for awhile, and it looks like it's diverged hugely, but the talk he gave a few months back seemed like he had basically done everything (more or less) and intended to try to get it back into master

21:06 Morgawr: bbloom: yes, exactly

21:07 a priority queue is exactly the idea

21:07 like a priority queue for agent events

21:07 bbloom: is your game genuinely multithreaded with concurrent processes like that? what's MUCH MUCH MORE COMMON is to have task parallelism, where you ahve one master thread that does scatter/gather on tasks to workers

21:07 and does things like physics in parallel

21:07 Morgawr: I remember somebody in here wrote this https://gist.github.com/halgari/7028120 when talking to me as a way to emulate clojure agents using core.async, maybe a priority queue with this might be a cool idea

21:08 bbloom: I'm planning to write a "simple" game engine/proof of concept for a fully multithreaded game

21:08 bbloom: usually C++ bases games achieve that sort of thing by block-copying large arrays of data structures & giving each parallel process an isolated world. like "here's all my physics matrices" and "here's all my game state"

21:08 Morgawr: as in, each single entity is an independent agent

21:08 bbloom: you're probably better off having a single thread WITHOUT AN ATOM that's literally just a normal loop w/ the state in it

21:08 then sending off work and having the master thread block for multiple clients

21:09 multiple workers* rather

21:09 instead of trying to shove everything in to atoms or agents

21:09 Morgawr: I'm going for a different approach though, I'm trying to abstract away from the idea of a fixed update loop with a synchronized update step

21:09 (not sure if it's a good idea or not, yet, it's going to be fun)

21:09 trying to follow Hickey's idea that the world shouldn't stop just because we ask it to

21:09 bbloom: well surely your rendering has to be a loop of some kind right?

21:10 Morgawr: agents take care of themselves and then there's two priority threads, one for rendering and one for sending "tick" events to agents

21:10 yeah rendering is its standalone threads

21:10 queries all the agents and runs a rendering function on them

21:10 bbloom: and surely your physics happens on a time step too, right?

21:10 Morgawr: that one I still need to decide, technically yes

21:10 bbloom: so all your game objects are the agents?

21:10 Morgawr: the idea is yes

21:10 all game objects are agents

21:11 some are physical entities too so they are affected by a physics standalone/priority thread (like rendering or updating)

21:11 and I'd need to make sure those entities receive "immediate" (or pseudo-immediate) response

21:11 bbloom: i think you're much better off sticking everything in one big atom & then writing a very simple message dispatch system

21:11 Morgawr: but agents != message dispatch

21:12 agents make sure that the events are executed independently and in an ordered fashion in their own thread

21:12 which is exactly what I want

21:12 bbloom: except it's not, b/c you need to synchronize some message types

21:12 agents embody a queue, but that implies the sender has no control once the message is queued

21:12 Morgawr: the idea is, if I have an agent like (agent { :something 0 :something-else 1 :atom (atom { :data "whatever" }) })

21:12 xuser: bbloom: Bronsa's is this one? http://clojure.github.io/tools.emitter.jvm/

21:13 bbloom: you have some central authority, and so you should implement it explicitly

21:13 Morgawr: then I can retrieve the "atom" compoent of that agent, right?

21:13 bbloom: xuser: https://github.com/Bronsa/CinC

21:13 Morgawr: right, i understand what you're trying to do, but i'm saying you'd be much better off to be able to call deref ONCE and get "the state of the world"

21:13 Morgawr: the state of the world is just composed of multiple independent agents

21:14 bbloom: but what happens when you want to save the world state?

21:14 Morgawr: I mean, I know what you're trying to say bbloom and I agree with you, but I am trying to go in another direction and see what happens

21:14 bbloom: you need to walk each agent & then save it

21:14 you also need to save it's queue

21:14 agents are not magic

21:14 Morgawr: saving the world state is just taking a "snapshot" of the current world

21:14 bbloom: if you need something that is sorta like agents, but isn't, then you can implement your variant

21:14 Morgawr: as in, I don't care about events that haven't been processed yet

21:15 yeah, I guess

21:15 bbloom: but then you're going to get dropped messages, if you save/reload

21:15 which everything will need to account for

21:15 Morgawr: that's a good point, but... does it matter? saving should only save the *current* state of the world and the resume/load function should take care to make it consistent

21:16 bbloom: the question is: are messages in flight part of the world?

21:16 Morgawr: even in traditional game engines you don't just save the current state of the game, you just save a loadable representation of that data

21:16 no

21:16 bbloom: i'd agree with you that their not... but only in a loop-based model

21:16 if you don't have "frames" so to speak, then there is no point in time you can break and say "the world is consistent without queued messages"

21:16 you would never be able to prove that property of your system

21:16 Morgawr: you raise a good point

21:17 bbloom: if you processed all messages every frame, you could discard them all and save the PREVIOUS frame

21:17 Morgawr: the thing is... is it really a problem? answer: I don't really know :V

21:17 bbloom: btw, i make a good point b/c i've implemented save-anywhere in real games before ;-)

21:17 it's hard.

21:17 and holy hell do i wish i had clojure then!

21:17 Morgawr: the thing is, if we wanted to "save" the game then we could broadcast a "save" event to all agents

21:17 once those agents receive that "save" event then we know that they can be shut down

21:17 because agents have ordered events

21:18 hence their event queue has been processed up to that point

21:18 bbloom: how do you know when everybody is done saving? you need coordination

21:18 Morgawr: I mean, it might need to take care of a few thing but that'd be the gist of it

21:18 you drop down to a coordinated model

21:18 as in, you can always read instantly the state of an agent

21:18 you only need to send a message to change its state

21:19 bbloom: what i'm suggesting is that you *start* with a coordinated model, since even if you had 10,000 threads an atom could handle it fine & then you build a simple ansynchronous system on top of that

21:19 it's really quite easy to build some worker loops, especially if you use core.async

21:19 Morgawr: coordinated models are boring :P the idea is to implement a completely abstracted and asynchronous model

21:19 else I'd just go back to normal game development

21:19 I mean, the whole point of this project is to try it out

21:19 and see how it works

21:19 bbloom: Morgawr: that's only interesting if you're going to go DISTRIBUTED

21:20 if you're not distributed, then you should take advantage of the fact that you have shared memory & fast coordination

21:20 you can still program in an asynchonrous model

21:20 but it's one that is controlled by a synchronous overlord... you know, like how your operating system works :-P

21:20 Morgawr: yes and no

21:20 bbloom: real games tend to look a lot like operating systems anyway :-)

21:21 Morgawr: I mean, I totally agree, but still agents help providing a message queue of some sort

21:21 the whole point is, I want to distribute events as actions performed by independent threads

21:21 and not as messages passed around

21:21 there is no "message passing"

21:21 bbloom: what agents do is message passing :-P

21:21 Morgawr: yes but not in the traditional distributed way (like in erlang)

21:22 bbloom: *shrug* ok, don't say i didn't warn you :-)

21:22 Morgawr: but that's beside the point, I get what you mean. I guess I can consider looking at the implementation of agents (or even use core.async) and see if I can implement some sort of priority queue or something similar

21:22 thanks for the good insights btw ;)

21:22 this is just a hobby project

21:22 bbloom: implementing a priority queue with core.async is hilariously easy

21:23 Morgawr: I never personally used core.async but I can read up, I've been done a lot of reading as of lately about it and it's really cool

21:23 bbloom: it's just a loop with a queue argument. then in the loop body you mulitplex on reads from a channel, plus executing what's in the queue. then recur

21:24 good luck!

21:25 Morgawr: thanks ;) going to sleep now, got some good food for thoughts, night

21:29 arrdem: bitemyapp: pig

21:29 bitemyapp: ping

21:51 bitemyapp: arrdem: yes?

21:52 arrdem: bitemyapp: your monad protocol library was...

21:53 oh. fluokitten.

21:55 bitemyapp: arrdem: yissss

21:56 arrdem: also: http://en.wikibooks.org/wiki/Haskell/Monad_transformers

21:56 arrdem: http://www.haskell.org/tutorial/monads.html

21:56 with that, I am heading home.

21:56 arrdem: bitemyapp: starting a new project and your comments about having a single set of basic operations repeated again and again are making me feel bad about my initial design.

21:56 bitemyapp: I didn't want to make you feel bad :(

21:57 arrdem: juuuust...inspire you to seek greatness!

21:57 _scape: I want to be able to use repl within my openGL app, I started an nrepl server within the opengl initialization but realize I cannot access that context still. How would I do this? Here's my error when running openGL functions from repl:

21:57 Exception: class java.lang.RuntimeExceptionRuntimeException No OpenGL context found in the current thread. org.lwjgl.opengl.GLContext.getCapabilities (GLContext.java:124)

21:59 Perhaps I can save the current entry into nrepl to an atom which I can access from the openGL thread, but I don't know how to hook in to nrepl to grab this

22:10 udoprog: Hey, I'm trying to use the following to read all expressions from an PushbackReader; http://pastebin.com/PqDXSrus - however whenever I encounter a comment it just returns the eof character, does anyone know why?

22:11 arrdem: udoprog: is the comment the end of the string?

22:12 udoprog: arrdem: no, I will try to put together a complete example using a ByteArrayInputStream and see if I can encounter the same issue

22:19 akurilin: Am I correctly thinking that list comprehension in clojure is possibly the cleanest way of working with list indexes?

22:19 As in, sometimes you're basing logic on the position of the item in a list

22:19 and you really need that index

22:19 Can I do better than for?

22:29 amalloy: &(doc map-indexed)

22:29 lazybot: ⇒ "([f coll]); Returns a lazy sequence consisting of the result of applying f to 0 and the first item of coll, followed by applying f to 1 and the second item in coll, etc, until coll is exhausted. Thus function f should accept 2 arguments, index and item."

22:30 akurilin: amalloy, oh yeah I remember using that once, good reminder.

23:12 arohner: is there a libraryfn out there for taking an instance of a defrecord, and returning its constructor(s)?

23:12 i.e. (find-constructor Foo) returns ->Foo ?

23:14 _scape: anyone have a link on how to implement a middleware for nrepl? i want to hook in to it

23:17 jared314: _scape: take a look at ritz project's middleware

23:17 _scape: https://github.com/pallet/ritz/tree/develop/nrepl-middleware/src/ritz/nrepl/middleware

23:18 _scape: and the nrepl readme is pretty good

23:18 _scape: thanks jared314

23:18 the readme portion on the middleware didn't make much sense to me actually :-\

23:20 technomancy: nrepl-discover has an example of middleware too

23:21 _scape: thx i'll check it out

23:26 akurilin: So I discovered that caching stuff from DB at boot with def is not fun when running with an empty test database which you populate at a later stage

23:28 Is there a more elegant way to generate unique random integers than by recursively smashing random numbers at a set until it's large enough?

23:31 varlog: hi, i am using pmap to distribute a function over a list. is it possible to identify the particular thread id (e.g. thread 1, 2, 3)

23:36 jared314: arohner: you could look it up by name in the map returned from ns-public

23:37 arohner: jared314: right, and then you need to munge "Foo" into "->Foo" and resolve it. I was just hoping for a library fn

23:38 jared314: arohner: (symbol (str "->" (.getSimpleName (type myinstance))))

23:38 arohner: yeah i don't know one

23:57 amalloy: varlog: you could use a thread-local variable, although in general i would be cautious of anything that cares what thread it is

23:59 eg, if you don't mind depending on useful, you could use https://github.com/flatland/useful/blob/develop/src/flatland/useful/utils.clj#L197 like (let [counter (atom 0), thread-num (thread-local (swap! counter inc))] (defn which-thread [] @thread-num))

23:59 varlog: amalloy: thanks for the tip. Basiclly I am tryig to make sure that each thread calls a different port

23:59 else there will be a logjam

Logging service provided by n01se.net