#clojure log - May 30 2012

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

0:14 johnmn3: how do you conj on to the end of a vec?

0:15 wait

0:18 conj'ing on a vector adds it to the end, right?

0:20 ,(conj (map #(inc %) [1 2 3]) 9)

0:20 clojurebot: (9 2 3 4)

0:21 johnmn3: so it turns into a lazySeq?

0:22 okay, that fixed it

0:56 arohner: johnmn3: conj adds an item to the collection wherever it is fastest. so yes, it adds to the end of vectors, and the beginning of lists & lazy seqs

0:56 johnmn3: k

3:04 squidsoup: hey there, would anyone be willing to share their opinion on web development in clojure? Is Noir generally the most popular framework, or is it considered more idiomatic to assemble libraries like Ring, Hiccup?

3:05 Dvyjones: squidsoup: I don't know what's more common, but I just made something with ring, compojure and enlive, and it seems nice. My app is pretty tiny, though.

3:08 squidsoup: Dvyjones: yeah, from the reading I've been doing that seems to be the 'clojure' way, rather than using a full stack framework. I'm used to Rails, so it's a bit of a departure for me.

3:11 Dvyjones: squidsoup: I'm coming from Rails too, and it is quite a change. It's actually not too tricky once you get started though. All you really lose is the "magic" of, say, routing. So instead of saying "route / to foo-action on bar-controller" you say "route / to call this function".

3:11 squidsoup: Here's my (probably horrible) little app, if you want an example: https://github.com/cluenet/server-list/blob/master/src/server_list/server.clj

3:11 squidsoup: oh cool, thanks Dvyjones

3:18 wei_: johnmn3: yes. pretty sure conj is what you're looking for

3:22 amalloy: noir is a perfectly-acceptable "magic-included" option. personally i prefer to glue together hiccup, ring, and compojure myself, but i don't really have a good reason

3:38 Raynes: squidsoup, Dvyjones: Noir is pretty popular these days. It is a bit higher level than compojure and ring (and is in fact built on them). It has a lot of the bells and whistles you want (validation, encryption, session management, etc) but isn't a "framework" as much as it is a library or set of libraries for easily creating large and/or small websites.

3:39 ejackson: Raynes: can you tell me the difference between a framework and a library ?

3:39 is its simply perfective: you put your stuff in a framework, but you but a library into your stuff ?

3:40 Dvyjones: You call a library, a framework calls you. That's basically how I separate the two.

3:40 ejackson: s/perfective/perspective/

3:40 Dvyjones: (Not completely true, but makes sense to me)

3:40 Raynes: ejackson: Go look at rails and then go look at noir.

3:40 ejackson: yeah, that amkes sense to me

3:40 i've used both

3:41 Raynes: Noir is a libwork. :P

3:41 ejackson: :)

3:41 i was watching bradford cross's vid yesterday

3:42 he was also riding this horse about small, composable abstractions

3:42 and then presented bucket which looked a bit big

3:42 so i'm trying to figure it all out

3:43 so i don't go and do stupid things

3:43 i guess the interface of bucket is 'small' although what it covers is large

3:44 kral: namaste

3:44 ejackson: namaste

3:45 and good luck

4:16 tomoj: can you access the old state in a validator?

4:19 amalloy: &(doc set-validator)

4:19 lazybot: java.lang.RuntimeException: Unable to resolve var: set-validator in this context

4:19 amalloy: &(doc set-validator!)

4:19 lazybot: ⇒ "([iref validator-fn]); Sets the validator-fn for a var/ref/agent/atom. validator-fn must be nil or a side-effect-free fn of one argument, which will be passed the intended new state on any state change. If the new state is unacceptable, the validator-fn should ... https://www.refheap.com/paste/2923

4:19 amalloy: looks like no

4:22 tomoj: well (swap! a #(when-not % (update %))) will work I guess

4:25 clgv: does the metadata ^{:once true} has an effect on the definition of a deftype?

4:25 for repl use I would love to have defonce semantic for a specific deftype

4:25 tomoj: actually

4:25 (set-validator! a (complement (comp deref (constantly a))))

4:26 is that bad?

4:26 besides style.. I couldn't think of a pointy represent I liked..

4:26 s//ation/

4:26 clgv: ^{:once true} seems not to work on a deftype.

4:27 tomoj: you could define deftypeonce as a workaround? :(

4:27 clgv: tomoj: that validator looks weird

4:27 tomoj: what do you want to check?

4:28 tomoj: oh

4:28 (set-validator! a (fn [_] (not @a)))

4:28 clgv: tomoj: try (set-validator! a not) instead

4:29 tomoj: no

4:29 clgv: or is that the old state you want to access?

4:29 tomoj: @a there (in my tests so far) returns the old state

4:29 clgv: ah well...

4:29 tomoj: (def a (atom nil))

4:30 (this could be (atom)..)

4:30 clgv: you want to set the atom only once?

4:30 tomoj: right

4:30 well

4:30 clgv: that sounds like a weird use case for an atom

4:30 tomoj: that actually allows them to reset nil multiple times

4:30 or false

4:30 but I don't cre

4:30 (fn [_] (nil? @a))

4:31 (comp nil? defer (constantly a))

4:31 so how do you do this without an atom?

4:32 hmm

4:32 yeah

4:32 I want my own deftype anyway

4:33 clgv: tomoj: there is promise & deliver

4:33 tomoj: yeah

4:33 cljs has no promise though

4:33 clgv: oh. didn't know you were in cljs.

4:34 you code port promise & deliver to cljs ;)

4:34 tomoj: and I am thinking about non-blocking promises

4:34 so "promise" from clj doesn't really apply

4:34 clgv: ok

4:34 tomoj: cljque has what I want, they seem to use atoms inside

4:35 with (swap! v (fn [[supplied? & _ :as state]] (if supplied? state (conj state f))))

4:35 clgv: tomoj: but you can take the clojure source for promise&deliver as inspiration

4:35 it's pretty easy to read

4:36 tomoj: oh, it uses an atom too

4:36 clgv: yep

4:37 and in clojure 1.3+ you can query whether it is realized...

4:37 tomoj: (compare-and-set! a nil x)

5:48 Dvyjones: How do I conditionally change all values in a map? I want to change "TRUE" values to true, "FALSE" to false, and leave all others. I have this so far: https://gist.github.com/53a6179953dee821e16b

5:48 Basically, I just need to convert ([:foo "bar"] [:bar "foobar"]) back to {:foo "bar" :bar "foobar"}.

5:50 Ah, (into {} ...).

6:08 ordnungswidrig: Dvyjones: there's also fmap to apply map on map values. and the cond can then be replaced with (get {"TRUE" true "FALSE" false} v v)

6:09 Dvyjones: ordnungswidrig: fmap? Doesn't show up in the API docs?

6:11 clgv: Dvyjones: it's probably clojure 1.4

6:13 Dvyjones: it's not fmap I guess - he probably meant reduce-kv in clojure 1.4

6:14 &(clojure-version)

6:14 lazybot: ⇒ "1.4.0"

6:14 Dvyjones: Ah, thanks :)

6:14 clgv: ,(doc reduce-kv)

6:14 clojurebot: I don't understand.

6:15 clgv: &(doc reduce-kv)

6:15 lazybot: ⇒ "([f init coll]); Reduces an associative collection. f should be a function of 3 arguments. Returns the result of applying f to init, the first key and the first value in coll, then applying f to that result and the 2nd key and value, etc. If coll contains no en... https://www.refheap.com/paste/2924

6:15 tomoj: how is IDerefWithTimeout supposed to work in cljs?

6:16 clgv: ,(clojure-version)

6:16 clojurebot: "1.4.0-master-SNAPSHOT"

6:16 clgv: poor bot^^

6:19 tomoj: oh, deref doesn't even call -deref-with-timeout

6:25 clgv: tomoj: yeah. plain deref blocks

6:25 tomoj: err no, in clojure 1.3 it has two arities

6:26 tomoj: cljs, so can't block

6:27 clgv: hmmm this part of the language seems to diverge heavily

6:42 tomoj: in cljs master, the defcurried macro is defined (private) in src/clj/cljs/core.clj, but it is used in src/cljs/clojure/core/reducers.cljs

6:42 is that somehow correct?

6:43 clgv: tomoj: does reducers.cljs have a proper namespace?

6:45 tomoj: yeah

6:45 clojure.core.reducers

6:46 which is where defcurried is defined in clojure itself..

6:46 rkz: cljs reducers? how does that work? webworkers?

6:46 clgv: ok. then I guess all reducers in cljs are macros?

6:46 tomoj: rkz: no, fork/join related stuff is commented out

6:47 rkz: ah but we could hack webworkers in it's place

6:47 if supported

6:49 clgv: tomoj: hmm that source folder is confusing anyway...

6:51 tomoj: rkz: seems so

6:57 rkz: only annoying thing is that webworkers expect a single js file

6:58 cant pass first class function in

6:58 tomoj: hmm

6:59 seems like you could work around

7:00 actually, I dunno

7:00 rkz: i don't know gclosure well enough to figure it out. might have a bash later

7:03 tomoj: couldn't you just send the webworker your compiled js file, with fn.toString() appended to the end?

7:04 or you have to give a url?

7:05 rkz: i think it needs a url

7:05 but hackable to accept a string

7:05 http://stackoverflow.com/a/10372280/44252

7:05 tomoj: oh, http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers

7:07 can you get the source of the script you're in anyway?

8:31 dsrguru: anyone know if there's a way to render hiccup's html output with indentation and whitespace

8:31 rkz: I think that's by design

8:32 dsrguru: I'd like to use the compressed form for production, but it's not very readable while developing

8:32 rkz: dsrguru: you could try to put the output through jtidy

8:34 twhume: Hi. I'm trying to get to grips with gen-class, as per the little tutorial at http://kotka.de/blog/2010/02/gen-class_how_it_works_and_how_to_use_it.html … but when I cut and paste the examples from that page into the REPL, I get an error CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: some.Example, compiling:(NO_SOURCE_PATH:1) ...

8:35 Is there a good beginner's tutorial for gen-class out there which I should refer to instead? Or does this point to a problem with my environment (Eclipse+counterclockwise, Clojure 1.3)?

8:35 dsrguru: rkz: I might do that if there's no builtin way, thanks

8:38 clgv: twhume: do not paste it in the repl but write the source file that is described

8:38 twhume: Thanks clgv. Why does that make a difference? Does gen-class rely on having a source file it can compile, behind the scenes?

8:39 clgv: twhume: I dont think so. but you make sure that the namespace is right.

8:39 twhume: ok, thanks.

8:40 clgv: twhume: what for do you need it? you know the other options?

8:40 twhume: I want to access a class method of ClassLoader from my Clojure code. I was thinking of using gen-class to generate a Java class from Clojure which would expose this method… I guess one alternative would be to use proxy?

8:42 clgv: twhume: so you want to derive from classloader to expose a private method?

8:43 twhume: I'm trying to instantiate a class from an array of bytes; there's a method to do that in ClassLoader. Hmph, why aren't I just instantiating ClassLoader...?

8:43 * twhume kicks self

8:43 clgv: twhume: you may not even need to instanciate one. you can get the contextclassloader from the current thread for example

8:44 * twhume scurries away to the documentation

8:58 twhume: Hmm, so now I have the following class. It throws IllegalArgumentException saying there's no matching method found for defineClass. I've checked the types of each parameter and they match the method signature in the javadocs. Any ideas?

8:58 (defn load-class "" [name bytes]

8:58 (let [cl (ClassLoader/getSystemClassLoader)]

8:58 (. cl defineClass name bytes 0 (int (count bytes)))))

9:02 devn: twhume: please use a pastebin like github gist if you need to post multi-line stuff

9:02 twhume: devn: sure, sorry.

9:02 devn: (or (inline it))

9:10 hoeck1: twhume: defineClass is protected

9:11 twhume: only usable from within derived classes

9:11 twhume: face palm. OK, so I do need to produce a proxy class or similar to override and expose it…

9:22 tomoj: could core.logic relations be made asynchronous?

9:29 dnolen: tomoj: what do you mean?

9:31 matthavener: like a multithreaded eval of a 'q'?

9:31 tomoj: not sure exactly

9:32 I'm vaguely imagining relations operating on future seqs

9:32 dnolen: tomoj: no following :)

9:32 tomoj: (a future seq is an async promise for a cons of an element and another future seq)

9:33 dnolen: matthavener: prototype for that exists in the main repo under fork-join branch

9:33 matthavener: dnolen: oh, awesome, this core.logic stuff continues to blow my mind

9:33 logic programming in general i should say

9:34 tomoj: so (conj fseq 1) is like (deliver fseq [1 (promise)]) where the (promise) is the new tail of the future seq

9:34 but cljs, so you can't block for a promise

9:34 dnolen: tomoj: still trying to understand the "why?" here

9:34 tomoj: I haven't got there yet

9:36 on the top of the why stack is running logic programs on streams of facts and getting a stream of results

9:38 locojay: hi what csv should i use data.csv or clojure-csv?

9:43 tomoj: I only skimmed over TRS

9:43 my thoughts about logic programming are likely incoherent :)

9:43 shouldn't clojure.core.reducers also provide a reduce-kv?

9:44 it seems strange that clojure.core.reducers uses map? to decide whether to reduce-kv

9:47 bobry: i wonder why there's still now 'out of the box' way of converting clojurescript structures to js?

9:47 tomoj: I could just implement IMap (which only requires dissoc) to get core.reducers/reduce to reduce-kv something, but I don't think IMap makes sense for everything reduce-kv is useful for

9:48 dnolen: bobry: there is no sensible conversion

9:49 tomoj: maybe reduce-kv does only make sense for maps

9:49 bobry: dnolen: well, at least maps can be coerced to Objects

9:49 dnolen: bobry: they cannot, complex keys

9:49 bobry: ah, right ...

9:50 I guess I can just use js-obj with a list of k-v pairs :)

9:50 dnolen: bobry: yes, that's what it's there for.

9:51 bobry: thanks!

9:56 mmarczyk: dnolen: ping

10:05 tomoj: suppose (rest coll) returns an IDeref and @(rest coll) returns an ISeq

10:05 is coll broken?

10:05 as an ISeq

10:05 well, yeah, ofc

10:15 hcumberdale: is there a ring cache middleware for cache expiration headers in the response?

10:16 dnolen: mmarczyk: pong

10:17 mmarczyk: dnolen: thanks for setting me straight re: truth_

10:17 dnolen: replying to your comment

10:17 dnolen: ...now

10:17 hcumberdale: ^^

10:18 mmarczyk: dnolen: comment posted

10:19 dnolen: mmarczyk: sounds good!

10:19 mmarczyk: dnolen: great

10:19 dnolen: at some point in the near future I'd like to finish the patch for putting all protocols on the fast path... that could make things easier I think

10:19 dnolen: mmarczyk: you were right about satisfies? not generating truth_ sorry I wasn't clear about that.

10:20 mmarczyk: it's just that the last if of a cond will emit a null breaking boolean inference.

10:20 mmarczyk: dnolen: right

10:21 dnolen: I wonder if cond could special-case truthy literals and just skip the final clause... but that's another issue

10:22 ro_st: should my emacs slime clojure exception stacktrace ever show any locals when i expand a stack item?

10:22 dnolen: mmarczyk: or we perhaps could improve inference - return a set representing the types returned.

10:23 if can remove check if that set is a subset of #{boolean nil}

10:23 mmarczyk: dnolen: that would be great!

10:23 it's pretty amazing how much of a win type inference is

10:24 dnolen: mmarczyk: I'm not totally sure that would eliminate the extra fn.

10:24 mmarczyk: remember that satisfies will be almost always embedded in (if ...)

10:25 mmarczyk: so generated code may be complex enough that Closure won't touch it.

10:25 mmarczyk: this was a big problem with old next, two satisifies? calls was enough for Closure to leave the no arg functions alone.

10:25 mmarczyk: dnolen: incidentally, the most annoying issues for this particular patch come up in connection to (surprise, surprise) the string/String etc. duality -- I have a hunch that that'll be a problem for putting all protocols on the fast path :-(

10:25 dnolen: that is unfortunate

10:26 dnolen: mmarczyk: it just means we have to write better code :) INext simplified many things and made things faster.

10:26 mmarczyk: dnolen: idiomatic code might be a bit carefree when it comes to Boolean expressions

10:26 and the like

10:27 hcumberdale: amalloy_ ^^

10:27 dnolen: mmarczyk: yeah the js/String prototype modification for keyword invocation sucks.

10:27 mmarczyk: dnolen: INext is great, yeah :-)

10:27 dnolen: mmarczyk: been pondering it's removal but I think that would be a bit of work.

10:28 mmarczyk: true about other people being more carefree - doing our own lifting, unwrapping is something we'll get to all in good time I think.

10:29 lynaghk`: ping

10:30 lynaghk`: dnolen: morning, what's up?

10:30 mmarczyk: dnolen: lots of fun to be head in ClojureScript dev for months to come :-)

10:30 dnolen: lynaghk`: did you see Brian Taylor's perf graphs?

10:31 mmarczyk: and years, I'm sure.

10:31 lynaghk`: dnolen: yep, looks pretty boss. It's the direction I wanted to go it but haven't for lack of time

10:32 dnolen: mmarczyk: hah, probably tho I think by the end of this year we will probably run out of the big optimizations :)

10:32 mmarczyk: lynaghk`: looking forward to seeing Clojure JVM as a baseline on those graphs. Would like to show that off at Strange Loop :)

10:32 mmarczyk: dnolen: :-D

10:33 lynaghk`: dnolen: there's plenty of time for that to come together. I'd be happy to build more of an interactive web UI on top of that kind of data too

10:33 dnolen: lynaghk`: that would be sweet!

10:34 mmarczyk: dnolen: we might have some new hosts to worry come end of summer though :-)

10:34 lynaghk`: dnolen: I actually took some time to use my cljs perf stuff to try and profile/optimize some of the C2 internals. I actually ended up splitting the super DOM intesive stuff out into a CoffeeScript lib.

10:34 mmarczyk: ^worry about

10:34 I mean, I'm looking forward to being worried in this way :-D

10:34 hcumberdale: is there a library for this in clojure: http://www.askapache.com/htaccess/apache-speed-cache-control.html#Add_Cache-Control_Headers

10:35 lynaghk`: which, evan did some great work to add cljsbuild support for automatically picking up libs & externs

10:36 mmarczyk: lynaghk`: the split was due to cljs perf being less than handwritten Java/CoffeeScript, right?

10:36 hcumberdale: wrap-file-info does not set cache headers

10:38 lynaghk`: mmarczyk: yes. I rewrote Hiccup in CoffeeScript because the vector traversal was slow. Also the regular expression fns were much slower than native JS, which I was surprised about.

10:39 well, not vector traversal being slow---mostly all of the checks and attribute merging and such.

10:39 dnolen: lynaghk`: ah merging maps?

10:40 brainproxy: anyone familiar with the Conway examples in the Cloj Prog book from O'Reilly, have a min for a question?

10:40 mmarczyk: lynaghk`: would you have the time to put together a list of top pain points? would be worthwhile optimization targets

10:40 dnolen: lynaghk`: regex fns are slower than native JS - in CLJS they return vectors.

10:40 lynaghk`: what mmarczyk said

10:41 mmarczyk: lynaghk`: also, did you switch to arrays for the hiccup-in-coffee? if so, have you tried doing the same thing in cljs?

10:42 lynaghk`: mmarczyk: the latest few commits of my cljs-profile project has the pain points I ran into. There wasn't a single particular thing that stood out aside from the regex.

10:42 mmarczyk

10:42 mmarczyk: yeah, singult (hiccup-in-coffee) takes JS arrays. There's a clojurescript API that just does clj->js conversion and then passes to the coffeescript

10:43 the reason for the port was just because speed was crucial (working on a mobile app), not that cljs was unusably slow in any way.

10:43 mmarczyk: lynaghk`: I wonder if writing hiccup-on-arrays in cljs would be on a similar level perf-wise

10:43 cemerick: brainproxy: Happy to help, but I'll be leaving in a minute. Maybe post the question to the Clojure ML, and one of us can pick it up there?

10:44 dnolen: mmarczyk: lynaghk`: gotta run for a bit. I recommend forking Brian's benchmarks and adding lynaghk's cases so we can investigate.

10:44 lynaghk`: dnolen: cya.

10:44 mmarczyk: dnolen: bye

10:45 lynaghk`: mmarczyk: yeah, it's possible--basically have the first hiccup fn convert its argument to a js array and do all of the manipulation on that?

10:45 mmarczyk: lynaghk`: right

10:45 lynaghk`: or just expect user code to provide args in the form of arrays, or provide for both usage patterns

10:47 lynaghk`: mmarczyk: can't do that--the best part about hiccup is that you just feed it literals

10:48 mmarczyk: Take a look at the diffs of this file to see what I tried for perf improvements if interested: https://github.com/lynaghk/profile-cljs/blob/master/src/cljs/c2_benchmarks/hiccup.cljs

10:48 mmarczyk: lynaghk`: ah, right, you're doing conversion before passing stuff to coffee

10:49 lynaghk`: will have a look, thanks! (in fact, browsing the git log now... will need to finish some other stuff before really diving in though)

10:50 brainproxy: cemerick: sure, mailing list is a good idea; in a nutshell, I've dran conclusion that in cell-block func for the index-free stepper, (window (map vector left mid right)) is equivalent to (window (repeat nil) (map...))

10:50 *drawn

10:50 and I'm wondering if that is correct

10:50 lynaghk`: mmarczyk: yeah, do it to satisfy your personal curiosity only. It's not by any means a blocking issue for us, since I just dropped to CoffeeScript.

10:50 brainproxy: correct conclusion I mean

10:51 mmarczyk: lynaghk`: sure, no worries

10:52 cemerick: brainproxy: Don't know off the top of my head. Been a couple of months since I looked at that code. :-) Definitely post to the list.

10:52 brainproxy: cemerick: cool, will do :)

10:52 mmarczyk: lynaghk`: still, I'd rather you didn't have to do it -- will be interesting to see what can be done about that at this stage

10:52 brainproxy: cemerick: the conway and maze examples are really challening! haven't been challenged by an oreilly book in that way, probably every

10:52 *ever

10:53 cemerick: brainproxy: Those are almost entirely due to Christophe. :-) Glad you're enjoying the book.

10:54 lynaghk`: mmarczyk: there's always going to be some amount of overhead. At least, until you write some kind of insane whole-program optimization stuff that is smart enough to realize that it can use mutable JS-objects here and JS-arrays there.

10:55 borkdude: can you read a version number from defproject inside let's say a core.clj of a leiningen project?

10:55 in an easy way

10:56 hmm

10:56 that would not work if the project was deployed probably

10:56 TimMc: Right.

10:57 You could alter the packaging to add the version to the manifest, though.

10:57 mmarczyk: lynaghk`: in general, sure, but some types of code (explicit use of arrays, fully deducible fn arity stuff etc.) should be very nearly equivalent to JS

10:57 borkdude: TimMc so like this? https://github.com/trptcolin/reply/pull/63#issuecomment-6011538

10:58 TimMc I guess you have to so some ~ expression in defproject?

10:58 SurlyFrog: are `finally` clauses really just used for side effects?

10:58 lynaghk`: mmarczyk: I would love to see your attempt at a hiccup compiler; the algorithm I'm using is pretty simple/understandable (I hope) =)

10:59 TimMc: borkdude: Not sure what the right approach is.

10:59 And uberjar'ing "reply" would probably destroy any manifest info...

10:59 ystael: My project.clj has [org.clojure/clojure "1.4.0"] as a dependency, but both lein-swank and "lein repl" start a version 1.3.0 repl. What might I be doing wrong?

11:00 borkdude: TimMc right, so having a version.clj is probably the best

11:00 SurlyFrog: if a function is passed to `send` or `send-off`, and it ends with a finally clause, can I assume that the agent has been updated before the finally clause runs?

11:01 TimMc: Oh! You could use (load "src/.../version.clj") from project.clj and also load it from something in src/.

11:01 Yeah, that might work...

11:01 mmarczyk: lynaghk`: I'll give it a shot :-)

11:03 borkdude: TimMc you can just put a load before defproject?

11:03 TimMc: I think so.

11:03 Arbitrary code.

11:05 borkdude: ok cool

11:07 dribnet: what do i use instead of map if i have a collection of functions and one piece of data to pass to each?

11:10 TimMc: Why not map? :-)

11:10 Oh, juxt.

11:11 dribnet: (foo [even? odd? big? small?] 3) => [false true false true]

11:11 solve for foo :)

11:11 TimMc: &((apply juxt [even? odd? big? small?]) 3)

11:11 lazybot: java.lang.RuntimeException: Unable to resolve symbol: big? in this context

11:12 TimMc: &((apply juxt [even? odd? pos? integer?]) 3)

11:12 lazybot: ⇒ [false true true true]

11:12 dribnet: Thx TimMc - will try.

11:12 TimMc: ~juxt

11:12 clojurebot: juxt is usually the right answer

11:19 dribnet: thank TimMc, that was it, tho it's a shame I can't (reduce and x) the result :-/

11:22 why does and have to be a macro? that doesn't seem helpful.

11:22 TimMc: dribnet: (and (is-valid? foo) (do-stuff foo))

11:22 Can't do that with fns.

11:23 dribnet: Are these fns predicates?

11:23 There's every-pred.

11:23 dribnet: i just want to reduce a bunch of booleans.

11:23 TimMc: &((every-pred odd? pos? integer?) 3)

11:23 lazybot: ⇒ true

11:24 TimMc: dribnet: If need be, you can (reduce #(and % %2) true my-bools)... but every-pred seems more suited to your needs.

11:25 dribnet: so the answer is: short-circuiting?

11:25 cool - thanks for the every-pred tip.

11:27 yes, every-pred fits the bill. good thing i didn't need or. :)

11:32 borkdude: TimMc https://github.com/trptcolin/reply/pull/64/files

11:32 mwillhite: given I have the following: (update-in {:foo 1 :bar 1} ??? inc)

11:32 borkdude: o shit, forgot to add version.clj :)

11:32 mwillhite: is there anything I can do to update both :foo and :bar?

11:35 TimMc: dribnet: There's also 'some-fn, which is the 'or equivalent.

11:37 borkdude: mwillhite assoc takes more than one key-val

11:37 ,(assoc {:foo 1 :bar 2} :foo 2 :bar 3)

11:37 clojurebot: {:foo 2, :bar 3}

11:38 mwillhite: ideally I could just pass a function in (actually using this to format timestamps), I assume with assoc I'd have to fetch each value as well

11:38 but that is helpful, thanks :)

11:39 borkdude: mwillhite maybe update-in?

11:39 ,(doc update-in)

11:39 clojurebot: "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created."

11:40 mwillhite: yup, "a value"

11:41 tmciver: mwillhite: looks like you'd have to call update-in separately for each update: ##(-> {:foo 1 :bar 2} (update-in [:foo] inc) (update-in [:bar] inc))

11:41 lazybot: ⇒ {:foo 2, :bar 3}

11:41 mwillhite: thx

11:42 borkdude: ,(for [[k v] {:foo 1 :bar 2}] [k (inc v)])

11:42 clojurebot: ([:foo 2] [:bar 3])

11:42 borkdude: ,(apply hash-map (for [[k v] {:foo 1 :bar 2}] [k (inc v)]))

11:42 clojurebot: {[:foo 2] [:bar 3]}

11:42 borkdude: nooooooes

11:43 but sort of that way

11:43 I gtg

11:45 dnolen: mmarczyk: excellent vector perf looking good again :)

11:47 gowlin: sup.

11:52 dribnet: TimMc: what's the easiest way to explode out the my-bools vector so i can pass it to every-pred?

11:58 TimMc: dribnet: You don't pass booleans to every-pred; you give it predicate fns.

11:58 &((every-pred odd? pos? integer?) 3)

11:58 lazybot: ⇒ true

11:59 TimMc: &((apply every-pred [odd? pos? integer?]) 3) ;; alternatively

11:59 lazybot: ⇒ true

11:59 dribnet: TimMc: sorry, my answer was 'apply'. i didn't ask the question right. :)

12:00 TimMc: Mine ends up looking like ((apply every-pred [odd? pos? integer?]) 3)

12:00 TimMc: still much nicer than (reduce #(and % %2) true foo)

12:00 TimMc: yep

12:10 mmarczyk: dnolen: great! :-) new patch w/o enumerated protos attached

12:12 dnolen: mmarczyk: excellent, so we'll leave satisfies? alone for now.

12:12 mmarczyk: dnolen: indeed

12:13 dnolen: mmarczyk: V8 deoptimization is pretty wild. ~470 ms for vector reduce before patch, ~70ms after on my machine.

12:15 mmarczyk: dnolen: yeah, good to be back on the good side of the fence

12:15 dnolen: incidentally, would you have the time to look at cljs-259? "confusion avoidance"

12:16 dnolen: mmarczyk: will take a look

12:16 mmarczyk: dnolen: cool

12:21 dnolen: mmarczyk: both patches applied, thx much

12:21 mmarczyk: dnolen: great, thanks!

12:26 dnolen: mmarczyk: you know PersistentVector/fromArray could be a lot a faster if we just set the tail to the array, if the number of elements is less than 32.

12:28 mmarczyk: no sure if that's the real bottleneck around regex perf but worth investigating.

13:03 mittchel: Hello everyone :)

13:06 devn: cheapest quickest way to get a byte-array from a file input stream?

13:07 gfredericks: (-> is slurp .getBytes)?

13:07 technomancy: nein

13:08 slurp assumes you have a string

13:08 gfredericks: O_O

13:08 I must be crazy

13:08 I swear I've been slurping ring bodies for years

13:09 technomancy: gfredericks: I mean it assumes the contents of its argument will go cleanly into a string

13:09 gfredericks: since most of you were in diapers, presumably

13:09 technomancy: so it's no good for binary data

13:09 gfredericks: oh some bytes do not go cleanly into strings?

13:09 I didn't know strings were so opinionated

13:09 this must have something to do with "encodings"

13:09 technomancy: this isn't ruby =)

13:09 strings are actual strings, byte arrays are byte arrays.

13:10 devn: anyway I'd say copy to a ByteArrayOutputStream and do .toByteArray on that

13:11 TimMc: Make that a fn and call it "blurp".

13:12 devn: TimMc: heh, like expectorate

13:14 p_l: gfredericks: there's no guarantee the modified UTF-16 won't damage the data

13:21 devn: technomancy: like (let [baos (java.io.ByteArrayOutputStream.)] (io/copy "foo.mp3" baos) (take 5 (.toByteArray baos))) ???

13:21 lazybot: devn: Oh, absolutely.

13:21 p_l: actually I'm pretty sure you can get damage from UTF-16 transform

13:21 ...saying UTF transform feels like department of redundancy department

13:21 tomoj: why does folder wrap twice in xf?

13:22 replacing folder with reducer, which only wraps once with xf, for e.g. map seems to work

13:22 wrapping twice seems to work too, which I don't understand

13:39 oh, the extra call to xf is in folder is not the only difference

13:39 coventry`: Can you rely on (rest #{0 1}) and (first #{0 1}) to be consistent, in that the (rest) is the complement of whatever (first) returns?

13:40 I guess under the hood it's converting the set to a seq in both cases, and they do that in the consistent way?

13:41 tomoj: I believe the order depends on the hashcode of the elements?

13:42 technomancy: devn: sure

13:43 McMartin: coventry:

13:43 user=> (.getClass (rest {:a 1 :b 2 :c 3 :d 4}))

13:43 clojure.lang.PersistentArrayMap$Seq

13:44 Seq should be consistent the way HashMap.entrySet().iterator() is.

13:45 TimMc: coventry`: Yes. THe order is arbitrary, but consistent per identical? object.

13:46 McMartin: I'd say for clarity it's probably best to make a seq of it on the way in though and then operate on seqs generally.

13:48 dwierenga: is there a way to pass command-line arguments to my code when i do "lein run" ?

13:49 borkdude: dwierenga: "lein help run"

13:53 tomoj: huh, it seems the CollReduce/IReduce reifies in reducer/folder are indeed equivalent, just written differently

13:55 these are exactly equivalent, right? https://gist.github.com/78d8bcf9f2753e2f85ed

13:57 oh, obviously

14:02 dwierenga: borkdude: yes i read that. i don't actually get the arguments though: http://pastebin.com/EbsbwXta

14:03 devn: stuart halloway's datomic talk at euroclojure was interesting. i did not know you could query your code with it in much the same was you'd query a database.

14:03 https://gist.github.com/2645453

14:14 eggsby: hmm, so I have a list of keys that I want to turn into a list of values by doing a db lookup

14:14 however (map #(db/get my-database-conn %) (list key1 key2 key3)) isn't working

14:14 am I missing something?

14:17 nDuff: eggsby: "isn't working" is pretty vague.

14:18 eggsby: I guess my question is 'how do I take a sequence of side effects and turn them into a list)

14:18 borkdude: dwierenga I think with args you have to also name the ns explicitly?

14:18 nDuff: eggsby: are you saying you want that sequence to be evaluated immediately, rather than lazily?

14:18 eggsby: I can (doseq [key my-keys] (println (db/get my-db key)))

14:19 nDuff: I've tried wrapping it in dorun/doall but no dice...

14:19 raek: eggsby: does the db/get form need to be wrapped in something? you may be bitten by laziness

14:19 nDuff: eggsby: the map thing you're doing there should work fine, as long as you don't expect the db/get calls to be made until the values from the sequence are actually used.

14:19 eggsby: hm

14:20 it just hangs the repl

14:20 raek: if wrapping the map call directly in a doall doesn't solve the problem, then laziness is not the issue here

14:20 nDuff: Hmm. The repl should evaluate it all immediately, at least for a 3-item list.

14:20 raek: eggsby: have you tried just (db/get my-database-conn key1)

14:20 ?

14:20 eggsby: works fine

14:21 just returns the value

14:21 raek: but (doall (map #(db/get my-database-conn %) (list key1 key2 key3))) doesn't?

14:21 eggsby: mhmm

14:22 nDuff: eggsby: is the context for this small enough that you could provide a reproducer (say, on gist.github.com or another pastebin)?

14:22 eggsby: sure, it's the redis-clj lib

14:25 dwierenga: borkdude: i'm not sure how i would do that. you mean with "lein run -m"? that doesn't seem to work unless i'm missing the secret incantation for it..

14:26 borkdude: dwierenga o wait, without m you should just be able to provided the args

14:26 eggsby: https://www.refheap.com/paste/2928

14:27 nDuff: ...'ya know, I personally would be pretty wary about overwriting things as critical as get in your namespace.

14:28 eggsby: I guess I could have an atom and swap the atoms value in the body of a doseq?

14:28 nDuff: ...but anyhow, installing redis to be able to reproduce.

14:28 eggsby: nDuff: ya I require in actual code

14:28 require :as redis or w/e

14:29 dwierenga: borkdude: ok (first args) in main i get a value, but with *command-line-args* i don't: http://pastebin.com/wU436Pz7

14:29 borkdude: dwierenga the args are passed to the -main function

14:29 dwierenga: I think i'm maybe more confused about how to structure my program than i am on how to get the arguments..

14:30 borkdude: I think

14:30 nDuff: eggsby: https://gist.github.com/70ff40a28b400fe9bd73

14:30 eggsby: ...works fine here. That's clj-redis 0.0.12 and clojure 1.4.0

14:30 borkdude: dwierenga I don't know where you got *command-line-args*, I've never seen it before

14:31 dwierenga: borkdude: yeah i get that. i'm just confused as to how to access them from the rest of my program without going straight imperative style..

14:31 borkdude: http://clojuredocs.org/clojure_core/clojure.core/*command-line-args*

14:32 borkdude: ah

14:32 raek: *command-line-args* is filled in when clojure.main is used as the entry point

14:32 eggsby: nDuff: no need

14:32 mfex: eggsby: final ) paren?

14:32 eggsby: I think the issue was in those 'WARNINGS'

14:33 nDuff: Heh.

14:33 eggsby: when I fired up a new repl and used 'require' instead of 'use' it didn't blow up

14:33 * nDuff indeed missed that eggsby's example was just missing close parens.

14:33 dwierenga: raek: so i shouldn't use lein run then?

14:33 eggsby: so map must use get/set/something internally somewhere

14:33 nDuff: eggsby: actually -- I think mfex has it right

14:33 eggsby: you didn't close your parens before pressing enter, so it didn't execute.

14:34 eggsby: nah, wasn't that, I tried )))))))) too

14:34 nDuff: eggsby: ...map is in the clojure.core namespace, so it doesn't care how you redefined get in your local ns

14:34 eggsby: hm

14:34 raek: dwierenga: if you use lein run then your main function is the entry point. use its arguments then

14:34 (defn -main [& args] ...)

14:35 dwierenga: that means i'd need lein installed on my production server then right?

14:36 mfex: eggsby: did you try your code with a closing paren?

14:36 raek: no, you can ahead of time compile that namespace and make it emit a real java main method

14:36 which will call your main function

14:37 you can use the "lein otf" plugin to avoid ahead of time compilation but still get an executable jar

14:37 (well, executable as in "java -jar"-able)

14:38 dwierenga: but i *want* ahead of time compilation, no?

14:38 McMartin: Does the uberjar really use all the vast number of clojure-core-library classes?

14:39 raek: as the last step, yes

14:39 it gets in the way during interactive development though (.class files can shadow your updated source files)

14:42 dwierenga: raek: i have no idea what that means, sorry. i'm coming from Perl-land where there's no difference between source and executable..

14:47 eggsby: clojure has a string split somewhere, right?

14:48 McMartin: I'd check in clojure/string

14:48 mfex: ,(doc clojure.string/split)

14:48 clojurebot: "([s re] [s re limit]); Splits string on a regular expression. Optional argument limit is the maximum number of splits. Not lazy. Returns vector of the splits."

14:48 eggsby: thanks McMartin mfex

14:50 awesome

14:51 McMartin: Note that if you want to do the reverse, (clojure.string/join "" v) is roughly equivalent to (apply str v).

15:41 timvisher: how do i control the version of clojure lein repl uses outside of a project?

15:42 amalloy: timvisher: probably in ~/.lein/profiles.clj, but i dunno

15:42 timvisher: i'm on 1.7.1 at the moment, too

15:42 amalloy: thanks

15:43 amalloy: oh. then not in that file, which is for lein2

15:43 gtrak`: what's the state of the art in debugging? ritz? cdt?

15:43 yazirian: println

15:43 amalloy: gtrak`: probably ritz

15:44 raek: timvisher: I don't think you can in 1.x

15:44 timvisher: you know, i don't think you can configure it

15:44 lol

15:55 nDuff: If I have two sequences '(1 2 3 ...) '(:a :b :c ...), what's the standard mechanism to get a sequence returning '((1 :a) (2 :b) (3 :c) ...)?

15:55 gtrak`: zipmap

15:55 * nDuff would have hoped he'd know the sequence library well enough by now to not be asking these questions, but sadly...

15:55 clojure-newcomer: hi guys… can anyone help ? I am falling into a newb lazy seq trap : http://pastebin.com/WgYAd48k

15:55 nDuff: ahh, graci.

15:56 mfex: ,(map list '(1 2 3) '(:a :b :c))

15:56 clojurebot: ((1 :a) (2 :b) (3 :c))

15:57 clojure-newcomer: I'm getting : 'clojure.data.xml/Emit found for class: clojure.lang.LazySeq' when I try to emit-str

15:57 gtrak`: ah, same shape as zipmap, with a subtle difference, my mistake :-). zipmap would give you the same thing but possibly in a different order

15:57 timvisher: well, is it possible to control the version of clojure from lein2?

15:57 clojure-newcomer: I figure I need to realise the lazy seq, but am unsure how to do it

15:57 nDuff: timvisher: yes, in your project.clj

15:58 timvisher: ...just make the dependency be the one you want.

15:58 timvisher: outside of a project

15:58 duck1123: timvisher: why not just lein new up a project?

15:58 timvisher: :)

15:58 i'm using it for inferior lisp when i don't really want a project

15:58 basically it's quicker than starting a whole new project and then jacking in

15:58 S11001001: timvisher: running low on disk space?

15:58 mfex: nDuff, gtrak`: zipmap builds a (hash)map, not a list and therefore has no ordering

15:58 timvisher: S11001001: lol

15:58 time

15:59 gtrak`: mfex: it has an ordering... but probably not the one you want

15:59 S11001001: so do it once and use that over and over

15:59 gtrak`: maps are seqs

15:59 texnomancy: timvisher: it's locked to Leiningen's own version

15:59 allowing an arbitrary version would make it slower for everyone

15:59 timvisher: which is what i already do

15:59 sweet

15:59 gtrak`: (first (zipmap '(1 2 3) [:a :b :c]))

15:59 ,(first (zipmap '(1 2 3) [:a :b :c]))

15:59 clojurebot: [3 :c]

15:59 gtrak`: ,(rest (zipmap '(1 2 3) [:a :b :c]))

15:59 clojurebot: ([2 :b] [1 :a])

15:59 mfex: gtrak`: a set can produce a seq, does it have an ordering?

16:00 gtrak`: mfex: pretty sure it'll produce the same ordering every time, so yes

16:01 mfex: the seq has an ordering, but a set or map does not I would say

16:01 gtrak`: mfex: maybe not an intentional 'ordering', but definitely an order

16:01 S11001001: after creating a powerful configuration language for setting up exactly how lein should build a classpath and start clojure &c, does it really seem appropriate, architecturally, to create an alternate half-broken config language for command-line? Maven did this, and the results are spectacularly ugly and still don't work half the time

16:02 texnomancy: S11001001: the command-line is really just a mechanism for running certain types of clojure functions

16:02 so you can have higher-order tasks, etc.

16:03 see lein assoc, lein with-profile, lein trampoline, etc

16:03 terom: mfex, gtrak`: there are also sorted-map and sorted-set which preserve the order

16:03 amalloy: clojure-newcomer: a realized lazy-seq is still a lazy-seq; it won't become suitable for Emit

16:04 clojure-newcomer: amolloy: oh… hmmm, am I far from the way to do this right ?

16:04 amalloy: you probably just need to switch the first line to (apply element...)

16:05 clojure-newcomer: amolloy: thanks, I'll give it a go

16:05 amalloy: element doesn't take a seq of content as its third arg; it takes a variable number of arguments

16:06 clojure-newcomer: amalloy: thanks, it works… now going to hit google to see what I just did :-) Appreciate it

16:16 amalloy: coventry`: you around? ISTR you got ritz working recently, and i'm having some trouble with it. i got it all installed: lein2 ritz fires up a server, and M-x slime-connect recognizes it and attempts to connect. but after it spends some time compiling, i get https://gist.github.com/35025a22a846a742c61d

16:17 ritz does seem to be otherwise working - i can inspect local stack frames in the sldb buffer, and there are more restarts than i'm used to seeing

16:17 and in fact, if i just tell it to abort, ritz seems to be able to work perfectly fine after that. so maybe it's not such a big problem

16:37 TimMc: gtrak`: A map is not a seq; it is seqable.

16:38 gtrak`: TimMc: i was wondering about that

16:48 gfredericks: ,(seq? [])

16:48 clojurebot: false

16:48 gfredericks: ,(seq? ())

16:48 clojurebot: true

16:49 nDuff: I find myself frequently using (into {} (map #(array-map ...) ...)) -- is this an acceptable idiom, or should I be doing something else?

16:49 gfredericks: ,(map #(identical? % (seq %)) [() '(2 3) [] #{}])

16:49 clojurebot: (false true false false)

16:50 gfredericks: huh; that's curious

16:50 hiredman: nDuff: no, that is bad

16:50 gfredericks: seq on an empty seq returns nil

16:50 gtrak`: nDuff: http://tech.puredanger.com/2010/09/24/meet-my-little-friend-mapmap/

16:51 nDuff: gtrak`: graci

16:52 gtrak`: nDuff: I was thinking about that earlier but didn't remember what it was for :-), thanks for reminding me

16:52 amalloy: gfredericks: why is that curious?

16:53 nDuff: (map #(...) ...) is usually better as (for [...] ...)

16:54 hugod: amalloy: that exception is with clojure 1.4 I take it

16:54 I need to add it to the initially ignored exception list

16:54 amalloy: hugod: yes

16:54 gtrak`: amalloy: why is 'for' preferred?

16:55 gfredericks: amalloy: () is a seq but is not identical to (seq ())

16:55 even though that's true for a nonempty seq

16:55 or list rather

16:55 amalloy: &(seq ())

16:55 lazybot: ⇒ nil

16:55 TimMc: It's a hack to allow (if (seq ...))

16:55 gfredericks: oh crap of course

16:55 silly things

16:56 TimMc: (as far as I can tell)

16:56 amalloy: TimMc: that doesn't really sound like a hack, but okay

16:56 TimMc: It makes life less pleasant.

16:56 It's a total kludge.

16:56 hugod: amalloy: if you IGNORE it, everything should work properly - and then you can save the exception filter list (M-x slime-selector f then 's' for save) and you will not be pestered again

16:56 TimMc: (*slightly* less pleasant)

16:56 gfredericks: (if (seq ...)) is real weird. Why not (if (not-empty? ...))

16:56 unless you've already called seq on something and want to test that

16:57 but calling seq just for the test...

16:58 S11001001: you can't find out whether a seq is empty until you've seqed it

16:58 duck1123: I've found myself doing (when (seq ...) ...) a lot lately. It takes care of both empty seqs and empty strings

16:58 hiredman: ,(empty? "")

16:58 clojurebot: true

16:58 gfredericks: certainly it works. It's just oddly named for that purpose.

16:59 * nDuff thought he recalled JoC describing using seq just for the test as idiomatic

16:59 duck1123: hiredman: I need the reverse, so it would be (not (empty? ...))

16:59 amalloy: hugod: pressing f there gives me an error - i don't see a filter-related option when i press ? to get the list

16:59 gfredericks: nDuff: I don't doubt it. I'm complaining about that :)

16:59 S11001001: also

16:59 ,(doc empty?)

16:59 clojurebot: "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"

17:00 hiredman: it is a remnant of a bygone era of nil punning

17:00 gfredericks: I don't mind disagreeing with a docstring

17:00 hiredman: originally there was no empty seq

17:00 your seq had something in it, or it was nil

17:01 but that wasn't lazy enough

17:01 gfredericks: right

17:01 is it lazy enough in other lisps?

17:02 where they don't have jvm semantics

17:02 hiredman: other lisps don't have lazy seqs

17:02 I mean they do, as can any language, they just don't have them has the first class iteration protocol

17:03 most lisps have linked lists and cons cells

17:03 gfredericks: ah hah. right.

17:03 TimMc: non-empty? would call seq on its arg for you

17:03 just like empty? does

17:03 Or heck, you'd just use (if-not (empty? ..) ... ...)

17:04 gfredericks: yep

17:05 gtrak`: how do I pull a jar from clojars?

17:05 manually?

17:05 rather, how do I manually pull a jar from clojars?

17:05 hiredman: anyway, (if (seq x) … …) is the idiom when x is a seq

17:06 gtrak`: nevermind, I found it, clojars.org/repo

17:09 dgrnbrg: is there an easy way to have cascalog run a dependency graph?

17:12 pbostrom_: amalloy: can you elaborate on (map #(...) ...) vs (for [...] ...)? Is it a matter of style/readability? Just curious 'cause you mentioned it yesterday too I believe

17:12 coventry`: tomoj, McMartin and TimMc: thanks for the info around 1:30 US ET. I got pulled away from my computer.

17:12 hiredman: for is actually more effecient

17:12 amalloy: hiredman: really? i can't think why

17:13 hiredman: no fn object allocation, no intermediate seqs for mapping and filtering

17:13 coventry`: amalloy: Regarding ritz, I clearly misunderstood when you were talking about it earlier. I thought it was another term for swank-clojure. So it looks like I haven't actually played with ritz.

17:14 amalloy: haha that's okay coventry`. i've got hugod helping me out now, and it's going great

17:15 glitch99: Anybody know how to turn a string into code - (?? "(list 1 2)") --- what should the question marks be?

17:15 amalloy: $findfn "(list 1 2)" '(list 1 2)

17:15 lazybot: [clojure.core/read-string]

17:16 glitch99: Sweet - let me try those

17:18 coventry`: amalloy: good to know, though. It looks like it would address the problems I've run into since. Thanks.

17:18 amalloy: hiredman: it still has to allocate the function

17:19 you can see it in `(fn ~giter ...)

17:21 hiredman: sure

17:21 amalloy: but you're right about there being fewer intermediate seqs, of course

17:22 pbostrom_: anyway, more importantly it's more readable, more flexible, and more nestable

17:27 arohner: are there any maintained zeromq / messaging libraries?

17:28 texnomancy: there's no JVM zeromq client, just native bindings =(

17:28 llasram: Writing a library which one expects will be used on occasionally incorrect data, which seems the most idiomatic pattern?: (a) have a correctness-checking function, and raise an exception on error in the actual parsing function; (b) return `nil` on error in the aactual parsing function

17:29 arohner: texnomancy: is there anything similar to 0mq?

17:29 texnomancy: arohner: oh, if you just want messaging there are lots of amqp clients

17:30 arohner: I might be out of my depth here. What is the difference between zeromq and messaging?

17:30 hiredman: arohner: why do you want 0mq?

17:30 llasram: zeromq is kind-of-sort-of sort-of fancy UDP sockets

17:30 texnomancy: zeromq is not a message queue, it's the raw materials to build your own message queue

17:31 arohner: hiredman: I don't need it specifically. I'm looking for broadcasting 'event' messages between boxes in a cluster. A persistent queue on top of that would be nice, but not necessary

17:31 I was using hazelcast, but it's made of Fail.

17:31 texnomancy: arohner: I'd recommend amqp or jms

17:31 hiredman: how about instead of "blah blah blah 0mq is x blah blah blah" we ask arohner what he wants and then we can argue about if 0mq is good for that

17:32 arohner: hornetq is a nice embedable jvm message queue

17:32 llasram: hiredman: too productive

17:32 hiredman: (meaning you can run the hornetq server in your app's jvm in you want)

17:33 https://github.com/hiredman/vespa-crabro

17:33 texnomancy: came across this the other day for racket: http://planet.racket-lang.org/package-source/gcr/riot.plt/1/0/planet-docs/riot/index.html

17:33 antares_: arohner: Langohr is a well maintained message library (although depending on your needs, it may make more sense to use zeromq than rabbitmq, but for plenty of cases rabbitmq will work great): https://github.com/michaelklishin/langohr/

17:33 texnomancy: nice approach

17:35 arohner: hiredman: thanks. hornetq & vespa looks nice

17:35 llasram: hiredman: Cool. I've been meaning to check out hornetq. We're using rabbitmq at my company, but I think that was mostly the result of die roll

17:35 arohner: btw, word of warning. stay away from hazelcast. rip it out of any project you have to maintain

17:36 hiredman: arohner: I dunno that I would recommend using any of the bits of vespa besides the server embedding code (create-server)

17:36 not that there is anything bad, just nothing provably good

17:36 ivan: arohner: what's wrong with it?

17:37 arohner: ivan: it's not threadsafe. it claims to support distributed transations and locks, but just fails miserably

17:37 ivan: ouch

17:37 arohner: sometimes your cluster will partition for no good reason, and then *if* the clusters merge, your locks will be in inconsistent states

17:38 the documentation mentions none of these flaws, but the devs will admit them in the google group

17:38 "oh yeah, distributed transactions are best effort. hope you weren't doing anything important with that"

17:38 p_l: arohner: ... that doesn't make sense

17:39 arohner: p_l: ?

17:39 p_l: arohner: transactions as best-effort

17:39 hiredman: yeah, well, my experience with hazlecast was laptops running hazlecast nodes wired into a gigE switch would not stay clustered

17:39 p_l: unless it means fail-fast

17:40 everything else can go to hell, but distributed transactions are there to help me maintain (eventual) consistency

17:40 arohner: p_l: basically, hazelcast transactions aren't transactional

17:40 p_l: >_>

17:40 arohner: they sometimes fail. sometimes both sides disagree on what happened

17:40 p_l: ... can I have TPF/OpenVMS back?

17:43 Chiron_: Hi, I'm creating a function that accepts named parameters to execute this command: gluster volume create NEW-VOLNAME [transport tcp | rdma] NEW-BRICK --> gluster volume create test-volume transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4

17:43 arohner: p_l: oh, and my favorite. sometimes your queue will report it is N items long, but then you go take the first item off, and get nil

17:43 Chiron_: new-brick is a vector

17:43 arohner: but the length is still N

17:43 Chiron_: {:keys [volname transport new-brik]}

17:44 new-brik could be one value or many

17:44 what should I tweak in {:keys [volname transport new-brik]}?

17:44 p_l: arohner: ... fun

17:46 arohner: so I was saying... TPF/OpenVMS? I think both support X/Open XA... ;)

17:50 glitch99: so update - i still can't seem to get it to work. Let's say I want to execute the line in the string... what would the the one liner? here's my guess: (#(read-string "(list 1 2)")) but that doesn't seem to work

17:50 I'm loooking for the REPL to return (1 2)

17:51 arohner: ,(read-string "(list 1 2)")

17:51 clojurebot: (list 1 2)

17:51 p_l: ,(eval (read-string "(list 1 2)"))

17:51 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

17:51 p_l: ... SANBOX? ;P

17:51 arohner: glitch99: read-string returns the data, if you want to execute, you need to use eval, though that's usually not the best approach

17:52 glitch99: what are you trying to do?

17:52 amalloy: p_l: it's been that way for so long i think it's now regarded as a feature, not a bug :P

17:53 glitch99: arohner: there's a research tool on the net that posts the lisp parse of sentence tree for an NLP project - trying to turn the string into the lisp and then just define the keywords so that I just need to eval the line and magic happens haha

17:53 p_l: arohner: I don't know about clojure, but in CL, needing to use EVAL is considered a point to stop and rethink wtf you're doing

17:53 glitch99: (eval (read-string "(list 1 2)")) seemed to work! Thanks!

17:53 arohner: p_l: yeah, that's how we treat eval as well

17:53 p_l: and that there's a reason EVAL is one letter difference from EVIL :>

17:54 glitch99: p_l: may I ask why it's taboo?

17:55 amalloy: p_l: the only difference is we don't CAPITALIZE random words like you CRAZIES

17:55 p_l: glitch99: it's less of a taboo, more of a feature that is more misused than GOTO and Dijsktra's papers.

17:55 Raynes: I feel like I'm being yelled at and it is making me uncomfortable.

17:55 amalloy: poor Raynes. let's actually yell at him, to line his perceptions up with reality

17:56 p_l: amalloy: there's so called modern-mode. It didn't catch on :P

17:56 (maybe because it requires manually typing those capitals when needed)

17:56 amalloy: p_l: oh, where the reader doesn't capitalize symbols?

17:57 p_l: amalloy: yes

17:57 Allegro lisp includes a whole image that has common-lisp package with lowercase symbols for that

17:57 glitch99: p_l: haha! you should write the anti-eval paper

17:58 p_l: glitch99: no thanks, someone will try to retitle it as "EVAL considered harmful". And the only "considered harmful" paper I'd like to write would be "Quoting Dijkstra considered harmful"

18:00 nDuff: Hmm.

18:00 * nDuff is handing records over to Velocity templates... but ${record.field} in Velocity isn't evaluating, though (.field record) in Clojure works fine.

18:01 TimMc: nDuff: Guess who doesn't like public fields?

18:01 That guy.

18:02 nDuff: There's something called a "PublicFieldUberspector" you can tell Velocity to use.

18:03 nDuff: Hmm. Given as the Velocity environment here is handed to me preconfigured by JIRA (writing a plugin), I'm actually not sure if I'm in a position to be able to do that.

18:04 TimMc: Velocity is quickly beating me into a pulp.

19:02 I apologize to Enlive for anything bad I ever said about it.

19:02 Raynes: Another one bites the dust.

19:04 TimMc: The Java ecosystem apparently has no notion of library composability.

19:35 devn: I found a brilliant form while toying around with expressions run in IRC:

19:35 &(symbol (apply str (mapcat #(cons "\n" (next (map {\0 \ \1 \#} (Long/toBinaryString %)))) [185 13235209671M 25939708511M 1654794401M 12429901063M 131081 65539])))

19:35 lazybot: ⇒ ### ## # # ### # # # ### #### # # # # # # # ###### # # # # # # # # # ### # ### # #### # ### # # ##

19:35 devn: That probably looks like garbage. Run that in your repl. Do it now.

19:36 TimMc: devn: "RuntimeException Map literal must contain an even number of forms"

19:37 ,(symbol (apply str (mapcat #(cons "\n" (next (map {\0 \space \1 \#} (Long/toBinaryString %)))) [185 13235209671M 25939708511M 1654794401M 12429901063M 131081 65539])))

19:37 clojurebot: ### #

19:37 # # # ### # # # ### ###

19:37 # # # # # # # # #####

19:37 # # # # # # # # # #

19:37 ### # ### # #### # ###

19:37 # #

19:37 ##

19:37 gfredericks: witchcraft

19:38 TimMc: marquee

19:38 devn: haha. now I need to fix this damned project of mine to include who said that so I can send them cupcakes.

19:38 tmciver: Nice

19:39 TimMc: devn: http://clojure-log.n01se.net/date/2010-08-26.html#15:05c I think.

19:39 McMartin: witchalocks

19:39 Also, boggle. You can have newlines in symbol names?

19:40 gfredericks: probably anything

19:40 ,(symbol "foo/bar/baz/bang")

19:40 clojurebot: foo/bar/baz/bang

19:40 p_l: I'm reminded of that trick which printed some text using position of symbols in CL package

19:42 McMartin: This looks like it's old-school monochrome spriting.

19:49 JorgeB: is cupboard the best lib for using BerkeleyDB? Doesn't seem to be maintained.

19:51 eggsby: JorgeB: a lot of clojure libs are just thin wrappers over better maintained java libs, shouldn't be too hard to write one if it doesn't have the features you want :)

19:52 JorgeB: true, but I am looking to make my life easy atm

19:53 and can't login to clojars.org. maybe a hint I should take a break

21:37 sjl: what's happens when I put two libraries in my project.clj, each requiring a different version of another lib foo, and run lein deps?

21:37 which version actually gets used?

21:42 amalloy: 1d2

21:42 clojurebot: 2

21:42 amalloy: sjl: probably something a lot like that

21:42 sjl: sweet

21:42 amalloy: if you need to be specific, i recommend having your project.clj specify a version - that will "win" over either library

21:43 sjl: meh, seems like friend and noir require different versions -- I'll just ignore friend for now I guess

21:43 amalloy: versions of what? compojure, or ring or something?

21:43 sjl: ring

21:45 dreish: It's only at version 1.1.0, isn't it? How could there be any version conflicts?

21:45 amalloy: there's certainly some version that they both work with (in fact probably lots of such versions), but they have to pick one of them to mention in project.clj (since maven's version ranges are so atrocious). probably whatever version you pick will work

21:45 dreish: 1.1.0 should be backward compatible with 1.0.0, if they're using version numbers correctly.

21:45 sjl: dreish: friend's 1.0.2 doesn't work with the latest version of Noir, which needs 1.1.0

21:45 weavejester: dreish: It is

21:45 sjl: I don't know if the other way around will happen to work

21:46 weavejester: sjl: Friend should be fine with Ring 1.1

21:46 * sjl would kill for a programming language that encouraged/enforced semantic versioning at the language level

21:47 dreish: So the question is just whether you can override friend's dependency on 1.0.2 and force it to use 1.1.0?

21:47 weavejester: Ring follows semantic versioning, although there is a Hiccup dependency that spoils it a little.

21:47 sjl: dreish: in this case yes, though I'm curious what happens in the more general sense

21:47 weavejester: Leiningen should use the higher version when using dependencies.

21:47 sjl: it would be cool if 'lein deps' would warn you about conflicting version requirements

21:47 dreish: (It would be nice if Clojure itself followed semantic versioning.)

21:48 sjl: dreish: yeah that would be a nice first step

21:48 xeqi: that would be really ugly at a clojure transition

21:48 sjl: xeqi: exactly -- the point is to make transitions that break everyone's code stand out and look ugly

21:49 weavejester: Ah, gotta go...

21:51 xeqi: and the fix would be to pester and wait for every library the project uses to update to compatible dependencies.. that could take awhile

21:51 TimMc: Unfortunately, I'm pretty sure Lein passes all the dep management straight to Maven.

21:52 sjl: xeqi: the fix is for every library to stop breaking backwards compatibility once they hit 1.0 so you never need to wait.

21:52 gfredericks: the proper way to use semantic versioning is to work on the project for years before it's finally ready for the big 0.1.0

21:55 xeqi: sure, until you want a 1.x -> 2.x jump

21:55 sjl: which should happen very rarely, since it breaks all your users' code

21:57 dreish: It does seem sort of contrary to the Lisp development model to spend a ton of time designing the perfect interface, and then implement it without changing the spec.

21:57 TimMc: The only thing I can't work out is how to version alphas and betas.

21:57 dreish: That's how big parts of Clojure were developed.

21:58 dreish: TimMc: Clojure's at least partly a Java project. ;-)

21:58 TimMc: ...since maybe you don't know ahead of time if you're going to introduce a breaking change.

22:00 sjl: dreish: You can extend the spec all you want in semver, but if you're going to *break* it, you're going to cause all your users time and frustration, so it *should* be a big deal.

22:00 dreish: sjl: Right.

22:00 sjl: but the best part about semver is that even if you do make a breaking change, it's obvious to your users

22:01 when they see the major version number change, they know they need to sit down and read the changelog

22:01 TimMc: There's a difference between the local dev model and how you manage your spec.

22:01 dreish: I can think of a few in Clojure itself, some big and some small (and all changes for the better -- don't get me wrong). I don't remember any of them resulting in a major version change.

22:01 TimMc: Really, you think the RTE-wrapping was for the better? :-/

22:01 dreish: The biggest obviously being the move from lazy-cons to lazy-seq.

22:01 sjl: Yeah, Clojure follows a "maybe we broke your code, maybe we didn't" versioning scheme.

22:01 It's fun.

22:13 klauern: Maybe the simplest step would be to file a bug with Leiningen to make the default `lein new` generate a project.clj with 1.0.0-SNAPSHOT as the version, so as to commit to the big number first...

22:13 I know I'm always changing my projects from 0.1.0-SNAPSHOT to 1.0.0 because I do semver

22:13 it'd be a nudge in the right direction then at least

22:47 vosovich: hey. is anyone available to help with a library problem?

22:48 coventry: I'm getting a NullPointerException when I run 'lein plugin install lein-ritz "0.3.0-SNAPSHOT"' <http://pastebin.com/A0FmhnEH>. Any suggestions?

22:49 gfredericks: ~anyone

22:49 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 ..."

22:52 vosovich: I'm trying to use midje in a project. I've added midje 1.4.0 to my dev-dependencies and dl'ed it with lein deps. Now i try to :use midje.sweet in a test file, but I get a "could not find midje/sweet.... on classpath"

22:53 what am I missing?

22:57 xeqi: coventry: what version of lein?

22:57 vosovich: lein 1.7.1

23:17 coventry: xeqi: Thanks for the suggestion. 1.6.1. Will try upgrading.

23:24 Similar failure with 1.7.1, but this time the java exception is "ZIP file must have at least one entry". http://pastebin.com/4TWQDRzD

23:26 amalloy: coventry: i had the same problem with lein1, and kinda suspect a bad ritz jar in maven somewhere. it works fine in lein2

23:28 xeqi: coventry: could try removing the jar from your ~/.m2

23:29 coventry: I was able to install it by making :dependcies in project.clj and doing "lein deps". Weird...

23:33 fil512: noir question: is there an easy way to serve up a flatfile css?

23:33 I know how to include it in the page header, but I need noir to serve the actual css up when it's requested.

23:35 gfredericks: vosovich: what does `lein classpath` give you?

23:38 xeqi: fil512: I think noir will map the url "/public/*" to the files "resources/*"

23:39 vosovich: gfredericks: it's quite a bunch of jars. is it appropriate to copy-paste everything here?

23:39 or are you looking for something specific?

23:40 gfredericks: vosovich: well mostly that the midge jar is there

23:40 Raynes: xeqi: Nope.

23:40 xeqi: bah, thats what I get for reading source and not actually trying it

23:40 vosovich: gfredericks: the midje jar is indeed in lib/dev/

23:41 Raynes: fil512, xeqi: Pretty sure it maps /* to resources/public/*

23:41 By default.

23:41 gfredericks: vosovich: and you get the error when running `lein test`?

23:41 Raynes: You can change that, if you want.

23:41 xeqi: Raynes: yeah.. look like you're right

23:42 vosovich: pastes can go on refheap.com

23:42 vosovich: no. I just have mentioned this. lein midje (i installed the plugin) works fine. Only when I compile in slime I get the classpath error

23:42 xeqi: thank you

23:42 *I should have mentioned this*

23:42 funny typo...

23:44 seancorfield: man, how did i not know about C-x rfa / C-x rja until today?

23:47 vosovich: gfredericks: So in short: lein midje works, but in slime C-c C-k gives the compilation error

23:49 xeqi: vosovich: just to make sure.. have you restarted slime since adding midje?

23:51 coventry: Hmm, I had to put [lein-ritz "0.3.0"] in :plugins in the local project until "lein ritz" would respond with anything but "that's not a task." Putting it in ~/.lein/project.clj did not work. Now "lein ritz" errors out with "Unable to resolve var: leiningen.core.classpath/get-classpath in this context". http://pastebin.com/VPcLhV4d

23:52 I'm at a point now where I would probably try to figure this out from the source, if I had a decent debugger. :-

23:52 Er, :-)

23:53 vosovich: xeqi: oops. That's it. I figured i could add libs without restarting slime :S

23:53 clojurebot: then its perfect. but of course, there are a lot of other parts too that changes. so after I make assoc :show, is there a problem I make again (def data (assoc data :list ...)

23:53 vosovich: xeqi: thank you

23:54 xeqi: coventry: thats an error saying its trying to load a lein2 namespace

23:54 I see it at the bottom of https://github.com/pallet/ritz/blob/develop/lein-ritz/src/leiningen/ritz.clj

23:54 prolly need to file a bug for that one

23:56 amalloy: coventry: and are you actually running lein2, or is lein still lein1?

23:59 coventry: amalloy: "lein version" says 1.7.1. I took it from raw/stable/bin/lein in technomancy's github. Should I be using a different version?

23:59 Will try lein2

23:59 amalloy: well, i suggested you upgrade to lein2; you certainly don't have to, but my thought was that ritz doesn't work on lein1

Logging service provided by n01se.net