#clojure log - Apr 25 2013

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

0:45 l1x: hey guys, is it a good idea to use pmap + dosync to create a fixed size pool for executing synchronous tasks?

0:47 amalloy: no. use a real threadpool from java.util.concurrent

0:53 tieTYT: amalloy: I"d like to ask again why you're saying this feature wouldn't be very useful: stackoverflow.com/questions/16199258/how-can-i-pass-in-the-list-of-methods-to-gen-class

0:53 i didn't see you answer, sorry if i missed it

0:55 amalloy: because it's just a crazy thing to do. don't generate objects with piles and piles of methods: write a small number of functions that expose whatever behavior you need

1:03 l1x: amalloy: how is the import (for the java threadpool you suggested) working in a lein project? is there a :import for the ns?

1:18 amalloy: i got the 70% of it by reading the concurrency page, but i dont get what the task should be what i am passing to the threadpool : (.invokeAll pool tasks)

1:20 amalloy: $google raek clojure executors

1:20 lazybot: [raek: Executors in Clojure] http://blog.raek.se/2011/01/24/executors-in-clojure/

1:23 tieTYT: amalloy: but I wanted to use clojure to generate classes. It's not for readability

1:23 i wanted to add the methods as needed

1:24 amalloy: i don't know what jersey is, but if it needs you to add zillions of specifically named methods instead of implementing some interface, it is trash

1:25 tieTYT: it uses annotations

1:25 so it looks for methods/classes with specific annotations on it

1:25 amalloy: lord. just write some java

1:25 clojure is not going to make it easy for you to work with that

1:25 tieTYT: oh ok

1:25 well I already figured out how to generate an example of this class

1:26 I just didn't know how to add methods dynamically. I felt that I was 90% there

1:26 but I guess I"ll stick with java

2:02 tdignan: one man's trash is another company's enterprise codebase :)

3:14 samvit: hello - noobish question here

3:14 would anybody be willing to explain to me what the proper usages of var and #' are?

3:15 I've use them in projects

3:15 but i'm not 100% sure what is happening behind the scenes

3:16 antares_: samvit: clojure.core/var returns you a var, not what the var evaluates to

3:16 not the value it is referencing

3:16 samvit: so it acts as a pointer?

3:17 antares_: samvit: this guide explains the reference/value separation http://clojure-doc.org/articles/language/concurrency_and_parallelism.html

3:17 samvit: thanks! will read

3:18 antares_: samvit: more or less. The word "pointer" is too strongly associated with C pointers, so it's not typically used.

3:18 samvit: haha okay. I'll read the link you sent but as of my current understanding

3:18 i think of vars like atoms

3:19 but without all the other

3:19 functionality

3:19 antares_: samvit: they are both reference types, just with different semantics

3:19 samvit: okay I'll read the link you said and figure this out

3:19 antares_: so your understanding is correct

3:21 samvit: oh I also had another question

3:22 does anyone know if someone in the clojurescript development is working on having defmacro in cljs?

3:22 where right now macros must be in separate cli files

4:22 beaky: hello

4:22 how do clojure symbols work? I have only seen them in a few other languages (ruby)

4:23 does a new one get cached into some hashtable?

4:23 clgv: ,(= 'a 'a)

4:23 clojurebot: true

4:23 ucb: clgv: can I pick your brains a little?

4:23 clgv: $source symbol

4:23 lazybot: symbol is http://is.gd/pEXCtI

4:24 clgv: ucb: be careful I still need it ;)

4:24 beaky: wow you can see the source code of clojure? :D

4:24 clgv: beaky: it is open source ;)

4:24 beaky: ah

4:24 thats awesom

4:24 e

4:25 ucb: clgv: I shall try my best. I've been pondering lately on whether it'd make sense to have parallel versions of -> and ->>. I have a little thing (which doesn't do much more than implicit map, promise, future and deref) here https://github.com/ulises/gok/

4:25 clgv: however the general idea is what interest me: would there be any merit in a parallel version of say -> ?

4:25 clgv: beaky: as you can see here https://github.com/clojure/clojure/blob/clojure-1.4.0/src/jvm/clojure/lang/Symbol.java#L55 symbols are created each time but their strings are interned

4:27 beaky: I wish other programming languages had something like symbols

4:27 ucb: (we probably discussed this already btw)

4:27 noidi: the equivalent of ruby symbols in clojure is keywords

4:27 clgv: ucb: hmm you mean parallel in terms of concurrency. but -> and ->> are sequential operators how could you possibly parallelize them?

4:28 oh sorry, I linked to 1.4

4:30 ucb: clgv: well, that's the thing, you'd have to impose a certain structure to the flow (which I do with p-source, one-by-one and p-sink)

4:31 and just push promises down the pipeline as further as you can while spawning futures to deliver them

4:31 clgv: ah so you have some kind of pipelining. then you just chose the wrong clojure macros ;)

4:32 ucb: I wonder if you do not end up reimplementing clojure.core.reducers plus some pipeline combining logic.

4:32 ucb: yeah, probably :)

4:32 I haven't looked at reducers yet, perhaps I should before I do anything else

4:33 clgv: ucb: in short htey are parallelized drop-in replacements for a lot of core's sequence functions

4:33 ucb: sounds awfully nice

4:52 beaky: hello

6:21 SR: hey. anyone here up to help with setting up lighttable on win vista?

6:36 ayia_: Hi guys, parameters that are passed to macro definition is considered as strings, isn't them?

6:42 cmdrdats: ayia_: no - they are passed in as actual clojure values

6:43 ayia_: so if you call (mymacro blah (foo bar)), the macro is passed a symbol as first argument and a list of two symbols as the second

6:43 ayia_: cmdrdats: so to treat them as strings (e.g. to parse by regex) i need to wrap them in (str ...), right?

6:44 cmdrdats: ye - or use (name …), I think

6:45 ayia_: cmdrdats: thanks!

6:46 cmdrdats: ayia_: glad I can be of assistance :)

6:56 thm_prover: Please recommend a clojure aws library.

6:56 aws as in Amazon Web Services.

6:57 https://github.com/weavejester/clj-aws-s3 looks good

8:25 Glenjamin: i'm looking at trying to parellize three api calls i'm making in a compojure controller, is there some sort of parallel let in core? the docs for binding say it executes in parellel, but requires the vars to already exist...

8:25 jcromartie: parallel let… not really, but you could destructure a pmap expression

8:26 (let [[a b c] (pmap expensive-op [x y z])] ...)

8:27 Glenjamin: (let [a (future (api-call-1)) b (future (api-call-2))] (view @a @b))

8:27 i guess something like that, but without the repetition

8:27 clgv: Glenjamin: either use futures explicitely or write a macro for it

8:27 Glenjamin: ah ok, i'm on the right lines then

8:27 jcromartie: that would work too

8:28 Glenjamin: is this the sort of thing that could/should be in core?

8:28 jcromartie: maybe

8:32 learner_: Hello Gurus, Is there any clojure example that demonstrates concurrency stuff? Specially around controlling number of parallel threads

8:33 clgv: Glenjamin: just a sec and you get a plet macro

8:34 jcromartie: Glenjamin: https://gist.github.com/jcromartie/5459350

8:34 Glenjamin: bonus points if it hides the deref :p

8:34 (let [a (future 1) b (future 3) a @a b @b] (+ a b))

8:34 jcromartie: clgv: sorry I beat you to it :)

8:35 clgv: jcromartie: thats using the awful semi-lazy pvalues ;)

8:35 jcromartie: awful, huh?

8:35 oh well

8:35 clgv: it is not as parallel as it could be^^

8:35 jcromartie: pmap would be better?

8:35 clgv: oh no. same story

8:36 jcromartie: you'd have to have a big let binding for it to matter

8:37 clgv: why not use that one and be on the safe side: https://gist.github.com/guv/5459364 ;)

8:37 mpenet: learner_: you need to use j.u.concurrent for that, or if you are using agents you can specify a thread-pool with send-via

8:37 clgv: it expands to what Glenjamin wrote^^

8:37 mpenet: learner_: or a wrapper: https://github.com/mpenet/knit

8:39 clgv: learner_: dependy on what your task is

8:39 Glenjamin: clgv: thanks, looks good to me

8:39 ucb: mpenet: nice

8:39 mpenet: lamina channels are nice to do that kind of stuff, parallelisation + dealing with the async results

8:40 you just enqueue stuff into channels and then deal with the values as they come through using its (rich) api

8:40 Glenjamin: does that just get lost in the annals of irc scrollback and gists, or is there some way to see if it'd be useful for people to be in core or a standalone lib?

8:41 learner_: clgv: mpenet: jcromartie: Thank you all

8:41 clgv: Glenjamin: I'll keep the gist on my github page

8:44 mpenet: just to expand on what I meant: the callbacks to your async-fn enqueue values into channels, maybe it wasnt clear

8:44 anyway

8:46 Glenjamin: should (list a b c) and '(a b c) be equivalent?

8:47 or more specifically:

8:47 should (list (a) b c) and '((a) b c) be equivalent?

8:48 and the answer is no, i'm doing it wrong :)

8:48 pyrtsa: ym. (list '(a) b c) :)

8:49 Sigma: '(a b c) is equivalent to (list 'a 'b 'c), which is pretty different :)

8:50 Glenjamin: yeah, for some reason i thought ` recursed and ' didn't

8:50 pyrtsa: Oh, true.

9:19 jcromartie: one day I'll get the hang of Clojure

9:19 clojurebot: clojurebot is a time-capsule for snark

9:19 jcromartie: the epiphany that will catapult my productivity and creativity is just around the corner, as usual

9:20 for like, 3 years

9:20 * jcromartie opens up Clojure Programming again

9:21 jcromartie: potential tip: keep things in one namespace until the cohesiveness takes shape

9:21 until you get a feel for what you're building

9:21 don't design it all up front

9:31 arrdem: dnolen: is clojure.match abandoned?

9:32 jcromartie: when you find yourself drawing commented lines across your files tho it's time to split into seperate namespaces

9:32 jcromartie: arrdem: excellent point

9:32 arrdem: and that's just what I've done :)

9:33 but you have to know what needs to cross those lines :)

9:33 perfect decoupling and cohesion… the hardest things in programming

9:33 arrdem: right. if you make things composable then splitting by those lines is clean

9:33 if it wasn't clean then breaking it into namspaces will clean it up

9:33 usually

9:34 *force you to clean it up

9:34 dnolen: arrdem: no, but I don't work on it very much.

9:35 arrdem: though patches do motivate me.

9:35 arrdem: dnolen: funny how that works :p

9:36 dnolen: background here is that I'm building a compiler for course work and with some help from gfredericks (I think it was) I have a full Lisp macro system under the hood

9:36 dnolen: arrdem: I do have a have bunch of refactoring/improvement ideas in mind but I'm currently distracted by core.logic / CLJS related things.

9:36 arrdem: dnolen: now I'm looking at using more than just the first symbol in the expression to decide on a macro CL style

9:36 so... tree matchers come up

9:37 dnolen: arrdem: yeah cata-matching, that's not on the near term for me. But I would happily take a patch for that.

9:37 arrdem: near terms is only about crushing bugs and removing some bad design ideas.

9:39 arrdem: dnolen: ok. If it's something I build I'll see if I can shoot you a reasonable pull request. thanks for the info!

9:41 dnolen: arrdem: Kent Dybvig & Dan Friedman et als matcher does this - http://github.com/eholk/elegant-weapons/blob/master/lib/elegant-weapons/match.scm

9:41 arrdem: mostly and issue of coming up with a sensible syntax

9:41 mostly an

9:42 arrdem: (inc dnolen) ;; added to the reading list

9:42 lazybot: ⇒ 8

10:16 asaleh: is there an easy way to use (rest [:a :b :c]) or (butlast [:a :b :c]) on vectors? these functions convert them to seqs ..

10:17 arrdem: asaleh: right. ideally it doesn't matter what _kind_ of sequence you're dealing with.

10:18 is there some reason you care?

10:18 clgv: asaleh: yeah. the stack operations

10:18 &(type (pop [1 2 3]))

10:18 lazybot: ⇒ clojure.lang.PersistentVector

10:18 clgv: arrdem: it does matter if you want to keep efficient random access

10:19 arrdem: ,(push 3 [1 2])

10:19 asaleh: arrdem, mostly parren preference in pprint :) ... my brain is wired that () means block, [] means data

10:19 TimMc: asaleh: There's no efficient way to do rest on a vector, but subvec may be sufficient. It holds onto the original, though -- so be careful GC-wise.

10:20 clgv: arrdem: thats conj ##(conj [1 2] 3)

10:20 lazybot: ⇒ [1 2 3]

10:20 asaleh: clgv, thanks!

10:20 clgv: &(pop [1 2 3])

10:20 lazybot: ⇒ [1 2]

10:21 clgv: just for completeness ;)

10:21 clojurebot: #<NoClassDefFoundError java.lang.NoClassDefFoundError: Could not initialize class clojure.lang.RT>

10:21 beaky: hello

10:21 clojurebot: I'm no man, and she's no lady!

10:22 beaky: I am a dude :D

10:23 clgv: good for you :P

10:23 TimMc: &(peek [1 2 3]) ;; to really be complete

10:23 lazybot: ⇒ 3

10:23 * arrdem facepalms

10:24 clgv: TimMc: hm yeah. `last` will bite you there ;)

10:24 hyPiRion: not exactly bite, but be a tad slower

10:24 TimMc: chew lightly

10:25 clgv: hyPiRion: depends on your vector size. I have usually much data ^^

10:25 hyPiRion: yeah, true that

10:25 TimMc: &((juxt peek pop) [])

10:25 lazybot: java.lang.IllegalStateException: Can't pop empty vector

10:25 TimMc: &(peek [])

10:25 lazybot: ⇒ nil

10:26 hyPiRion: but it won't change semantics

10:27 clgv: humm an exception instead of nil...

10:27 not nice for if-let/when-let...

10:27 now we learned "you gotta peek before you pop"

10:28 hmm except when you store nils as well :O

10:28 tomoj: &(clojure.pprint/pprint '(var x))

10:28 lazybot: ⇒ #'x nil

10:33 TimMc: clgv: empty?, not-empty, and seq have your back there

10:33 clgv: TimMc: right, but it is always nice when you do not need them ;)

10:34 TimMc: &(pop nil)

10:34 lazybot: ⇒ nil

10:34 beaky: what does clojure bring to the table over languages like python and ruby?

10:35 Morgawr: beaky: have you ever used a Lisp dialect?

10:35 beaky: I played with scheme when I was going through sicp

10:35 clgv: &(pop [])

10:35 lazybot: java.lang.IllegalStateException: Can't pop empty vector

10:35 clgv: thats not really consistent...

10:35 TimMc: &(pop (not-empty [])) ;; :-/

10:35 lazybot: ⇒ nil

10:36 TimMc: &(pop (not-empty [1 2 3]))

10:36 lazybot: ⇒ [1 2]

10:36 TimMc: (def soda (comp pop not-empty))

10:37 clgv: pop could just return nil like it does for nil^^

10:38 nDuff: beaky: Two main things. First, explicit state management (or, to be a little more expansive, a decomplected programming model). Second, the language being isomorphic means that macros are powerful enough that you can build new language features in the language itself.

10:39 TimMc: &(map pop [() clojure.lang.PersistentQueue/EMPTY])

10:39 lazybot: java.lang.IllegalStateException: Can't pop empty list

10:39 nDuff: beaky: Both of those are Big Deals -- the former gives you a model in which you can think about your code without a model where state, identity, method dispatch, &c. are confused with each other

10:40 beaky: ...also, Clojure has a far stronger concurrency model than Python or Ruby

10:40 beaky: ...my first experience in Clojure in production, for that matter, was using it to replace a Python program that couldn't scale up to large multi-core machines, and so couldn't handle the kind of real-time throughput we were asking of it.

10:41 beaky: ah

10:41 yeah python and ruby are infamous for being dog slow

10:41 nDuff: beaky: That's actually the smallest of those three advantages IMHO -- it's just the easiest one to explain. :)

10:42 beaky: ...but it being _possible_ falls out of the first one somewhat.

10:42 beaky: right; I guess the biggest benefits would be the boost to programmer productivity (the whole point of using clojure over java and scala)

10:43 nDuff: "programmer productivity" is a funny term. I can bang out a lot of code quickly in Python, for instance, but doing it in idiomatic Clojure requires me to think harder about breaking down the problem into its components.

10:44 Foxboron: There is no productivity boost in using Clojure in the start. It comes with time as you learn the language.

10:44 nDuff: If you measure productivity by how much time your developers spend typing, Clojure is awful. :P

10:44 Foxboron: Just like any other language

10:45 beaky: hello

10:47 ah thanks; maybe the advantage of learning clojure is similar to learning haskell: it expands your horizons by pushing the FP paradigm into your mind :D

10:47 nDuff: beaky: It _does_ do that -- but it also has the advantage of being practical as well.

10:50 jcromartie: I'm trying to find that productivity boost, myself.

10:50 I have seen it here and there. But I think the thing I'm missing is practice.

10:50 I will be deploying a real live Clojure system soon.

10:51 So hopefully the next one should be better.

10:52 hfaafb: is web programming a practical domain of clojure

10:52 TimMc: Sure.

10:52 Morgawr: ClojureScript is pretty neat

10:52 although there's not a lot of documentation around :(

10:55 * jcromartie felt his brain go *click*

10:55 TimMc: Ran out of bullets?

10:55 jcromartie: yeah I guess

10:58 I want to do something that adds a key to a map in one case but not in another

10:58 I don't want a nil value for that key

10:59 does that make sense?

10:59 TimMc: Sounds like `fix` from flatland/useful.

10:59 jcromartie: ah

11:00 TimMc: Just a little sugar over `if`.

11:00 jcromartie: I thought it might be in useful :)

11:01 TimMc: &(apply assoc {:my :map} (when (odd? 4) [:more :stuff]))

11:01 lazybot: clojure.lang.ArityException: Wrong number of args (1) passed to: core$assoc

11:01 TimMc: Hmm, I suppose that's just as well...

11:01 (Not really -- the base case should be supported.)

11:03 clgv: jcromartie: how about (cond-> my-map (awesome? x) (assoc :x y)) ?

11:03 jcromartie: hm

11:04 TimMc: (inc clgv) I forgot about the new stitching macros!

11:04 clgv: really useful if you have more than one pair of check and expression

11:04 jcromartie: where is cond->

11:04 yeah

11:04 clgv: clojure.core since 1.5

11:04 TimMc: (inc clgv)

11:04 lazybot: ⇒ 6

11:04 TimMc: there we go

11:04 clgv: :)

11:05 beaky: is clojure slower than java?

11:05 or scala

11:05 clgv: https://github.com/clojure/clojure/blob/master/changes.md#24-new-threading-macros

11:06 deeplloyd: my how this room has grown

11:07 nDuff: beaky: *shrug*.

11:07 beaky: idiomatic clojure is slower than Java or scala.

11:07 beaky: You can write non-idiomatic Clojure to be fast, but it's typically something only done when you actually need to

11:07 beaky: ...tight inner loops and the like.

11:08 arrdem: beaky: re: nDuff you wind up writing Java in S expressions for performance

11:08 nDuff: beaky: The other thing is that idiomatic Clojure is getting faster over time as the runtime is improved.

11:09 beaky: ah

11:11 TimMc: arrdem: Which is pretty nice, actually. :-p

11:11 arrdem: TimMc: I mean it's nicer than writing Java in Java, but it still isn't as pretty as writing Clojure in Clojure :p

11:13 stain: just do like the Python/Ruby guys have been doing for years with C modules - if at some point some code is "too slow" (ie. actually has a negative effect) - then profile it, optimize it, and in worst case reimplement that bit in Java

11:14 mikerod: From clojure-doc.org: (defmacro unless [condition & forms] `(if ~(not condition) ~@forms)) ;\newline (macroexpand-1 '(unless (= 1 2) true false)) ;= (if false true false)

11:14 (macroexpand-1 '(unless (= 1 2) true false)) ;= (if false true false)

11:14 This actually confused me some. It seems like (= 1 2) is being evaluated during macro expansion.

11:15 arrdem: mikerod: why shouldn't it be?

11:15 stain: are you changing 2 later on?

11:15 arrdem: mikerod: if you can prove that all values are static that's a valid transform

11:16 mikerod: arrdem: What if it was something different like (unless (some #{5} my-var) true false)

11:16 clgv: mikerod: yeah thats wrong - move the "~" such that (not ~condition)

11:16 mikerod: clgv: Yes when I move chnage it to (not ~condition), it expands as I'd expect.

11:17 I was just getting this from http://clojure-doc.org/articles/language/macros.html#first_taste_of_macros

11:17 I didn't think at macro-expansion time, the arguments could be evaluated.

11:18 (defmacro unless [condition & forms] `(if (not ~condition) ~@forms))

11:18 clgv: mikerod: not all can. but with "not" it is possbile since everything is either truthy or nil

11:18 say falsy ;)

11:18 mikerod: (macroexpand-1 '(unless (= 1 2) true false)) ;= (if (not (= 1 2)) true false) makes sense to me

11:19 clgv: mikerod: fix it and send a pull request or create an issue on their github page

11:23 mikerod: clgv: So is this actually a bad example? I think I get it now. `not` is being passed the form itself as an argument and since the form is not nil, it is true and `not` makes it false

11:26 clgv: mikerod: yeah. your method to check with macroexpand-1 was the right way to check if the macro does what it is expected to do

11:27 mikerod: clgv: Thanks for helping clear that up.

11:33 silasdavis: does anyone know how you'd match an nth child in a document tree, or nth occurence using laser (https://github.com/Raynes/laser/blob/master/docs/guide.md)

11:33 ?

12:05 what's the best way to use/expand a relative path in a ring app

12:06 relative to some classpath root I guess

12:06 technomancy: silasdavis: clojure.java.io/resource

12:08 silasdavis: technomancy, thanks

12:09 naeg: how can I "unpack" [& args], so e.g. [1 2 3] => 1 2 3

12:10 rasmusto: naeg: you can apply a function to args &(apply + [1 2 3])

12:10 naeg: that's not what I want I guess. I have a function that modfies some other function, so I have return a function which just takes & args and then have to unpack them for the real fucntion

12:12 rasmusto: naeg: you can have the first function 'unpack' the sequence, then use apply with that sequence and the second function, or am I missing something?

12:13 AimHere: Isn't this what '@' is for in macros and such?

12:13 naeg: yeah, but I'm not defining a macro

12:13 rasmusto: naeg: the first function can only return one thing, or a collection, so you need the intermediate 'apply' if you want to pass multiple arguments to the second fn

12:13 naeg: maybe apply does the trick, trying

12:15 rasmusto: yeah apply was correct...maybe I misunderstood something about it

12:15 rasmusto: naeg: kk, glad it worked out

12:20 gdev: I need to read from a database, modify one column, and write it back to the database

12:23 since it is over a network my challenge is minimizing the number of reads and writes to the database

12:32 It's a pretty trivial problem but it's my one chance to use Clojure at work so I don't want to give Clojure a bad name by doing something wrong

12:36 I used korma to set up the connection and entity which was is not very straightfoward when using an Oracle database, and I can pull in the entire result set that I need to modify, I'm just looking for an idiomatic way of modifying that huge result set and wirting it back

12:38 I was thinking of using just an update query, but I have to calculate the update

13:13 borkdude: would it make sense to let regular expressions implement IFn, like (#"foo" "foo") ;;=> "foo"

13:13 technomancy: borkdude: yes! it totally would

13:14 except rich doesn't want to make a new regex class =\

13:14 borkdude: technomancy can't this be done with protocols maybe?

13:14 technomancy: IFn can't be done with protocols unfortunately

13:14 it interferes with hotspot inlining according to rich

13:15 personally I think having reader literals for java.util.Pattern is silly; I have never used regexes in interop scenarios nor heard of anyone doing so

13:15 but that's how it is

13:15 SegFaultAX: technomancy: Is there some reasoning behind not wanting to introduce a new regex class?

13:15 borkdude: the legacy of clojure ;)

13:17 technomancy: SegFaultAX: it sounded like it was to maintain compatibility with java code

13:17 which approximately zero people have ever wanted for regexes

13:18 SegFaultAX: technomancy: Eheh, yea. Strange.

13:19 silasdavis: what leiningen dependency do I need to get hold of the com.mysql.jdbc.Driver driver?

13:25 SegFaultAX: silasdavis: It looks like [mysql/mysql-connector-java "5.1.24"] is the most recent, but I'm using 5.1.22

13:25 silasdavis: http://search.maven.org/#artifactdetails%7Cmysql%7Cmysql-connector-java%7C5.1.24%7Cjar

13:27 silasdavis: SegFaultAX, thanks I'd added that already, I'm trying to us a migrations library called lobos

13:27 and adapting the example from postgres from sql

13:28 SegFaultAX: Why doesn't Maven Central provide leiningen coordinates?

13:28 silasdavis: but I'm still getting SQLException No suitable driver found for jdbc:mysql://localhost:3306/heroditus_production java.sql.DriverManager.getConnection (DriverManager.java:604)

13:28 SegFaultAX: It supports all the other major build tools. :/

13:28 silasdavis: SegFaultAX, yeah it's a bit inconvenient

13:33 asteve: NullPointerException clojure.lang.Reflector.invokeNoArgInstanceMember (Reflector.java:296)

13:34 it's very hard to debug this error, is there something that I should immediately know to look for when I get this?

13:34 amalloy: &(let [x nil] (.foo x))

13:34 lazybot: java.lang.NullPointerException

13:34 asteve: right, I know about NullPointerExceptions, but a NPE in Reflector is confusing to me

13:35 tcrayford: it'd be nice if it actually told you a) what object you're trying to invoke a method on and b) what method you tried invoking

13:35 asteve: I agree, I was hoping someone would say "you only get an NPE in Reflector when you're trying to access null args"

13:35 but as far as I can my args are not null

13:35 amalloy: asteve: not null args, a null target

13:36 tcrayford: that's normal for clojure error messages though, they're all awful

13:38 dnolen: asteve: it's likely the fully trace points to some place in your code where things started going wrong.

13:40 antares_: if only clojure error messages involved logic programming!

13:40 asteve: dnolen: amalloy I found it, something wasn't being initialized

13:40 antares_: they would be the best of the best by now

13:41 n_b: Is there any way to tell if clj-http is performing connection pooling or not? Trying to get some better performance out of the Couch driver

13:41 antares_: all the cool kinds would be all over them

13:41 dakrone: n_b: enable logging in your logging config for org.apache and you can see all of Apache's log messages about the connection pool

13:41 antares_: n_b: it does use a pool. You can configure it, too.

13:42 n_b: dakrone, antares_: Great, will look into that! Thanks

13:42 dnolen: antares_: not a bad idea actually - inferring the source of the error can be quite ugly normally

13:59 technomancy: tcrayford: how would you know the object? it's just nil.

13:59 oh, you mean maybe the name of the local or var?

14:23 danneu: a fun lein plugin would be on that let you `lein install digest` and it'll add [digest "1.3.0"] to project.clj.

14:25 technomancy: danneu: that's harder than it looks

14:25 because you have to preserve comments in project.clj

14:25 but yeah, would be nice

14:26 Foxboron: technomancy: you could just use a bit of regex magic and treat the whole file as a string, get the dependency out, eval to clojure code. Modify, then insert as string again

14:27 joegallo: yeah, phil! why didn't you think of that yet?

14:27 Foxboron: actually, that wouldnt solve the problem if someone ahd comments between the different libs.

14:29 technomancy: oh snap

14:30 pjstadig: anything that includes regex magic is probably doomed from the start

14:31 Foxboron: thats not what people coding Perl say.

14:31 pjstadig: irregular expressions are where the money's at

14:32 technomancy: elisp has those

14:56 gfredericks: is data.xml the best thing for some quick'n'dirty xml nonsense?

14:57 n_b: gfredericks: That's the answer amalloy gave me last week

14:57 gfredericks: n_b: sweet, thanks

14:57 I'm pretty convinced the best advice is usually whatever amalloy said last week

14:58 n_b: The only thing better is what he said several seconds ago ;)

14:58 gfredericks: no you gotta give it time to bake

15:11 Glenjamin: gfredericks: data.xml to write, data.zip.xml to read

15:12 and a bit of data.zip actually

15:12 gfredericks: Glenjamin: I just used tree-seq on the thing data.xml parsed

15:14 Glenjamin: (let [doc (-> input-stream data.xml/parse zip/xml-zip)] (data.xml.zip/xml1-> :child1 :child2 data.xml.zip/text))

15:15 depends what you're doing really, but data.zip.xml has some nice functions for extracting using expressions

15:17 (xml1-> :body :a (attr :href)) and so on

15:19 gfredericks: Glenjamin: that might well end up being useful; thanks

15:32 n_b: So, just to make sure I'm understanding this correctly from the logs, by default, clj-http just uses a SingleClientConnManager which will *not* pool and kill the connection once finished?

15:32 dakrone: n_b: that's correct

15:33 n_b: Great. Time to go rebinding vars inside another library. This should be fun!

15:35 saolsen: anybody know if there's saml support for friend? (cemerick maybe?)

15:39 alandipert: dakrone: thanks for clj-http btw, it rules

15:39 dakrone: alandipert: thanks! :)

15:42 n_b: ++ to that :)

15:42 ppppaul: i just removed a deftest (failing one at that) from my nrepl. how do i remove the offenting perpetually failing test def from my repl?

15:46 tieTYT2: dakrone: yeah it's really useful

15:47 xeqi: ppppaul: ##(doc ns-unmap)

15:47 lazybot: java.lang.SecurityException: You tripped the alarm! ns-unmap is bad!

15:48 xeqi: silly alarm

15:48 ppppaul: my (doc... doesn't work in my repl

15:48 however, thanks xeqi

15:48 i'll try to remember that fn

15:49 tieTYT2: ppppaul: mine either, are you using CCW?

15:49 xeqi: try (clojure.repl/doc ..)

15:49 ppppaul: i redefined my deftest to be (is true)

15:49 :)

15:49 nrepl 1.7

15:49 actually my doc works again

15:49 magic

15:49 tieTYT2: I don't really like deftest. Maybe I need to learn how to use it better. But I always have to use my brain to figure out if something failed or everything passed

15:50 ppppaul: fails print, successes don't

15:50 tieTYT2: at the end no matter what it gives you a summary

15:50 that I have to scan to figure out

15:51 ppppaul: isn't that what makes it good?

15:51 you no like summary?

15:51 <3 summary

15:51 tieTYT2: I want the summary to make it really obvious when their was a failure

15:51 there

15:51 and be minimal when there wasn't

15:52 ppppaul: {:type :summary, :pass 29, :test 16, :error 5, :fail 0}

15:52 that's what i see when i do (run-tests)

15:52 what do you see?

15:52 tieTYT2: my eyes have to scan left to right and once I get to the end I see there's a problem

15:53 the FIRST thing I care about is if there are failures

15:55 ppppaul: the line right above that has fail and error only

16:04 n_b: So on the topic of rebinding is this the right way of going about it? https://gist.github.com/5462675

16:04 Seemed very un-DRY to me

16:05 jcromartie: I feel like a Compojure app pretty much needs some global references at some point

16:06 otherwise it gets really unweildy passing around those references through functions that return handlers all the time

16:11 mynomoto: Released my first clojure library: https://github.com/mynomoto/repetition-hunter

16:11 It finds repetitions in your code.

16:11 Thanks for helping technomancy and tcrayford.

16:22 iamdrw: greetings. Does clojure.core.reducers/fold preserve order?

16:22 gfredericks: Glenjamin: I am somehow unable to make your example work

16:23 iamdrw: if I do something like: (count (r/fold (r/monoid into vector) conj (take 1000000 (range))))

16:23 will the resulting vector be 0,1,2…. and so on?

16:23 my tests show that yes, but can I be 100% sure or that?

16:24 *of

16:24 dnolen: iamdrw: as far as I understand, yes

16:24 iamdrw: cool

16:25 amalloy: well, that fold is just a reduce, because lazy-seqs don't fold in parallel

16:25 iamdrw: okay, then next question: why (time (dotimes [i 25] (count (r/fold (r/monoid into vector) conj (take 1000000 (range)))))) is faster than (time (dotimes [i 25] (count (vec (take 1000000 (range))))))

16:27 because of vec call?

16:28 dnolen: ,(doc vec)

16:28 clojurebot: "([coll]); Creates a new vector containing the contents of coll. Java arrays will be aliased and should not be modified."

16:28 amalloy: hey, how long has it had that warning about arrays?

16:28 dnolen: amalloy: for a very long time I think.

16:29 amalloy: dnolen: for a year, it looks like

16:30 jaffe_: Hi, what's the simplest/nicest way of mapping a function across a list, say (a b c d), but calling the function on (a) then (a b) then (a b c) etc.? I know I've done it in some neat way before, but can't remember

16:32 amalloy: jaffe_: that's two distinct steps: turning (a b c d) into ((a) (a b) (a b c) (a b c d)), and then mapping f over it. your search will be simpler if you don't look for a single function that does it all at once

16:32 gfredericks: ,(reductions conj [] '(a b c d))

16:32 clojurebot: ([] [a] [a b] [a b c] [a b c d])

16:32 jaffe_: gfredericks: fantastic, thanks!

16:32 gfredericks: ,(map #(apply + %) (rest (reductions conj [] [1 2 3 4])))

16:32 clojurebot: (1 3 6 10)

16:34 jjido: it doesn't do (b c d), (b c), (b) etc

16:36 iamdrw: okay, (time (dotimes [i 25] (count (take 1000000 (range))))) is expectedly faster than (time (dotimes [i 10] (count (r/fold (r/monoid into vector) conj (take 1000000 (range)))))), but the second one is a clojure.lang.PersistentVector and first is a lazy seq. How can I make a vector of it, and still be faster?

16:37 jjido: (reductions #(reductions conj) [] '(a b c d))

16:38 Mmh am I missing a conj

16:40 gtrak_: iamdrw: the first isn't doing nearly as much stuff as the second, it's just iterating over a lazy-seq. There's no way the second can be faster.

16:40 jcromartie: why would I use a deftype over a hash map for something like holding the sort of global state of an app

16:41 amalloy: jcromartie: maybe if you were crazy

16:42 gtrak_: jcromartie: the handlers thing sounds fun, we use a different (probably worse) approach, attaching state-keys to the request.

16:42 jcromartie: some hot shot here told me he did that in his web apps

16:42 gtrak_: then I wrote a terrible macro to deal with that again

16:42 jcromartie: and I mean it was one of the stuarts or something

16:42 dnolen: iamdrw: if you want to construct a PV quickly you probably aren't going to beat loop/recur + transient PV

16:43 jcromartie: right now I've got a project.web.core namespace with a top-level (defonce system (atom nil)) that gets swapped in with (start! 8000 "path/to/config")

16:43 and then I have a few functions to return parts of that system atom in that core namespace that the routes use

16:43 so the routes are basically using global variables

16:44 but I don't see the difference between that and a database

16:44 gtrak_: if you want to pass stuff around in the request, you can deal with pulling it back out like this: https://gist.github.com/gtrak/5042933

16:44 jcromartie: nice

16:46 gtrak_: every problem's solved with another level of indirection.. a stack-frame in this case

16:52 iamdrw: dnolen: transient, totally forgot about it

17:10 kwertii: I have a set of 1m short strings, and another set of 10k strings which is a subset of the first set. When I run "intersection" on the two sets repeatedly, it sometimes completes in 6 ms, and sometimes in 400 ms. What's the reason for this multiple orders of magnitude variance?

17:15 nDuff: kwertii: smells like garbage collection to me, but that very much sounds like a pull-out-a-profiler kind of question.

17:15 TimMc: kwertii: Why are you running intersection on a set and its subset? :-P

17:16 Just testing?

17:16 kwertii: TimMc: Just for profiling purposes right now. Later, it'll run with real independently generated data.

17:16 TimMc: Ah, I see -- the second might not always be a subset.

17:16 decaf: which profiler you suggest?

17:16 TimMc: You might try criterium.

17:17 * nDuff would be using YourKit

17:17 TimMc: It will tell you if there is real variation or if you're just seeing warmup (and GC?) issues.

17:17 nDuff: ...but then, I'm lucky enough to have an employer who shelled out the $$$$ for a license.

17:18 TimMc: If it's for open source, it can be free.

17:19 I don't know what the evaluation copy lacks.

17:19 oh, fully functional.

17:25 kwertii: I'll give it a try with the profiler and see what happens.

17:48 It appears to have been GC. Re-running with a larger heap size makes the problem go away.

17:49 justin_smith: is there a way to generate less garbage? is cons-free programming in clojure a thing?

17:50 technomancy: justin_smith: cons-free programming is typically referred to as transients

17:50 justin_smith: aha!

17:51 thanks

17:51 I had an idea to try some dsp, but got scared by the gc

17:52 technomancy: hm; well, real-time programming on the JVM is still hard no matter what

17:52 justin_smith: it's a conservative collector, yes? so if you can avoid making garbage, you can prevent gc (theoretically)

17:53 technomancy: I don't think so

17:54 timvisher: ,(= [1 + 1] [1 + 1])

17:54 clojurebot: true

17:54 dnolen: justin_smith: I think you're likely to run into issues w/ the GC.

17:54 timvisher: ,(= [1 + 1] (read-string "[1 + 1]"))

17:54 clojurebot: false

17:54 timvisher: ?

17:55 technomancy: timvisher: if it's longs vs ints imma punch something

17:55 timvisher: lol

17:56 ,(map class (read-string "[1 + 1]"))

17:56 clojurebot: (java.lang.Long clojure.lang.Symbol java.lang.Long)

17:56 dnolen: ,(type (second (read-string "[1 + 1]")))

17:56 clojurebot: clojure.lang.Symbol

17:56 timvisher: ,(map class [1 + 1])

17:56 clojurebot: (java.lang.Long clojure.core$_PLUS_ java.lang.Long)

17:56 dnolen: timvisher: you beat me to it

17:59 justin_smith: ,(= (-> "[1 + 1]" read-string eval) [1 + 1])

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

17:59 justin_smith: well it would have said true

17:59 timvisher: so how can get the fn represented by the class in question?

17:59 justin_smith: eval will do it, maybe resolve?

18:00 amalloy: &(= '[1 + 1] (read-string "[1 + 1]"))

18:00 lazybot: ⇒ true

18:01 timvisher: the reason i ask is https://gist.github.com/timvisher/5463574

18:01 apparently those things not being fns screws up my algorithm in someway

18:02 ,(let [[a op b] (read-string "[1 + 1]")] (op a b))

18:02 clojurebot: 1

18:02 timvisher: ,(let [[a op b] [1 + 1])] (op a b))

18:02 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

18:02 timvisher: ,(let [[a op b] [1 + 1]] (op a b))

18:02 clojurebot: 2

18:03 justin_smith: (#(cond (symbol? %) (resolve %) :default %) '+)

18:03 could be an if if there will never be other cases, of course

18:04 timvisher: looks like resolve will do the trick

18:04 justin_smith: resolve does fail on numbers though

18:04 timvisher: I only resolve on the op

18:05 fire everything!

18:05 justin_smith: resolve also fails on fns, it only works on symbols

18:06 but if you know the ops will only ever be symbols

18:06 timvisher: justin_smith: indeed. i'm only working with symbols for this little kata so i'm fine.

18:06 justin_smith: ahh

18:55 amalloy: anyone know how i can make emacs never-ever enter clojure-test-mode? i don't use it, and it steps on keybindings that are supposed to be reserved for the user

18:56 S11001001: amalloy: (setf (fdefinition #'clojure-test-mode) (lambda (& args) (interactive) nil))?

18:56 amalloy: i guess i can just remove that entire file

18:56 justin_smith: the quick and dirty way is you could rename the source file so require does not find it

18:56 technomancy: amalloy: why do you have it installed?

18:56 amalloy: technomancy: it came with my git-clone

18:57 justin_smith: also, you could replace clojure-test-mode-map with something that does not steal keybindings you use

18:57 mthvedt: if git is a functional tree, there should be a way to do tree transforms on it

18:58 technomancy: wow, fate is really thickly piling on the opportunities to illustrate why people shouldn't use starter kits

18:58 mthvedt: (remove clojure-test-mode? my-git-repo)

18:59 cromney: @technomancy didn't you author the starter kit? ;)

18:59 technomancy: also, which key binding is it? I thought we'd gotten rid of those

18:59 cromney: nobody's perfect

18:59 amalloy: technomancy: i just cloned clojure-mode and required the files in it

18:59 technomancy: amalloy: oh, well that's easy then

18:59 amalloy: sure. i'm deleting the bits i don't want; it's taken years for it to ever be a problem for me

19:00 cromney: @technomancy don't be so hard on yourself-your 'kit helped me migrate from Vim

19:01 justin_smith: all the keybindings happen in one short block, so it should be easy to copy and redefine it in your .emacs

19:01 technomancy: cromney: well, it may have been the right thing at the time

19:01 things were very different in 2008; we didn't really have proper emacs packages

19:01 amalloy: technomancy: anyway, my clone is way old; you may have fixed the keybindings by now

19:01 technomancy: gotcha

19:02 amalloy: about a year old, in fact

19:02 justin_smith: since elisp is not namespaced or lexically closed, you really can just copy paste the defvar statement in the original file, replacing the keybindings with ones you like better

19:03 cromney: @technomancy for me it was like learning to swim with floaties as opposed to swallowing lots of water

19:03 amalloy: technomancy: no, technomancy/clojure-mode/master/clojure-test-mode.el still takes C-c k

19:03 technomancy: arg; right

19:04 the rest of them got moved to punctuation, but I guess that one got stuck

19:04 or ignored rather

19:04 amalloy: heh

19:04 i use C-c k for bury-buffer, which is a handy little function

19:04 technomancy: yep; I have it bound too =)

19:05 amalloy: well, i figured *you* did, you emacs wizard. just thought i'd mention it in case anyone else wanted to try it and improve their lives

19:11 scottj: unbury-buffer too

19:11 amalloy: really? when do you ever decide to bury something and then want it back before you open any other buffers?

19:12 scottj: amalloy: it doesn't have to be before you open any other buffers

19:13 amalloy: oh, of course. that's true

19:13 i just use ido-mode if i want something back, but i can see how if you pay a little more attention than i do, you might know that unbury is what you want

19:17 scottj: it can be used as a kind of stack. things to do later get burried, and you unbury to work on the next thing

19:18 I mostly use it in my web browser

19:59 lynaghk: ping: weavejester

20:02 er, nevermind. Found myself an answer in the source code =)

20:07 mindbender1: is there a transpose function for map

20:09 technomancy: mindbender1: like swapping keys/vals?

20:10 that's zipmap

20:10 mindbender1: technomancy: yes

20:10 rasmusto: mindbender1: also, clojure.set/map-invert for some reason

20:13 mindbender1: ,(zipmap {:a :b})

20:13 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$zipmap>

20:13 technomancy: (zipmap (vals m) (keys m))

20:13 mindbender1: (clojure.set/map-invert {:a :b})

20:13 ,(clojure.set/map-invert {:a :b})

20:13 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>

20:13 technomancy: or that

20:13 mindbender1: map-invert works

20:15 thanks

20:21 SegFaultAX: ,(require 'clojure.set)

20:22 clojurebot: nil

20:22 SegFaultAX: (clojure.set/map-invert {:a :b})

20:22 ,(clojure.set/map-invert {:a :b})

20:22 clojurebot: {:b :a}

20:29 n_b: I'm attempting to profile some code and it seems what's killing my performance is a ton of Reflection that results in invokeMatchingMethod, but I'm not seeing what causes it even with warn-on-reflection set

20:29 I assume that means the issue is in some library I'm calling into?

20:31 amalloy: n_b: usually, yeah. but the profiler can show you backtraces from the reflection

20:47 seancorfield: hmm, so i'm calculating an MD5 signature for a web service... if i have a map of params, i need to create a string of k1=v1k2=v2k3=v3 with the keys in sorted order...

20:47 is there a cleaner way than this: https://www.refheap.com/paste/13968

21:00 amalloy: not really. you could save an intermediate string by changing it to (apply str (concat (for ...) [secret]))

21:01 seancorfield: hmm, yes, that is cleaner...

21:01 thanx amalloy

21:01 amalloy: i'd describe it as less clean, personally, but it'll perform slightly better

21:02 seancorfield: instead of a sorted-map you could sort-by first

21:04 and if you only need your output to be internally-consistent, rather than matching up exactly with their example, you could just str it all, rather than turning it into a k=v thing first

21:05 seancorfield: it needs to be exactly k1=v1k2=v2secret and then md5 applied

21:05 amalloy: oh well

21:06 seancorfield: is (sort-by first params) going to faster or slower than (into (sorted-map) params)? i would have expected it to be slower

21:09 amalloy: it ought to be faster

21:09 not noticably either way, of course

21:10 i guess i'm not sure. the sorting should be faster for sort-by, since it's building a simpler data structure, but it has to do a little bit of copying as well when crossing the API boundary with java.util.Collections

21:14 seancorfield: new version https://www.refheap.com/paste/13970

21:15 thanx!

21:22 n_b: amalloy: Thanks for the backtrace hint, turned out I was reading it completely wrong. Some type-hinting in the library solved the issue

21:23 justin_smith: wouldn't type-hinging be the standard way to avoid reflection?

21:23 *hinting

21:24 n_b: justin_smith: I think the only way? It was more figuring out where the issue was that I was having problems. It's the rare occasion that I'm not the one munging something up ;)

21:24 justin_smith: gotcha

21:48 hadronzoo: Clojure and Clojurescript seem to produce different hash codes for identical datastructures. Can anyone recommend a replacement that produces identical hashes across both Clojure and Clojurescript?

22:00 hiredman: hadronzoo: hashing (via something like clojure's hash and java's hashCode) are just intented to provide hashes for using in hashmaps, there is no guarantee that they will even be the same across program runs (they just need to be the same within a single program run)

22:03 hadronzoo: hiredman: Thank you for the clarification. I'll implement something guaranteed not to change across runs.

22:05 hiredman: something like a canonicalizing layer + fressian then the hash algorithm of your choice seems like it would work well

22:08 hadronzoo: hiredman: is there a clojurescript port of fressian?

22:09 hiredman: unlikely

22:18 hadronzoo: hiredman: I suppose hashing the edn string representation will work as a first pass.

22:21 gdev: ~anyone done any database programming with korma?

22:22 clojurebot: "In practice, nothing works." -- Brad Fitzpatrick

22:22 gdev: thanks clojurebot, I've learned that very quickly

22:23 nothing works in production either

22:25 dan_s28: Im looking for a tutorial that has program structure for beginners. I have read a lot of tutorials, but because of my skill level :) - I can't make the jump from seeing the tools to know which tools to implement. I need something to bridge the gap.

22:26 mynomoto: gdev: what do you mean by database programming?

22:27 gdev: mynomoto:) I mean accessing a database from a clojure app, mutating a result set and writing it back to the database

22:29 mynomoto: Writing everything back? Like updating everything that changed?

22:31 gdev: mynomoto:) let me describe the problem to be a bit more clear... i have a table of repair data, I need to read in all the rows that have an a certain id, add a random number to their retail column, and write that back

22:33 it sounds trivial but I'm trying to get clojure introduced in a java EE shop, so babysteps

22:35 mynomoto:) actually, yea what you described is correct, i would only want to write back that one column of mutated data

22:36 mynomoto: gdev: and what part is causing trouble?

22:40 gdev: mynomoto:) for some reason i'm at a loss of how to mutate the result set, so then I try to just do an update query, but I'm not sure if I can put a function in the update query

22:41 as in (update users (set-fields {:age (inc)})) for an update query that increases all users age by one

22:43 instead doing (def result-set (select users)) (def mutated-set (inc :age result-set)) (write mutated-set back to database)

22:44 samrat___: where did clojure.contrib.map-utils go?

22:44 gfredericks: gdev: your issue is that the resultset is not mutable

22:44 gdev: korma is not an ORM

22:45 mynomoto: gdev: gfredericks is right.

22:45 gfredericks: in that way you can think of korma as being equivalent to writing SQL -- when you get a raw SQL result, you don't update the result itself via mutation, you just construct a logically separate UPDATE query that happens to change the thing you fetched previously

22:46 gdev: gfredericks:) so I just need to find a way to map the new value I want to the old one and write it back

22:47 gfredericks: korma has an update function

22:47 it's just sugar around the SQL update

22:47 gdev: gfredericks:) yeah I know, but the only example shows writing a hardcoded value back

22:48 gfredericks: ah right

22:48 are you writing a different value for each record?

22:48 gdev: gfredericks:) yes, i just need a new random value for each record

22:49 gfredericks: (doseq [rec recs] (update things (set-fields {:foo (rand-int 10)}) (where {:id (:id rec)})))

22:49 ^ that kind of structure might work for you

22:50 gdev: gfredericks:) I'll try it out, thanks for the suggestion

22:50 gfredericks: np

22:50 * gfredericks goes to bed

22:51 gdev: lol gnight

22:56 tieTYT: if a multimethod doesn't match, does it just do nothing?

22:58 scottj: tieTYT: you can provide a default. maybe it gives an error.

22:59 tieTYT: hrm: https://www.refheap.com/paste/5d3def738a84f97da52a224ea

22:59 this is printing "committing"

22:59 and the derefed contents of action

22:59 AND it seems to be reseting action, but it doesn't seem to be going into any of the multi methods

22:59 what am I doing wrong?

23:01 in other words, it appears to be running lines 15, 16, and 18, but I don't see any effect of running 17

23:01 here's an example of @actions: [[:delete #<Win32ShellFolder2 C:\Users\tieTYT\Documents\1.txt>] [:delete #<Win32ShellFolder2 C:\Users\tieTYT\Documents\3.txt>]]

23:04 scottj: tieTYT: there's something about having to restart when you redefine the dispatch function maybe. perhaps that's your problem

23:04 tieTYT: redefine?

23:04 where am I doing that?

23:04 scottj: maybe you did it during devel

23:05 tieTYT: ...

23:07 this doesn't print out anything either: (map #(println "hi " %) @actions)

23:13 mattmoss: tieTYT: map is lazy

23:13 tieTYT: mattmoss: how do I unlazy it?

23:14 gdev: korma isn't an orm? but it has "orm" right in its name, no wonder i was so confused

23:14 mattmoss: tieTYT: wrap in dorun (IIRC)

23:14 metellus: tieTYT: use doseq or dorun

23:14 tieTYT: ok thanks guys

23:14 mynomoto: gdev: Not something like active record in rails.

23:16 gdev: mynomoto:) with clojure's java interop i guess i could just use hibernate

23:18 SegFaultAX: gdev: But why would you want to?

23:19 gdev: SegFaultAX:) I wouldn't, that was the cough syrup talking

23:21 I'm just surprised there aren't more examples of dealing with relational databases in clojure floating around on the internets

23:23 although i am getting a copy of the clojure data processing book which will probably have exactly what I was looking for too bad this project needs to be deployed tomorrow

Logging service provided by n01se.net