#clojure logs

2013-04-25

00:45l1xhey guys, is it a good idea to use pmap + dosync to create a fixed size pool for executing synchronous tasks?
00:47amalloyno. use a real threadpool from java.util.concurrent
00:53tieTYTamalloy: 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
00:53tieTYTi didn't see you answer, sorry if i missed it
00:55amalloybecause 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
01:03l1xamalloy: how is the import (for the java threadpool you suggested) working in a lein project? is there a :import for the ns?
01:18l1xamalloy: 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)
01:20amalloy$google raek clojure executors
01:20lazybot[raek: Executors in Clojure] http://blog.raek.se/2011/01/24/executors-in-clojure/
01:23tieTYTamalloy: but I wanted to use clojure to generate classes. It's not for readability
01:23tieTYTi wanted to add the methods as needed
01:24amalloyi 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
01:25tieTYTit uses annotations
01:25tieTYTso it looks for methods/classes with specific annotations on it
01:25amalloylord. just write some java
01:25amalloyclojure is not going to make it easy for you to work with that
01:25tieTYToh ok
01:25tieTYTwell I already figured out how to generate an example of this class
01:26tieTYTI just didn't know how to add methods dynamically. I felt that I was 90% there
01:26tieTYTbut I guess I"ll stick with java
02:02tdignanone man's trash is another company's enterprise codebase :)
03:14samvithello - noobish question here
03:14samvitwould anybody be willing to explain to me what the proper usages of var and #' are?
03:15samvitI've use them in projects
03:15samvitbut i'm not 100% sure what is happening behind the scenes
03:16antares_samvit: clojure.core/var returns you a var, not what the var evaluates to
03:16antares_not the value it is referencing
03:16samvitso it acts as a pointer?
03:17antares_samvit: this guide explains the reference/value separation http://clojure-doc.org/articles/language/concurrency_and_parallelism.html
03:17samvitthanks! will read
03:18antares_samvit: more or less. The word "pointer" is too strongly associated with C pointers, so it's not typically used.
03:18samvithaha okay. I'll read the link you sent but as of my current understanding
03:18samviti think of vars like atoms
03:19samvitbut without all the other
03:19samvitfunctionality
03:19antares_samvit: they are both reference types, just with different semantics
03:19samvitokay I'll read the link you said and figure this out
03:19antares_so your understanding is correct
03:21samvitoh I also had another question
03:22samvitdoes anyone know if someone in the clojurescript development is working on having defmacro in cljs?
03:22samvitwhere right now macros must be in separate cli files
04:22beakyhello
04:22beakyhow do clojure symbols work? I have only seen them in a few other languages (ruby)
04:23beakydoes a new one get cached into some hashtable?
04:23clgv,(= 'a 'a)
04:23clojurebottrue
04:23ucbclgv: can I pick your brains a little?
04:23clgv$source symbol
04:23lazybotsymbol is http://is.gd/pEXCtI
04:24clgvucb: be careful I still need it ;)
04:24beakywow you can see the source code of clojure? :D
04:24clgvbeaky: it is open source ;)
04:24beakyah
04:24beakythats awesom
04:24beakye
04:25ucbclgv: 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/
04:25ucbclgv: however the general idea is what interest me: would there be any merit in a parallel version of say -> ?
04:25clgvbeaky: 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
04:27beakyI wish other programming languages had something like symbols
04:27ucb(we probably discussed this already btw)
04:27noidithe equivalent of ruby symbols in clojure is keywords
04:27clgvucb: hmm you mean parallel in terms of concurrency. but -> and ->> are sequential operators how could you possibly parallelize them?
04:28clgvoh sorry, I linked to 1.4
04:30ucbclgv: 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)
04:31ucband just push promises down the pipeline as further as you can while spawning futures to deliver them
04:31clgvah so you have some kind of pipelining. then you just chose the wrong clojure macros ;)
04:32clgvucb: I wonder if you do not end up reimplementing clojure.core.reducers plus some pipeline combining logic.
04:32ucbyeah, probably :)
04:32ucbI haven't looked at reducers yet, perhaps I should before I do anything else
04:33clgvucb: in short htey are parallelized drop-in replacements for a lot of core's sequence functions
04:33ucbsounds awfully nice
04:52beakyhello
06:21SRhey. anyone here up to help with setting up lighttable on win vista?
06:36ayia_Hi guys, parameters that are passed to macro definition is considered as strings, isn't them?
06:42cmdrdatsayia_: no - they are passed in as actual clojure values
06:43cmdrdatsayia_: 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
06:43ayia_cmdrdats: so to treat them as strings (e.g. to parse by regex) i need to wrap them in (str ...), right?
06:44cmdrdatsye - or use (name …), I think
06:45ayia_cmdrdats: thanks!
06:46cmdrdatsayia_: glad I can be of assistance :)
06:56thm_proverPlease recommend a clojure aws library.
06:56thm_proveraws as in Amazon Web Services.
06:57thm_proverhttps://github.com/weavejester/clj-aws-s3 looks good
08:25Glenjamini'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...
08:25jcromartieparallel let… not really, but you could destructure a pmap expression
08:26jcromartie(let [[a b c] (pmap expensive-op [x y z])] ...)
08:27Glenjamin(let [a (future (api-call-1)) b (future (api-call-2))] (view @a @b))
08:27Glenjamini guess something like that, but without the repetition
08:27clgvGlenjamin: either use futures explicitely or write a macro for it
08:27Glenjaminah ok, i'm on the right lines then
08:27jcromartiethat would work too
08:28Glenjaminis this the sort of thing that could/should be in core?
08:28jcromartiemaybe
08:32learner_Hello Gurus, Is there any clojure example that demonstrates concurrency stuff? Specially around controlling number of parallel threads
08:33clgvGlenjamin: just a sec and you get a plet macro
08:34jcromartieGlenjamin: https://gist.github.com/jcromartie/5459350
08:34Glenjaminbonus points if it hides the deref :p
08:34Glenjamin(let [a (future 1) b (future 3) a @a b @b] (+ a b))
08:34jcromartieclgv: sorry I beat you to it :)
08:35clgv jcromartie: thats using the awful semi-lazy pvalues ;)
08:35jcromartieawful, huh?
08:35jcromartieoh well
08:35clgvit is not as parallel as it could be^^
08:35jcromartiepmap would be better?
08:35clgvoh no. same story
08:36jcromartieyou'd have to have a big let binding for it to matter
08:37clgvwhy not use that one and be on the safe side: https://gist.github.com/guv/5459364 ;)
08:37mpenetlearner_: you need to use j.u.concurrent for that, or if you are using agents you can specify a thread-pool with send-via
08:37clgvit expands to what Glenjamin wrote^^
08:37mpenetlearner_: or a wrapper: https://github.com/mpenet/knit
08:39clgvlearner_: dependy on what your task is
08:39Glenjaminclgv: thanks, looks good to me
08:39ucbmpenet: nice
08:39mpenetlamina channels are nice to do that kind of stuff, parallelisation + dealing with the async results
08:40mpenetyou just enqueue stuff into channels and then deal with the values as they come through using its (rich) api
08:40Glenjamindoes 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?
08:41learner_clgv: mpenet: jcromartie: Thank you all
08:41clgvGlenjamin: I'll keep the gist on my github page
08:44mpenetjust to expand on what I meant: the callbacks to your async-fn enqueue values into channels, maybe it wasnt clear
08:44mpenetanyway
08:46Glenjaminshould (list a b c) and '(a b c) be equivalent?
08:47Glenjaminor more specifically:
08:47Glenjaminshould (list (a) b c) and '((a) b c) be equivalent?
08:48Glenjaminand the answer is no, i'm doing it wrong :)
08:48pyrtsaym. (list '(a) b c) :)
08:49Sigma'(a b c) is equivalent to (list 'a 'b 'c), which is pretty different :)
08:50Glenjaminyeah, for some reason i thought ` recursed and ' didn't
08:50pyrtsaOh, true.
09:19jcromartieone day I'll get the hang of Clojure
09:19clojurebotclojurebot is a time-capsule for snark
09:19jcromartiethe epiphany that will catapult my productivity and creativity is just around the corner, as usual
09:20jcromartiefor like, 3 years
09:21jcromartiepotential tip: keep things in one namespace until the cohesiveness takes shape
09:21jcromartieuntil you get a feel for what you're building
09:21jcromartiedon't design it all up front
09:31arrdemdnolen: is clojure.match abandoned?
09:32arrdemjcromartie: when you find yourself drawing commented lines across your files tho it's time to split into seperate namespaces
09:32jcromartiearrdem: excellent point
09:32jcromartiearrdem: and that's just what I've done :)
09:33jcromartiebut you have to know what needs to cross those lines :)
09:33jcromartieperfect decoupling and cohesion… the hardest things in programming
09:33arrdemright. if you make things composable then splitting by those lines is clean
09:33arrdemif it wasn't clean then breaking it into namspaces will clean it up
09:33arrdemusually
09:34arrdem*force you to clean it up
09:34dnolenarrdem: no, but I don't work on it very much.
09:35dnolenarrdem: though patches do motivate me.
09:35arrdemdnolen: funny how that works :p
09:36arrdemdnolen: 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
09:36dnolenarrdem: I do have a have bunch of refactoring/improvement ideas in mind but I'm currently distracted by core.logic / CLJS related things.
09:36arrdemdnolen: now I'm looking at using more than just the first symbol in the expression to decide on a macro CL style
09:36arrdemso... tree matchers come up
09:37dnolenarrdem: yeah cata-matching, that's not on the near term for me. But I would happily take a patch for that.
09:37dnolenarrdem: near terms is only about crushing bugs and removing some bad design ideas.
09:39arrdemdnolen: ok. If it's something I build I'll see if I can shoot you a reasonable pull request. thanks for the info!
09:41dnolenarrdem: Kent Dybvig & Dan Friedman et als matcher does this - http://github.com/eholk/elegant-weapons/blob/master/lib/elegant-weapons/match.scm
09:41dnolenarrdem: mostly and issue of coming up with a sensible syntax
09:41dnolenmostly an
09:42arrdem(inc dnolen) ;; added to the reading list
09:42lazybot⇒ 8
10:16asalehis there an easy way to use (rest [:a :b :c]) or (butlast [:a :b :c]) on vectors? these functions convert them to seqs ..
10:17arrdemasaleh: right. ideally it doesn't matter what _kind_ of sequence you're dealing with.
10:18arrdemis there some reason you care?
10:18clgvasaleh: yeah. the stack operations
10:18clgv&(type (pop [1 2 3]))
10:18lazybot⇒ clojure.lang.PersistentVector
10:18clgvarrdem: it does matter if you want to keep efficient random access
10:19arrdem,(push 3 [1 2])
10:19asaleharrdem, mostly parren preference in pprint :) ... my brain is wired that () means block, [] means data
10:19TimMcasaleh: 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:20clgvarrdem: thats conj ##(conj [1 2] 3)
10:20lazybot⇒ [1 2 3]
10:20asalehclgv, thanks!
10:20clgv&(pop [1 2 3])
10:20lazybot⇒ [1 2]
10:21clgvjust for completeness ;)
10:21clojurebot#<NoClassDefFoundError java.lang.NoClassDefFoundError: Could not initialize class clojure.lang.RT>
10:21beakyhello
10:21clojurebotI'm no man, and she's no lady!
10:22beakyI am a dude :D
10:23clgvgood for you :P
10:23TimMc&(peek [1 2 3]) ;; to really be complete
10:23lazybot⇒ 3
10:24clgvTimMc: hm yeah. `last` will bite you there ;)
10:24hyPiRionnot exactly bite, but be a tad slower
10:24TimMcchew lightly
10:25clgvhyPiRion: depends on your vector size. I have usually much data ^^
10:25hyPiRionyeah, true that
10:25TimMc&((juxt peek pop) [])
10:25lazybotjava.lang.IllegalStateException: Can't pop empty vector
10:25TimMc&(peek [])
10:25lazybot⇒ nil
10:26hyPiRionbut it won't change semantics
10:27clgvhumm an exception instead of nil...
10:27clgvnot nice for if-let/when-let...
10:27clgvnow we learned "you gotta peek before you pop"
10:28clgvhmm except when you store nils as well :O
10:28tomoj&(clojure.pprint/pprint '(var x))
10:28lazybot⇒ #'x nil
10:33TimMcclgv: empty?, not-empty, and seq have your back there
10:33clgvTimMc: right, but it is always nice when you do not need them ;)
10:34TimMc&(pop nil)
10:34lazybot⇒ nil
10:34beakywhat does clojure bring to the table over languages like python and ruby?
10:35Morgawrbeaky: have you ever used a Lisp dialect?
10:35beakyI played with scheme when I was going through sicp
10:35clgv&(pop [])
10:35lazybotjava.lang.IllegalStateException: Can't pop empty vector
10:35clgvthats not really consistent...
10:35TimMc&(pop (not-empty [])) ;; :-/
10:35lazybot⇒ nil
10:36TimMc&(pop (not-empty [1 2 3]))
10:36lazybot⇒ [1 2]
10:36TimMc(def soda (comp pop not-empty))
10:37clgvpop could just return nil like it does for nil^^
10:38nDuffbeaky: 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:39TimMc&(map pop [() clojure.lang.PersistentQueue/EMPTY])
10:39lazybotjava.lang.IllegalStateException: Can't pop empty list
10:39nDuffbeaky: 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:40nDuffbeaky: ...also, Clojure has a far stronger concurrency model than Python or Ruby
10:40nDuffbeaky: ...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:41beakyah
10:41beakyyeah python and ruby are infamous for being dog slow
10:41nDuffbeaky: That's actually the smallest of those three advantages IMHO -- it's just the easiest one to explain. :)
10:42nDuffbeaky: ...but it being _possible_ falls out of the first one somewhat.
10:42beakyright; I guess the biggest benefits would be the boost to programmer productivity (the whole point of using clojure over java and scala)
10:43nDuff"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:44FoxboronThere is no productivity boost in using Clojure in the start. It comes with time as you learn the language.
10:44nDuffIf you measure productivity by how much time your developers spend typing, Clojure is awful. :P
10:44FoxboronJust like any other language
10:45beakyhello
10:47beakyah 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:47nDuffbeaky: It _does_ do that -- but it also has the advantage of being practical as well.
10:50jcromartieI'm trying to find that productivity boost, myself.
10:50jcromartieI have seen it here and there. But I think the thing I'm missing is practice.
10:50jcromartieI will be deploying a real live Clojure system soon.
10:51jcromartieSo hopefully the next one should be better.
10:52hfaafbis web programming a practical domain of clojure
10:52TimMcSure.
10:52MorgawrClojureScript is pretty neat
10:52Morgawralthough there's not a lot of documentation around :(
10:55TimMcRan out of bullets?
10:55jcromartieyeah I guess
10:58jcromartieI want to do something that adds a key to a map in one case but not in another
10:58jcromartieI don't want a nil value for that key
10:59jcromartiedoes that make sense?
10:59TimMcSounds like `fix` from flatland/useful.
10:59jcromartieah
11:00TimMcJust a little sugar over `if`.
11:00jcromartieI thought it might be in useful :)
11:01TimMc&(apply assoc {:my :map} (when (odd? 4) [:more :stuff]))
11:01lazybotclojure.lang.ArityException: Wrong number of args (1) passed to: core$assoc
11:01TimMcHmm, I suppose that's just as well...
11:01TimMc(Not really -- the base case should be supported.)
11:03clgvjcromartie: how about (cond-> my-map (awesome? x) (assoc :x y)) ?
11:03jcromartiehm
11:04TimMc(inc clgv) I forgot about the new stitching macros!
11:04clgvreally useful if you have more than one pair of check and expression
11:04jcromartiewhere is cond->
11:04jcromartieyeah
11:04clgvclojure.core since 1.5
11:04TimMc(inc clgv)
11:04lazybot⇒ 6
11:04TimMcthere we go
11:04clgv:)
11:05beakyis clojure slower than java?
11:05beakyor scala
11:05clgvhttps://github.com/clojure/clojure/blob/master/changes.md#24-new-threading-macros
11:06deeplloydmy how this room has grown
11:07nDuffbeaky: *shrug*.
11:07nDuffbeaky: idiomatic clojure is slower than Java or scala.
11:07nDuffbeaky: You can write non-idiomatic Clojure to be fast, but it's typically something only done when you actually need to
11:07nDuffbeaky: ...tight inner loops and the like.
11:08arrdembeaky: re: nDuff you wind up writing Java in S expressions for performance
11:08nDuffbeaky: The other thing is that idiomatic Clojure is getting faster over time as the runtime is improved.
11:09beakyah
11:11TimMcarrdem: Which is pretty nice, actually. :-p
11:11arrdemTimMc: I mean it's nicer than writing Java in Java, but it still isn't as pretty as writing Clojure in Clojure :p
11:13stainjust 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:14mikerodFrom clojure-doc.org: (defmacro unless [condition & forms] `(if ~(not condition) ~@forms)) ;\newline (macroexpand-1 '(unless (= 1 2) true false)) ;= (if false true false)
11:14mikerod(macroexpand-1 '(unless (= 1 2) true false)) ;= (if false true false)
11:14mikerodThis actually confused me some. It seems like (= 1 2) is being evaluated during macro expansion.
11:15arrdemmikerod: why shouldn't it be?
11:15stainare you changing 2 later on?
11:15arrdemmikerod: if you can prove that all values are static that's a valid transform
11:16mikerodarrdem: What if it was something different like (unless (some #{5} my-var) true false)
11:16clgvmikerod: yeah thats wrong - move the "~" such that (not ~condition)
11:16mikerodclgv: Yes when I move chnage it to (not ~condition), it expands as I'd expect.
11:17mikerodI was just getting this from http://clojure-doc.org/articles/language/macros.html#first_taste_of_macros
11:17mikerodI didn't think at macro-expansion time, the arguments could be evaluated.
11:18mikerod(defmacro unless [condition & forms] `(if (not ~condition) ~@forms))
11:18clgvmikerod: not all can. but with "not" it is possbile since everything is either truthy or nil
11:18clgvsay falsy ;)
11:18mikerod(macroexpand-1 '(unless (= 1 2) true false)) ;= (if (not (= 1 2)) true false) makes sense to me
11:19clgvmikerod: fix it and send a pull request or create an issue on their github page
11:23mikerodclgv: 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:26clgvmikerod: 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:27mikerodclgv: Thanks for helping clear that up.
11:33silasdavisdoes 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:33silasdavis?
12:05silasdaviswhat's the best way to use/expand a relative path in a ring app
12:06silasdavisrelative to some classpath root I guess
12:06technomancysilasdavis: clojure.java.io/resource
12:08silasdavistechnomancy, thanks
12:09naeghow can I "unpack" [& args], so e.g. [1 2 3] => 1 2 3
12:10rasmustonaeg: you can apply a function to args &(apply + [1 2 3])
12:10naegthat'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:12rasmustonaeg: 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:13AimHereIsn't this what '@' is for in macros and such?
12:13naegyeah, but I'm not defining a macro
12:13rasmustonaeg: 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:13naegmaybe apply does the trick, trying
12:15naegrasmusto: yeah apply was correct...maybe I misunderstood something about it
12:15rasmustonaeg: kk, glad it worked out
12:20gdevI need to read from a database, modify one column, and write it back to the database
12:23gdevsince it is over a network my challenge is minimizing the number of reads and writes to the database
12:32gdevIt'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:36gdevI 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:38gdevI was thinking of using just an update query, but I have to calculate the update
13:13borkdudewould it make sense to let regular expressions implement IFn, like (#"foo" "foo") ;;=> "foo"
13:13technomancyborkdude: yes! it totally would
13:14technomancyexcept rich doesn't want to make a new regex class =\
13:14borkdudetechnomancy can't this be done with protocols maybe?
13:14technomancyIFn can't be done with protocols unfortunately
13:14technomancyit interferes with hotspot inlining according to rich
13:15technomancypersonally 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:15technomancybut that's how it is
13:15SegFaultAXtechnomancy: Is there some reasoning behind not wanting to introduce a new regex class?
13:15borkdudethe legacy of clojure ;)
13:17technomancySegFaultAX: it sounded like it was to maintain compatibility with java code
13:17technomancywhich approximately zero people have ever wanted for regexes
13:18SegFaultAXtechnomancy: Eheh, yea. Strange.
13:19silasdaviswhat leiningen dependency do I need to get hold of the com.mysql.jdbc.Driver driver?
13:25SegFaultAXsilasdavis: It looks like [mysql/mysql-connector-java "5.1.24"] is the most recent, but I'm using 5.1.22
13:25SegFaultAXsilasdavis: http://search.maven.org/#artifactdetails%7Cmysql%7Cmysql-connector-java%7C5.1.24%7Cjar
13:27silasdavisSegFaultAX, thanks I'd added that already, I'm trying to us a migrations library called lobos
13:27silasdavisand adapting the example from postgres from sql
13:28SegFaultAXWhy doesn't Maven Central provide leiningen coordinates?
13:28silasdavisbut I'm still getting SQLException No suitable driver found for jdbc:mysql://localhost:3306/heroditus_production java.sql.DriverManager.getConnection (DriverManager.java:604)
13:28SegFaultAXIt supports all the other major build tools. :/
13:28silasdavisSegFaultAX, yeah it's a bit inconvenient
13:33asteveNullPointerException clojure.lang.Reflector.invokeNoArgInstanceMember (Reflector.java:296)
13:34asteveit's very hard to debug this error, is there something that I should immediately know to look for when I get this?
13:34amalloy&(let [x nil] (.foo x))
13:34lazybotjava.lang.NullPointerException
13:34asteveright, I know about NullPointerExceptions, but a NPE in Reflector is confusing to me
13:35tcrayfordit'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:35asteveI agree, I was hoping someone would say "you only get an NPE in Reflector when you're trying to access null args"
13:35astevebut as far as I can my args are not null
13:35amalloyasteve: not null args, a null target
13:36tcrayfordthat's normal for clojure error messages though, they're all awful
13:38dnolenasteve: it's likely the fully trace points to some place in your code where things started going wrong.
13:40antares_if only clojure error messages involved logic programming!
13:40astevednolen: amalloy I found it, something wasn't being initialized
13:40antares_they would be the best of the best by now
13:41n_bIs 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:41antares_all the cool kinds would be all over them
13:41dakronen_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:41antares_n_b: it does use a pool. You can configure it, too.
13:42n_bdakrone, antares_: Great, will look into that! Thanks
13:42dnolenantares_: not a bad idea actually - inferring the source of the error can be quite ugly normally
13:59technomancytcrayford: how would you know the object? it's just nil.
13:59technomancyoh, you mean maybe the name of the local or var?
14:23danneua fun lein plugin would be on that let you `lein install digest` and it'll add [digest "1.3.0"] to project.clj.
14:25technomancydanneu: that's harder than it looks
14:25technomancybecause you have to preserve comments in project.clj
14:25technomancybut yeah, would be nice
14:26Foxborontechnomancy: 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:27joegalloyeah, phil! why didn't you think of that yet?
14:27Foxboronactually, that wouldnt solve the problem if someone ahd comments between the different libs.
14:29technomancyoh snap
14:30pjstadiganything that includes regex magic is probably doomed from the start
14:31Foxboronthats not what people coding Perl say.
14:31pjstadigirregular expressions are where the money's at
14:32technomancyelisp has those
14:56gfredericksis data.xml the best thing for some quick'n'dirty xml nonsense?
14:57n_bgfredericks: That's the answer amalloy gave me last week
14:57gfredericksn_b: sweet, thanks
14:57gfredericksI'm pretty convinced the best advice is usually whatever amalloy said last week
14:58n_bThe only thing better is what he said several seconds ago ;)
14:58gfredericksno you gotta give it time to bake
15:11Glenjamingfredericks: data.xml to write, data.zip.xml to read
15:12Glenjaminand a bit of data.zip actually
15:12gfredericksGlenjamin: I just used tree-seq on the thing data.xml parsed
15:14Glenjamin(let [doc (-> input-stream data.xml/parse zip/xml-zip)] (data.xml.zip/xml1-> :child1 :child2 data.xml.zip/text))
15:15Glenjamindepends what you're doing really, but data.zip.xml has some nice functions for extracting using expressions
15:17Glenjamin(xml1-> :body :a (attr :href)) and so on
15:19gfredericksGlenjamin: that might well end up being useful; thanks
15:32n_bSo, 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:32dakronen_b: that's correct
15:33n_bGreat. Time to go rebinding vars inside another library. This should be fun!
15:35saolsenanybody know if there's saml support for friend? (cemerick maybe?)
15:39alandipertdakrone: thanks for clj-http btw, it rules
15:39dakronealandipert: thanks! :)
15:42n_b++ to that :)
15:42ppppauli 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:46tieTYT2dakrone: yeah it's really useful
15:47xeqippppaul: ##(doc ns-unmap)
15:47lazybotjava.lang.SecurityException: You tripped the alarm! ns-unmap is bad!
15:48xeqisilly alarm
15:48ppppaulmy (doc... doesn't work in my repl
15:48ppppaulhowever, thanks xeqi
15:48ppppauli'll try to remember that fn
15:49tieTYT2ppppaul: mine either, are you using CCW?
15:49xeqitry (clojure.repl/doc ..)
15:49ppppauli redefined my deftest to be (is true)
15:49ppppaul:)
15:49ppppaulnrepl 1.7
15:49ppppaulactually my doc works again
15:49ppppaulmagic
15:49tieTYT2I 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:50ppppaulfails print, successes don't
15:50tieTYT2at the end no matter what it gives you a summary
15:50tieTYT2that I have to scan to figure out
15:51ppppaulisn't that what makes it good?
15:51ppppaulyou no like summary?
15:51ppppaul<3 summary
15:51tieTYT2I want the summary to make it really obvious when their was a failure
15:51tieTYT2there
15:51tieTYT2and be minimal when there wasn't
15:52ppppaul{:type :summary, :pass 29, :test 16, :error 5, :fail 0}
15:52ppppaulthat's what i see when i do (run-tests)
15:52ppppaulwhat do you see?
15:52tieTYT2my eyes have to scan left to right and once I get to the end I see there's a problem
15:53tieTYT2the FIRST thing I care about is if there are failures
15:55ppppaulthe line right above that has fail and error only
16:04n_bSo on the topic of rebinding is this the right way of going about it? https://gist.github.com/5462675
16:04n_bSeemed very un-DRY to me
16:05jcromartieI feel like a Compojure app pretty much needs some global references at some point
16:06jcromartieotherwise it gets really unweildy passing around those references through functions that return handlers all the time
16:11mynomotoReleased my first clojure library: https://github.com/mynomoto/repetition-hunter
16:11mynomotoIt finds repetitions in your code.
16:11mynomotoThanks for helping technomancy and tcrayford.
16:22iamdrwgreetings. Does clojure.core.reducers/fold preserve order?
16:22gfredericksGlenjamin: I am somehow unable to make your example work
16:23iamdrwif I do something like: (count (r/fold (r/monoid into vector) conj (take 1000000 (range))))
16:23iamdrwwill the resulting vector be 0,1,2…. and so on?
16:23iamdrwmy tests show that yes, but can I be 100% sure or that?
16:24iamdrw*of
16:24dnoleniamdrw: as far as I understand, yes
16:24iamdrwcool
16:25amalloywell, that fold is just a reduce, because lazy-seqs don't fold in parallel
16:25iamdrwokay, 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:27iamdrwbecause of vec call?
16:28dnolen,(doc vec)
16:28clojurebot"([coll]); Creates a new vector containing the contents of coll. Java arrays will be aliased and should not be modified."
16:28amalloyhey, how long has it had that warning about arrays?
16:28dnolenamalloy: for a very long time I think.
16:29amalloydnolen: for a year, it looks like
16:30jaffe_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:32amalloyjaffe_: 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:32gfredericks,(reductions conj [] '(a b c d))
16:32clojurebot([] [a] [a b] [a b c] [a b c d])
16:32jaffe_gfredericks: fantastic, thanks!
16:32gfredericks,(map #(apply + %) (rest (reductions conj [] [1 2 3 4])))
16:32clojurebot(1 3 6 10)
16:34jjidoit doesn't do (b c d), (b c), (b) etc
16:36iamdrwokay, (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:37jjido(reductions #(reductions conj) [] '(a b c d))
16:38jjidoMmh am I missing a conj
16:40gtrak_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:40jcromartiewhy would I use a deftype over a hash map for something like holding the sort of global state of an app
16:41amalloyjcromartie: maybe if you were crazy
16:42gtrak_jcromartie: the handlers thing sounds fun, we use a different (probably worse) approach, attaching state-keys to the request.
16:42jcromartiesome hot shot here told me he did that in his web apps
16:42gtrak_then I wrote a terrible macro to deal with that again
16:42jcromartieand I mean it was one of the stuarts or something
16:42dnoleniamdrw: if you want to construct a PV quickly you probably aren't going to beat loop/recur + transient PV
16:43jcromartieright 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:43jcromartieand then I have a few functions to return parts of that system atom in that core namespace that the routes use
16:43jcromartieso the routes are basically using global variables
16:44jcromartiebut I don't see the difference between that and a database
16:44gtrak_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:44jcromartienice
16:46gtrak_every problem's solved with another level of indirection.. a stack-frame in this case
16:52iamdrwdnolen: transient, totally forgot about it
17:10kwertiiI 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:15nDuffkwertii: smells like garbage collection to me, but that very much sounds like a pull-out-a-profiler kind of question.
17:15TimMckwertii: Why are you running intersection on a set and its subset? :-P
17:16TimMcJust testing?
17:16kwertiiTimMc: Just for profiling purposes right now. Later, it'll run with real independently generated data.
17:16TimMcAh, I see -- the second might not always be a subset.
17:16decafwhich profiler you suggest?
17:16TimMcYou might try criterium.
17:17TimMcIt will tell you if there is real variation or if you're just seeing warmup (and GC?) issues.
17:17nDuff...but then, I'm lucky enough to have an employer who shelled out the $$$$ for a license.
17:18TimMcIf it's for open source, it can be free.
17:19TimMcI don't know what the evaluation copy lacks.
17:19TimMcoh, fully functional.
17:25kwertiiI'll give it a try with the profiler and see what happens.
17:48kwertiiIt appears to have been GC. Re-running with a larger heap size makes the problem go away.
17:49justin_smithis there a way to generate less garbage? is cons-free programming in clojure a thing?
17:50technomancyjustin_smith: cons-free programming is typically referred to as transients
17:50justin_smithaha!
17:51justin_smiththanks
17:51justin_smithI had an idea to try some dsp, but got scared by the gc
17:52technomancyhm; well, real-time programming on the JVM is still hard no matter what
17:52justin_smithit's a conservative collector, yes? so if you can avoid making garbage, you can prevent gc (theoretically)
17:53technomancyI don't think so
17:54timvisher,(= [1 + 1] [1 + 1])
17:54clojurebottrue
17:54dnolenjustin_smith: I think you're likely to run into issues w/ the GC.
17:54timvisher,(= [1 + 1] (read-string "[1 + 1]"))
17:54clojurebotfalse
17:54timvisher?
17:55technomancytimvisher: if it's longs vs ints imma punch something
17:55timvisherlol
17:56timvisher,(map class (read-string "[1 + 1]"))
17:56clojurebot(java.lang.Long clojure.lang.Symbol java.lang.Long)
17:56dnolen,(type (second (read-string "[1 + 1]")))
17:56clojurebotclojure.lang.Symbol
17:56timvisher,(map class [1 + 1])
17:56clojurebot(java.lang.Long clojure.core$_PLUS_ java.lang.Long)
17:56dnolentimvisher: you beat me to it
17:59justin_smith,(= (-> "[1 + 1]" read-string eval) [1 + 1])
17:59clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
17:59justin_smithwell it would have said true
17:59timvisherso how can get the fn represented by the class in question?
17:59justin_smitheval will do it, maybe resolve?
18:00amalloy&(= '[1 + 1] (read-string "[1 + 1]"))
18:00lazybot⇒ true
18:01timvisherthe reason i ask is https://gist.github.com/timvisher/5463574
18:01timvisherapparently those things not being fns screws up my algorithm in someway
18:02timvisher,(let [[a op b] (read-string "[1 + 1]")] (op a b))
18:02clojurebot1
18:02timvisher,(let [[a op b] [1 + 1])] (op a b))
18:02clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>
18:02timvisher,(let [[a op b] [1 + 1]] (op a b))
18:02clojurebot2
18:03justin_smith(#(cond (symbol? %) (resolve %) :default %) '+)
18:03justin_smithcould be an if if there will never be other cases, of course
18:04timvisherlooks like resolve will do the trick
18:04justin_smithresolve does fail on numbers though
18:04timvisherI only resolve on the op
18:05timvisherfire everything!
18:05justin_smithresolve also fails on fns, it only works on symbols
18:06justin_smithbut if you know the ops will only ever be symbols
18:06timvisherjustin_smith: indeed. i'm only working with symbols for this little kata so i'm fine.
18:06justin_smithahh
18:55amalloyanyone 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:56S11001001amalloy: (setf (fdefinition #'clojure-test-mode) (lambda (& args) (interactive) nil))?
18:56amalloyi guess i can just remove that entire file
18:56justin_smiththe quick and dirty way is you could rename the source file so require does not find it
18:56technomancyamalloy: why do you have it installed?
18:56amalloytechnomancy: it came with my git-clone
18:57justin_smithalso, you could replace clojure-test-mode-map with something that does not steal keybindings you use
18:57mthvedtif git is a functional tree, there should be a way to do tree transforms on it
18:58technomancywow, fate is really thickly piling on the opportunities to illustrate why people shouldn't use starter kits
18:58mthvedt(remove clojure-test-mode? my-git-repo)
18:59cromney@technomancy didn't you author the starter kit? ;)
18:59technomancyalso, which key binding is it? I thought we'd gotten rid of those
18:59technomancycromney: nobody's perfect
18:59amalloytechnomancy: i just cloned clojure-mode and required the files in it
18:59technomancyamalloy: oh, well that's easy then
18:59amalloysure. i'm deleting the bits i don't want; it's taken years for it to ever be a problem for me
19:00cromney@technomancy don't be so hard on yourself-your 'kit helped me migrate from Vim
19:01justin_smithall the keybindings happen in one short block, so it should be easy to copy and redefine it in your .emacs
19:01technomancycromney: well, it may have been the right thing at the time
19:01technomancythings were very different in 2008; we didn't really have proper emacs packages
19:01amalloytechnomancy: anyway, my clone is way old; you may have fixed the keybindings by now
19:01technomancygotcha
19:02amalloyabout a year old, in fact
19:02justin_smithsince 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:03cromney@technomancy for me it was like learning to swim with floaties as opposed to swallowing lots of water
19:03amalloytechnomancy: no, technomancy/clojure-mode/master/clojure-test-mode.el still takes C-c k
19:03technomancyarg; right
19:04technomancythe rest of them got moved to punctuation, but I guess that one got stuck
19:04technomancyor ignored rather
19:04amalloyheh
19:04amalloyi use C-c k for bury-buffer, which is a handy little function
19:04technomancyyep; I have it bound too =)
19:05amalloywell, 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:11scottjunbury-buffer too
19:11amalloyreally? when do you ever decide to bury something and then want it back before you open any other buffers?
19:12scottjamalloy: it doesn't have to be before you open any other buffers
19:13amalloyoh, of course. that's true
19:13amalloyi 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:17scottjit can be used as a kind of stack. things to do later get burried, and you unbury to work on the next thing
19:18scottjI mostly use it in my web browser
19:59lynaghkping: weavejester
20:02lynaghker, nevermind. Found myself an answer in the source code =)
20:07mindbender1is there a transpose function for map
20:09technomancymindbender1: like swapping keys/vals?
20:10technomancythat's zipmap
20:10mindbender1technomancy: yes
20:10rasmustomindbender1: also, clojure.set/map-invert for some reason
20:13mindbender1,(zipmap {:a :b})
20:13clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$zipmap>
20:13technomancy(zipmap (vals m) (keys m))
20:13mindbender1(clojure.set/map-invert {:a :b})
20:13mindbender1,(clojure.set/map-invert {:a :b})
20:13clojurebot#<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>
20:13technomancyor that
20:13mindbender1map-invert works
20:15mindbender1thanks
20:21SegFaultAX,(require 'clojure.set)
20:22clojurebotnil
20:22SegFaultAX(clojure.set/map-invert {:a :b})
20:22SegFaultAX,(clojure.set/map-invert {:a :b})
20:22clojurebot{:b :a}
20:29n_bI'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:29n_bI assume that means the issue is in some library I'm calling into?
20:31amalloyn_b: usually, yeah. but the profiler can show you backtraces from the reflection
20:47seancorfieldhmm, 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:47seancorfieldis there a cleaner way than this: https://www.refheap.com/paste/13968
21:00amalloynot really. you could save an intermediate string by changing it to (apply str (concat (for ...) [secret]))
21:01seancorfieldhmm, yes, that is cleaner...
21:01seancorfieldthanx amalloy
21:01amalloyi'd describe it as less clean, personally, but it'll perform slightly better
21:02amalloyseancorfield: instead of a sorted-map you could sort-by first
21:04amalloyand 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:05seancorfieldit needs to be exactly k1=v1k2=v2secret and then md5 applied
21:05amalloyoh well
21:06seancorfieldis (sort-by first params) going to faster or slower than (into (sorted-map) params)? i would have expected it to be slower
21:09amalloyit ought to be faster
21:09amalloynot noticably either way, of course
21:10amalloyi 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:14seancorfieldnew version https://www.refheap.com/paste/13970
21:15seancorfieldthanx!
21:22n_bamalloy: Thanks for the backtrace hint, turned out I was reading it completely wrong. Some type-hinting in the library solved the issue
21:23justin_smithwouldn't type-hinging be the standard way to avoid reflection?
21:23justin_smith*hinting
21:24n_bjustin_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:24justin_smithgotcha
21:48hadronzooClojure 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:00hiredmanhadronzoo: 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:03hadronzoohiredman: Thank you for the clarification. I'll implement something guaranteed not to change across runs.
22:05hiredmansomething like a canonicalizing layer + fressian then the hash algorithm of your choice seems like it would work well
22:08hadronzoohiredman: is there a clojurescript port of fressian?
22:09hiredmanunlikely
22:18hadronzoohiredman: I suppose hashing the edn string representation will work as a first pass.
22:21gdev~anyone done any database programming with korma?
22:22clojurebot"In practice, nothing works." -- Brad Fitzpatrick
22:22gdevthanks clojurebot, I've learned that very quickly
22:23gdevnothing works in production either
22:25dan_s28Im 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:26mynomotogdev: what do you mean by database programming?
22:27gdevmynomoto:) I mean accessing a database from a clojure app, mutating a result set and writing it back to the database
22:29mynomotoWriting everything back? Like updating everything that changed?
22:31gdevmynomoto:) 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:33gdevit sounds trivial but I'm trying to get clojure introduced in a java EE shop, so babysteps
22:35gdevmynomoto:) actually, yea what you described is correct, i would only want to write back that one column of mutated data
22:36mynomotogdev: and what part is causing trouble?
22:40gdevmynomoto:) 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:41gdevas in (update users (set-fields {:age (inc)})) for an update query that increases all users age by one
22:43gdevinstead doing (def result-set (select users)) (def mutated-set (inc :age result-set)) (write mutated-set back to database)
22:44samrat___where did clojure.contrib.map-utils go?
22:44gfredericksgdev: your issue is that the resultset is not mutable
22:44gfredericksgdev: korma is not an ORM
22:45mynomotogdev: gfredericks is right.
22:45gfredericksin 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:46gdevgfredericks:) so I just need to find a way to map the new value I want to the old one and write it back
22:47gfrederickskorma has an update function
22:47gfredericksit's just sugar around the SQL update
22:47gdevgfredericks:) yeah I know, but the only example shows writing a hardcoded value back
22:48gfredericksah right
22:48gfredericksare you writing a different value for each record?
22:48gdevgfredericks:) yes, i just need a new random value for each record
22:49gfredericks(doseq [rec recs] (update things (set-fields {:foo (rand-int 10)}) (where {:id (:id rec)})))
22:49gfredericks^ that kind of structure might work for you
22:50gdevgfredericks:) I'll try it out, thanks for the suggestion
22:50gfredericksnp
22:51gdevlol gnight
22:56tieTYTif a multimethod doesn't match, does it just do nothing?
22:58scottjtieTYT: you can provide a default. maybe it gives an error.
22:59tieTYThrm: https://www.refheap.com/paste/5d3def738a84f97da52a224ea
22:59tieTYTthis is printing "committing"
22:59tieTYTand the derefed contents of action
22:59tieTYTAND it seems to be reseting action, but it doesn't seem to be going into any of the multi methods
22:59tieTYTwhat am I doing wrong?
23:01tieTYTin other words, it appears to be running lines 15, 16, and 18, but I don't see any effect of running 17
23:01tieTYThere's an example of @actions: [[:delete #<Win32ShellFolder2 C:\Users\tieTYT\Documents\1.txt>] [:delete #<Win32ShellFolder2 C:\Users\tieTYT\Documents\3.txt>]]
23:04scottjtieTYT: there's something about having to restart when you redefine the dispatch function maybe. perhaps that's your problem
23:04tieTYTredefine?
23:04tieTYTwhere am I doing that?
23:04scottjmaybe you did it during devel
23:05tieTYT...
23:07tieTYTthis doesn't print out anything either: (map #(println "hi " %) @actions)
23:13mattmosstieTYT: map is lazy
23:13tieTYTmattmoss: how do I unlazy it?
23:14gdevkorma isn't an orm? but it has "orm" right in its name, no wonder i was so confused
23:14mattmosstieTYT: wrap in dorun (IIRC)
23:14metellustieTYT: use doseq or dorun
23:14tieTYTok thanks guys
23:14mynomotogdev: Not something like active record in rails.
23:16gdevmynomoto:) with clojure's java interop i guess i could just use hibernate
23:18SegFaultAXgdev: But why would you want to?
23:19gdevSegFaultAX:) I wouldn't, that was the cough syrup talking
23:21gdevI'm just surprised there aren't more examples of dealing with relational databases in clojure floating around on the internets
23:23gdevalthough 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