2013-04-25
| 00:45 | l1x | hey guys, is it a good idea to use pmap + dosync to create a fixed size pool for executing synchronous tasks? |
| 00:47 | amalloy | no. use a real threadpool from java.util.concurrent |
| 00: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 |
| 00:53 | tieTYT | i didn't see you answer, sorry if i missed it |
| 00: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 |
| 01: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? |
| 01:18 | l1x | 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) |
| 01:20 | amalloy | $google raek clojure executors |
| 01:20 | lazybot | [raek: Executors in Clojure] http://blog.raek.se/2011/01/24/executors-in-clojure/ |
| 01:23 | tieTYT | amalloy: but I wanted to use clojure to generate classes. It's not for readability |
| 01:23 | tieTYT | i wanted to add the methods as needed |
| 01: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 |
| 01:25 | tieTYT | it uses annotations |
| 01:25 | tieTYT | so it looks for methods/classes with specific annotations on it |
| 01:25 | amalloy | lord. just write some java |
| 01:25 | amalloy | clojure is not going to make it easy for you to work with that |
| 01:25 | tieTYT | oh ok |
| 01:25 | tieTYT | well I already figured out how to generate an example of this class |
| 01:26 | tieTYT | I just didn't know how to add methods dynamically. I felt that I was 90% there |
| 01:26 | tieTYT | but I guess I"ll stick with java |
| 02:02 | tdignan | one man's trash is another company's enterprise codebase :) |
| 03:14 | samvit | hello - noobish question here |
| 03:14 | samvit | would anybody be willing to explain to me what the proper usages of var and #' are? |
| 03:15 | samvit | I've use them in projects |
| 03:15 | samvit | but i'm not 100% sure what is happening behind the scenes |
| 03:16 | antares_ | samvit: clojure.core/var returns you a var, not what the var evaluates to |
| 03:16 | antares_ | not the value it is referencing |
| 03:16 | samvit | so it acts as a pointer? |
| 03:17 | antares_ | samvit: this guide explains the reference/value separation http://clojure-doc.org/articles/language/concurrency_and_parallelism.html |
| 03:17 | samvit | thanks! will read |
| 03:18 | antares_ | samvit: more or less. The word "pointer" is too strongly associated with C pointers, so it's not typically used. |
| 03:18 | samvit | haha okay. I'll read the link you sent but as of my current understanding |
| 03:18 | samvit | i think of vars like atoms |
| 03:19 | samvit | but without all the other |
| 03:19 | samvit | functionality |
| 03:19 | antares_ | samvit: they are both reference types, just with different semantics |
| 03:19 | samvit | okay I'll read the link you said and figure this out |
| 03:19 | antares_ | so your understanding is correct |
| 03:21 | samvit | oh I also had another question |
| 03:22 | samvit | does anyone know if someone in the clojurescript development is working on having defmacro in cljs? |
| 03:22 | samvit | where right now macros must be in separate cli files |
| 04:22 | beaky | hello |
| 04:22 | beaky | how do clojure symbols work? I have only seen them in a few other languages (ruby) |
| 04:23 | beaky | does a new one get cached into some hashtable? |
| 04:23 | clgv | ,(= 'a 'a) |
| 04:23 | clojurebot | true |
| 04:23 | ucb | clgv: can I pick your brains a little? |
| 04:23 | clgv | $source symbol |
| 04:23 | lazybot | symbol is http://is.gd/pEXCtI |
| 04:24 | clgv | ucb: be careful I still need it ;) |
| 04:24 | beaky | wow you can see the source code of clojure? :D |
| 04:24 | clgv | beaky: it is open source ;) |
| 04:24 | beaky | ah |
| 04:24 | beaky | thats awesom |
| 04:24 | beaky | e |
| 04: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/ |
| 04:25 | ucb | clgv: however the general idea is what interest me: would there be any merit in a parallel version of say -> ? |
| 04: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 |
| 04:27 | beaky | I wish other programming languages had something like symbols |
| 04:27 | ucb | (we probably discussed this already btw) |
| 04:27 | noidi | the equivalent of ruby symbols in clojure is keywords |
| 04:27 | clgv | ucb: hmm you mean parallel in terms of concurrency. but -> and ->> are sequential operators how could you possibly parallelize them? |
| 04:28 | clgv | oh sorry, I linked to 1.4 |
| 04: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) |
| 04:31 | ucb | and just push promises down the pipeline as further as you can while spawning futures to deliver them |
| 04:31 | clgv | ah so you have some kind of pipelining. then you just chose the wrong clojure macros ;) |
| 04:32 | clgv | ucb: I wonder if you do not end up reimplementing clojure.core.reducers plus some pipeline combining logic. |
| 04:32 | ucb | yeah, probably :) |
| 04:32 | ucb | I haven't looked at reducers yet, perhaps I should before I do anything else |
| 04:33 | clgv | ucb: in short htey are parallelized drop-in replacements for a lot of core's sequence functions |
| 04:33 | ucb | sounds awfully nice |
| 04:52 | beaky | hello |
| 06:21 | SR | hey. anyone here up to help with setting up lighttable on win vista? |
| 06:36 | ayia_ | Hi guys, parameters that are passed to macro definition is considered as strings, isn't them? |
| 06:42 | cmdrdats | ayia_: no - they are passed in as actual clojure values |
| 06:43 | cmdrdats | 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 |
| 06:43 | ayia_ | cmdrdats: so to treat them as strings (e.g. to parse by regex) i need to wrap them in (str ...), right? |
| 06:44 | cmdrdats | ye - or use (name …), I think |
| 06:45 | ayia_ | cmdrdats: thanks! |
| 06:46 | cmdrdats | ayia_: glad I can be of assistance :) |
| 06:56 | thm_prover | Please recommend a clojure aws library. |
| 06:56 | thm_prover | aws as in Amazon Web Services. |
| 06:57 | thm_prover | https://github.com/weavejester/clj-aws-s3 looks good |
| 08: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... |
| 08:25 | jcromartie | parallel let… not really, but you could destructure a pmap expression |
| 08:26 | jcromartie | (let [[a b c] (pmap expensive-op [x y z])] ...) |
| 08:27 | Glenjamin | (let [a (future (api-call-1)) b (future (api-call-2))] (view @a @b)) |
| 08:27 | Glenjamin | i guess something like that, but without the repetition |
| 08:27 | clgv | Glenjamin: either use futures explicitely or write a macro for it |
| 08:27 | Glenjamin | ah ok, i'm on the right lines then |
| 08:27 | jcromartie | that would work too |
| 08:28 | Glenjamin | is this the sort of thing that could/should be in core? |
| 08:28 | jcromartie | maybe |
| 08:32 | learner_ | Hello Gurus, Is there any clojure example that demonstrates concurrency stuff? Specially around controlling number of parallel threads |
| 08:33 | clgv | Glenjamin: just a sec and you get a plet macro |
| 08:34 | jcromartie | Glenjamin: https://gist.github.com/jcromartie/5459350 |
| 08:34 | Glenjamin | bonus points if it hides the deref :p |
| 08:34 | Glenjamin | (let [a (future 1) b (future 3) a @a b @b] (+ a b)) |
| 08:34 | jcromartie | clgv: sorry I beat you to it :) |
| 08:35 | clgv | jcromartie: thats using the awful semi-lazy pvalues ;) |
| 08:35 | jcromartie | awful, huh? |
| 08:35 | jcromartie | oh well |
| 08:35 | clgv | it is not as parallel as it could be^^ |
| 08:35 | jcromartie | pmap would be better? |
| 08:35 | clgv | oh no. same story |
| 08:36 | jcromartie | you'd have to have a big let binding for it to matter |
| 08:37 | clgv | why not use that one and be on the safe side: https://gist.github.com/guv/5459364 ;) |
| 08: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 |
| 08:37 | clgv | it expands to what Glenjamin wrote^^ |
| 08:37 | mpenet | learner_: or a wrapper: https://github.com/mpenet/knit |
| 08:39 | clgv | learner_: dependy on what your task is |
| 08:39 | Glenjamin | clgv: thanks, looks good to me |
| 08:39 | ucb | mpenet: nice |
| 08:39 | mpenet | lamina channels are nice to do that kind of stuff, parallelisation + dealing with the async results |
| 08:40 | mpenet | you just enqueue stuff into channels and then deal with the values as they come through using its (rich) api |
| 08: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? |
| 08:41 | learner_ | clgv: mpenet: jcromartie: Thank you all |
| 08:41 | clgv | Glenjamin: I'll keep the gist on my github page |
| 08:44 | mpenet | just to expand on what I meant: the callbacks to your async-fn enqueue values into channels, maybe it wasnt clear |
| 08:44 | mpenet | anyway |
| 08:46 | Glenjamin | should (list a b c) and '(a b c) be equivalent? |
| 08:47 | Glenjamin | or more specifically: |
| 08:47 | Glenjamin | should (list (a) b c) and '((a) b c) be equivalent? |
| 08:48 | Glenjamin | and the answer is no, i'm doing it wrong :) |
| 08:48 | pyrtsa | ym. (list '(a) b c) :) |
| 08:49 | Sigma | '(a b c) is equivalent to (list 'a 'b 'c), which is pretty different :) |
| 08:50 | Glenjamin | yeah, for some reason i thought ` recursed and ' didn't |
| 08:50 | pyrtsa | Oh, true. |
| 09:19 | jcromartie | one day I'll get the hang of Clojure |
| 09:19 | clojurebot | clojurebot is a time-capsule for snark |
| 09:19 | jcromartie | the epiphany that will catapult my productivity and creativity is just around the corner, as usual |
| 09:20 | jcromartie | for like, 3 years |
| 09:21 | jcromartie | potential tip: keep things in one namespace until the cohesiveness takes shape |
| 09:21 | jcromartie | until you get a feel for what you're building |
| 09:21 | jcromartie | don't design it all up front |
| 09:31 | arrdem | dnolen: is clojure.match abandoned? |
| 09:32 | arrdem | jcromartie: when you find yourself drawing commented lines across your files tho it's time to split into seperate namespaces |
| 09:32 | jcromartie | arrdem: excellent point |
| 09:32 | jcromartie | arrdem: and that's just what I've done :) |
| 09:33 | jcromartie | but you have to know what needs to cross those lines :) |
| 09:33 | jcromartie | perfect decoupling and cohesion… the hardest things in programming |
| 09:33 | arrdem | right. if you make things composable then splitting by those lines is clean |
| 09:33 | arrdem | if it wasn't clean then breaking it into namspaces will clean it up |
| 09:33 | arrdem | usually |
| 09:34 | arrdem | *force you to clean it up |
| 09:34 | dnolen | arrdem: no, but I don't work on it very much. |
| 09:35 | dnolen | arrdem: though patches do motivate me. |
| 09:35 | arrdem | dnolen: funny how that works :p |
| 09:36 | arrdem | 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 |
| 09: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. |
| 09: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 |
| 09:36 | arrdem | so... tree matchers come up |
| 09:37 | dnolen | arrdem: yeah cata-matching, that's not on the near term for me. But I would happily take a patch for that. |
| 09:37 | dnolen | arrdem: near terms is only about crushing bugs and removing some bad design ideas. |
| 09: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! |
| 09: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 |
| 09:41 | dnolen | arrdem: mostly and issue of coming up with a sensible syntax |
| 09:41 | dnolen | mostly an |
| 09:42 | arrdem | (inc dnolen) ;; added to the reading list |
| 09: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 | arrdem | is there some reason you care? |
| 10:18 | clgv | asaleh: yeah. the stack operations |
| 10:18 | clgv | &(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: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 | clgv | not nice for if-let/when-let... |
| 10:27 | clgv | now we learned "you gotta peek before you pop" |
| 10:28 | clgv | 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 | nDuff | beaky: ...also, Clojure has a far stronger concurrency model than Python or Ruby |
| 10:40 | nDuff | 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 | beaky | 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 | nDuff | 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 | beaky | 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 | jcromartie | I have seen it here and there. But I think the thing I'm missing is practice. |
| 10:50 | jcromartie | I will be deploying a real live Clojure system soon. |
| 10:51 | jcromartie | 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 | Morgawr | although there's not a lot of documentation around :( |
| 10:55 | TimMc | Ran out of bullets? |
| 10:55 | jcromartie | yeah I guess |
| 10:58 | jcromartie | I want to do something that adds a key to a map in one case but not in another |
| 10:58 | jcromartie | I don't want a nil value for that key |
| 10:59 | jcromartie | 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 | TimMc | (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 | jcromartie | 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 | beaky | 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 | nDuff | beaky: idiomatic clojure is slower than Java or scala. |
| 11:07 | nDuff | beaky: You can write non-idiomatic Clojure to be fast, but it's typically something only done when you actually need to |
| 11:07 | nDuff | 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 | mikerod | (macroexpand-1 '(unless (= 1 2) true false)) ;= (if false true false) |
| 11:14 | mikerod | 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 | mikerod | I was just getting this from http://clojure-doc.org/articles/language/macros.html#first_taste_of_macros |
| 11:17 | mikerod | I didn't think at macro-expansion time, the arguments could be evaluated. |
| 11:18 | mikerod | (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 | clgv | 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 | silasdavis | ? |
| 12:05 | silasdavis | what's the best way to use/expand a relative path in a ring app |
| 12:06 | silasdavis | 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 | naeg | 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 | gdev | since it is over a network my challenge is minimizing the number of reads and writes to the database |
| 12:32 | gdev | 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 | gdev | 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 | gdev | 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 | technomancy | 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 | technomancy | it interferes with hotspot inlining according to rich |
| 13:15 | technomancy | 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 | technomancy | 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 | technomancy | 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 | SegFaultAX | 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 | silasdavis | 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 | asteve | 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 | asteve | 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 | technomancy | 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 | technomancy | because you have to preserve comments in project.clj |
| 14:25 | technomancy | 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 | gfredericks | 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 | Glenjamin | 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 | Glenjamin | depends what you're doing really, but data.zip.xml has some nice functions for extracting using expressions |
| 15:17 | Glenjamin | (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 | ppppaul | however, thanks xeqi |
| 15:48 | ppppaul | 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 | ppppaul | :) |
| 15:49 | ppppaul | nrepl 1.7 |
| 15:49 | ppppaul | actually my doc works again |
| 15:49 | ppppaul | 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 | tieTYT2 | that I have to scan to figure out |
| 15:51 | ppppaul | isn't that what makes it good? |
| 15:51 | ppppaul | you no like summary? |
| 15:51 | ppppaul | <3 summary |
| 15:51 | tieTYT2 | I want the summary to make it really obvious when their was a failure |
| 15:51 | tieTYT2 | there |
| 15:51 | tieTYT2 | and be minimal when there wasn't |
| 15:52 | ppppaul | {:type :summary, :pass 29, :test 16, :error 5, :fail 0} |
| 15:52 | ppppaul | that's what i see when i do (run-tests) |
| 15:52 | ppppaul | 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 | tieTYT2 | 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 | n_b | 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 | jcromartie | 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 | mynomoto | It finds repetitions in your code. |
| 16:11 | mynomoto | 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 | iamdrw | will the resulting vector be 0,1,2…. and so on? |
| 16:23 | iamdrw | my tests show that yes, but can I be 100% sure or that? |
| 16:24 | iamdrw | *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 | iamdrw | 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 | jjido | 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 | jcromartie | and then I have a few functions to return parts of that system atom in that core namespace that the routes use |
| 16:43 | jcromartie | so the routes are basically using global variables |
| 16:44 | jcromartie | 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 | TimMc | 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 | 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 | TimMc | I don't know what the evaluation copy lacks. |
| 17:19 | TimMc | oh, fully functional. |
| 17:25 | kwertii | I'll give it a try with the profiler and see what happens. |
| 17:48 | kwertii | 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 | justin_smith | thanks |
| 17:51 | justin_smith | 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 | timvisher | ,(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 | timvisher | apparently those things not being fns screws up my algorithm in someway |
| 18:02 | timvisher | ,(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 | justin_smith | 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 | timvisher | fire everything! |
| 18:05 | justin_smith | resolve also fails on fns, it only works on symbols |
| 18:06 | justin_smith | 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 | technomancy | 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 | technomancy | 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 | technomancy | the rest of them got moved to punctuation, but I guess that one got stuck |
| 19:04 | technomancy | or ignored rather |
| 19:04 | amalloy | heh |
| 19:04 | amalloy | 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 | amalloy | 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 | scottj | I mostly use it in my web browser |
| 19:59 | lynaghk | ping: weavejester |
| 20:02 | lynaghk | 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 | technomancy | 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 | mindbender1 | ,(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 | mindbender1 | thanks |
| 20:21 | SegFaultAX | ,(require 'clojure.set) |
| 20:22 | clojurebot | nil |
| 20:22 | SegFaultAX | (clojure.set/map-invert {:a :b}) |
| 20:22 | SegFaultAX | ,(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 | n_b | 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 | seancorfield | 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 | seancorfield | thanx amalloy |
| 21:01 | amalloy | i'd describe it as less clean, personally, but it'll perform slightly better |
| 21:02 | amalloy | seancorfield: instead of a sorted-map you could sort-by first |
| 21:04 | amalloy | 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 | amalloy | not noticably either way, of course |
| 21:10 | amalloy | 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 | seancorfield | 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 | justin_smith | *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 | gdev | 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 | gdev | it sounds trivial but I'm trying to get clojure introduced in a java EE shop, so babysteps |
| 22:35 | gdev | 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 | gdev | as in (update users (set-fields {:age (inc)})) for an update query that increases all users age by one |
| 22:43 | gdev | 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 | gfredericks | 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 | gfredericks | 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 | gfredericks | 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 | gfredericks | ^ 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: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 | tieTYT | this is printing "committing" |
| 22:59 | tieTYT | and the derefed contents of action |
| 22:59 | tieTYT | AND it seems to be reseting action, but it doesn't seem to be going into any of the multi methods |
| 22:59 | tieTYT | what am I doing wrong? |
| 23:01 | tieTYT | 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 | tieTYT | 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 | tieTYT | where am I doing that? |
| 23:04 | scottj | maybe you did it during devel |
| 23:05 | tieTYT | ... |
| 23:07 | tieTYT | 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 | gdev | I'm just surprised there aren't more examples of dealing with relational databases in clojure floating around on the internets |
| 23:23 | gdev | 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 |