2010-10-25
| 00:33 | amalloy | ymasory, dsantiago: technically not just the name after &. the last argument can have further destructuring |
| 00:36 | amalloy | ,((fn [a b & {c :name}] [a b c]) 1 2 :name "steve" :age "paul") |
| 00:36 | clojurebot | [1 2 "steve"] |
| 00:40 | amalloy | heh. i guess paul isn't a good age. got distracted there :P |
| 00:48 | Derander | WORDPRESSSSSSS |
| 00:52 | amalloy | is that so? |
| 01:18 | rdeshpande | yo |
| 01:23 | amalloy | oi |
| 01:27 | jackdempsey | hehe |
| 01:27 | jackdempsey | amalloy: i turned "paul" just the other day |
| 01:27 | amalloy | haha, well, i take back my apology then |
| 01:30 | jackdempsey | hmm, a little unclear on how that destructuring works |
| 01:30 | jackdempsey | ,((fn [a b & {c :age}] [a b c]) 1 2 :name "steve" :age "paul") |
| 01:30 | clojurebot | [1 2 "paul"] |
| 01:31 | jackdempsey | amalloy: so & says "take the rest of the args and stick them in the next thing |
| 01:31 | amalloy | jackdempsey: yep |
| 01:31 | jackdempsey | and this next thing just happens to be a map |
| 01:31 | amalloy | yep. sneaky, innit? |
| 01:31 | jackdempsey | so |
| 01:31 | jackdempsey | hm |
| 01:31 | jackdempsey | heh |
| 01:32 | jackdempsey | i think i get destructuring normally |
| 01:32 | amalloy | heh. "normally" |
| 01:32 | jackdempsey | but this case seems a little different |
| 01:32 | jackdempsey | haha |
| 01:32 | amalloy | just wait. when you get this i'll show you some more trickery |
| 01:32 | jackdempsey | ,((fn [a b & c ] [a b c]) 1 2 :name "steve" :age "paul") |
| 01:32 | clojurebot | [1 2 (:name "steve" :age "paul")] |
| 01:33 | jackdempsey | k that makes sense |
| 01:33 | jackdempsey | but to make sure i'm calling things the correct names: (:name "steve" :age "paul") is a .....list at that point? |
| 01:33 | amalloy | it's a seq. i think whether it's a list or a vector or whatever is none of our business |
| 01:34 | jackdempsey | k so & foo takes the rest of the args and puts them in a seq referred to by symbol foo |
| 01:34 | amalloy | right |
| 01:34 | amalloy | ,((fn [a b & c ] [a b c (class c)]) 1 2 :name "steve" :age "paul") |
| 01:34 | clojurebot | [1 2 (:name "steve" :age "paul") clojure.lang.ArraySeq] |
| 01:34 | jackdempsey | ah |
| 01:35 | jackdempsey | so it almost seems like it should be & {:age} |
| 01:35 | jackdempsey | why {c :age} |
| 01:35 | amalloy | you have to give it a binding |
| 01:35 | amalloy | a way to refer to it inside the function |
| 01:35 | jackdempsey | c to name the arg and { ... :age} to destructure it? |
| 01:35 | amalloy | right! |
| 01:35 | jackdempsey | ,((fn [a b & {:age c}] [a b c]) 1 2 :name "steve" :age "paul") |
| 01:35 | clojurebot | java.lang.RuntimeException: java.lang.RuntimeException: java.lang.Exception: Unsupported binding form: :age |
| 01:36 | jackdempsey | aha |
| 01:36 | Adamant | jackdempsey: how's your left hook? |
| 01:36 | Adamant | :P |
| 01:36 | jackdempsey | Adamant: not too shabby... a bit rusty given the whole "being dead a couple decades" thing :-D |
| 01:37 | Adamant | why, you could lick any man alive at the time, I don't see how being dead would make any difference :P |
| 01:37 | jackdempsey | hehe |
| 01:37 | jackdempsey | man, watching IRT deadliest roads.....these drivers are insane |
| 01:37 | Adamant | jackdempsey: your real name or just a pseudonym? (in either case, someone had good taste :P) |
| 01:38 | jackdempsey | hehe, john by birth, but was too convenient to not go as jack |
| 01:38 | Adamant | ah |
| 01:38 | Adamant | :) |
| 01:38 | Adamant | yeah that road in South America is crazy |
| 01:39 | jackdempsey | ,((fn [a b & [foo & bam] [a b foo bam]) 1 2 :name "steve" :age "paul") |
| 01:39 | clojurebot | Unmatched delimiter: ) |
| 01:39 | jackdempsey | ,((fn [a b & [foo bam] [a b foo bam]) 1 2 :name "steve" :age "paul") |
| 01:39 | clojurebot | Unmatched delimiter: ) |
| 01:39 | jackdempsey | hm |
| 01:39 | amalloy | ,((fn [a b & [foo & bam]] [a b foo bam]) 1 2 :name "steve" :age "paul") |
| 01:39 | clojurebot | [1 2 :name ("steve" :age "paul")] |
| 01:40 | jackdempsey | off to a repl to hide my f'ups :-D |
| 01:40 | jackdempsey | hmm |
| 01:40 | Adamant | if clojurebot does PM that could work |
| 01:40 | amalloy | he does |
| 01:40 | jackdempsey | huh, gotta read that again, don't see the difference |
| 01:40 | amalloy | you missed a ] |
| 01:40 | amalloy | in the arglist |
| 01:40 | jackdempsey | ahh i see |
| 01:41 | jackdempsey | interesting |
| 01:41 | jackdempsey | so any tips on the destructing piece in the sense that: the structure you use to destructure needs to be _____ with the structure it's trying to destruct? |
| 01:41 | jackdempsey | good lord that's a mouthful |
| 01:42 | amalloy | must be an earful too, cause i don't think it got through my ear to my brain. try again? |
| 01:42 | jackdempsey | e.g. i understand that a map works to destructure a map...and a vector can work on a seq....but it's a bit jumbled to me |
| 01:42 | jackdempsey | heh |
| 01:42 | jackdempsey | is there a good place to read on how/what i can use to destructure things? |
| 01:43 | amalloy | hmmm, i think ss has a good blog post on it, and JoC definitely has a nice entry |
| 01:43 | amalloy | http://stuartsierra.com/2010/01/15/keyword-arguments-in-clojure is not *quite* relevant, but probably helpful |
| 01:44 | jackdempsey | cool. so now that i sorta/kinda get it...what was that cooler bit you wanted to show me? |
| 01:44 | amalloy | haha, i was gonna show you :or and :keys |
| 01:46 | jackdempsey | ok |
| 01:46 | amalloy | ,((fn [a b & {c :name d :age :or {d 10}}] [a b c d]) 1 2 :name "steve") |
| 01:46 | clojurebot | [1 2 "steve" 10] |
| 01:47 | jackdempsey | yeah |
| 01:47 | jackdempsey | that makes sense |
| 01:47 | jackdempsey | so |
| 01:48 | jackdempsey | the {c :name} bit is correctly thought of as binding the {third-arg :name} to c and {third-arg :age} to d |
| 01:48 | jackdempsey | except :age doesn't exist, so give it a default value of 10 |
| 01:48 | amalloy | *nod* i think that's about right |
| 01:49 | amalloy | ,((fn [{:keys [a b c d]] [a b c d]) {:a 1, :c 8}) |
| 01:49 | clojurebot | Unmatched delimiter: ] |
| 01:49 | amalloy | ,((fn [{:keys [a b c d]}] [a b c d]) {:a 1, :c 8}) |
| 01:49 | jackdempsey | i guess the final bit is being crystal on how & {c :name} turns into binding :name from the arg into c. it's like you're using a familiar form but not the same call semantics |
| 01:49 | clojurebot | [1 nil 8 nil] |
| 01:49 | jackdempsey | which would make me think i'm calling :name on c |
| 01:49 | jackdempsey | lol the face |
| 01:50 | jackdempsey | nice, yea i've seen :keys a little. is it used much in practice? |
| 01:50 | amalloy | hah, i dunno. i don't do a lot of anything, in practice |
| 01:50 | amalloy | yeah, the fact that {a :name} rather than {:name a} is used for destructuring is a bit confusing |
| 01:51 | amalloy | but it's so that things like :keys, :or, and so forth can't possibly be "normal" destructuring |
| 01:51 | kryft | Are there any vimpulse users around, btw? |
| 01:51 | amalloy | because :or is an illegal variable name |
| 01:52 | jackdempsey | hmm |
| 01:55 | amalloy | there are also :strings and :symbols equivalent to :keys. i've never used them, so they might be :strs and :syms or something |
| 01:55 | jackdempsey | cool |
| 01:55 | LauJensen | Morning all |
| 01:55 | amalloy | morning LauJensen |
| 01:55 | jackdempsey | ah |
| 01:55 | jackdempsey | The keys of the binding map are the local variables you want to create. The values of the binding map are keys in the initialization expression. The locals will be bound to the values of corresponding keys. |
| 01:55 | jackdempsey | that helps |
| 01:56 | amalloy | good, good |
| 01:56 | vibrant | morning |
| 01:58 | jackdempsey | ha :keys reminds me of explode or whatever that was in php |
| 01:59 | jackdempsey | that took a hash and made locals from the keys in it |
| 01:59 | amalloy | oh blech. thank god i haven't run into that yet |
| 02:00 | amalloy | hey LauJensen, since you got so sad yesterday i went and read your blog post about the orbital simulator, and i don't think you're right about the anonymous functions in distance/vector |
| 02:00 | LauJensen | amalloy: I dont remember being sad yesterday, and yes you're right about the anon fn, I spoke too soon |
| 02:00 | LauJensen | (read the comments) |
| 02:00 | amalloy | ah. you were "offended" i didn't follow your blog |
| 02:01 | LauJensen | yea that was a joke old chap |
| 02:03 | amalloy | hence my "scare quotes" |
| 02:03 | vibrant | so how do i represent 'objects' in clojure? like i na game i have a player, i created a hash-map for him and def'ed it to a global variable - how do i modify that map now? |
| 02:05 | LauJensen | ,(let [player (atom {:health 100 :name "Frank"})] (swap! player update-in [:health] dec)) |
| 02:06 | clojurebot | {:health 99, :name "Frank"} |
| 02:06 | LauJensen | vibrant: Get familiar with Clojures reference types. For a game you might want refs instead of atoms |
| 02:07 | amalloy | LauJensen: i was going to suggest passing the player around instead of making him a global. seems a lot more functional to me. i assume you have a good reason for your approach, though; what is it? |
| 02:07 | vibrant | LauJensen: yeah I'll get there. now I just managed to boot up clj-processing and I'm experimenting with the base stuff and learning Clojure in the meantime :) |
| 02:07 | LauJensen | amalloy: Your idea is better for something like Pacman I suppose, though for a more complex game, the pain of passing everything stateful around in args, not to mention the performance hit would be counterproductive |
| 02:08 | LauJensen | Generally, a great strength of Clojure, is to handle inherently stateful tasks correctly. Ie. not pretending there is no state |
| 02:09 | amalloy | is there really much of a performance hit? it seems like swap! is going to have to create new objects and so on anyway, so the only hit seems to be passing around some pointers |
| 02:11 | amalloy | i may be biased because my "game" does a lot of backtracking depth-first search, so i want to have old states available |
| 02:13 | LauJensen | amalloy: Well. I cant think of a one-size fits all answer re performance. The two hits you take are allocation and subsequent GC. Typically I think we see more seq traversal in programs that pass everything around. Though I might just be imaging that |
| 02:14 | kryft | LauJensen: Is there a big performance hit from seq traversal? |
| 02:14 | amalloy | i guess you do get more allocation passing stuff around, if you want to do deeply-nested modifications (eg changing the player's pet's hair color) |
| 02:15 | LauJensen | kryft: something like (-> this-seq map filter remove) etc, generates n number of seqs where n is the number of items in the list. However subsequently swapping that into an atom doesnt give a large overhead |
| 02:22 | LauJensen | amalloy: I guess in most cases, the only measurable performance diff, is whether or not you resort to transients, arrays or pods |
| 02:22 | amalloy | heh |
| 02:22 | yayitswei | when you guys get a chance, could you help me rewrite my recursive group-by function in idiomatic clojure? http://gist.github.com/644489 |
| 02:26 | amalloy | yayitswei: you can get rid of the yucky first/rest with destructuring |
| 02:26 | LauJensen | ,(reduce #(let [[d m y] %2] (assoc %1 m (conj (%1 m []) [d m y]))) {} [[30 9 2010] [30 10 2010] [31 10 2010]]) |
| 02:26 | clojurebot | {10 [[30 10 2010] [31 10 2010]], 9 [[30 9 2010]]} |
| 02:26 | amalloy | (loop [t s [f & fs] starting-fns] (use f and fs)) |
| 02:27 | LauJensen | or I guess you could do something like that |
| 02:27 | LauJensen | amalloy: you'll be surprised to learn that such destructuring is much slower than first/rest/next |
| 02:27 | amalloy | indeed i will be surprised, LauJensen! |
| 02:27 | LauJensen | Even if you have to call first/rest 2 or 3 times, it will still be faster |
| 02:28 | yayitswei | vibrant: btw, I'm reading Stuart Halloway's book and he has a good example on Clojure snake using refs: http://github.com/stuarthalloway/programming-clojure/blob/master/examples/snake.clj |
| 02:28 | amalloy | LauJensen: your solution does a different thing than his function, though |
| 02:28 | LauJensen | amalloy: you mean in that its not recursive+ |
| 02:29 | amalloy | maybe; i'm not sure what you mean. he seems to want nested maps for each grouping function |
| 02:30 | yayitswei | wow your versions are so much more dense |
| 02:30 | yayitswei | amalloy: yes, I believe that's what I want, trying it now |
| 02:30 | LauJensen | amalloy: of you're right, he's passing 2 f's |
| 02:31 | amalloy | LauJensen: i'm sure using reduce will be more idiomatic and/or better, but i didn't want to try and figure out how the function worked so i just pointed out a nice-looking fix |
| 02:32 | LauJensen | sure, so now he has 2 options :) |
| 02:32 | yayitswei | ,(doc use) |
| 02:32 | clojurebot | "([& args]); Like 'require, but also refers to each lib's namespace using clojure.core/refer. Use :use in the ns macro in preference to calling this directly. 'use accepts additional options in libsp... |
| 02:32 | yayitswei | interesting usage of 'use' |
| 02:34 | LauJensen | amalloy: I think you confused the man though |
| 02:34 | yayitswei | oh wait, that's pseudocode |
| 02:36 | amalloy | LauJensen: you're right, i should have used more parens and %s. that helped make your example more readable :) |
| 02:37 | LauJensen | ah you resort to mocking now do you? :D |
| 02:38 | amalloy | yeah, i gave up on actually looking smarter a while ago |
| 02:39 | yayitswei | amalloy: you're right though, I did want a nested hash. it took me a while to digest yours and Lau's suggestions |
| 03:01 | LauJensen | yayitswei: I understand why amalloys was hard to digest, but mine was quite elegant was it not? :D |
| 03:02 | amalloy | *laugh* |
| 03:06 | LauJensen | Here's a nested version |
| 03:06 | LauJensen | ,(for [f (list first second)] (reduce #(assoc %1 (f %2) (conj (%1 (f %2) []) %2)) {} [[30 9 2010] [30 10 2010] [31 10 2010]])) |
| 03:06 | clojurebot | ({31 [[31 10 2010]], 30 [[30 9 2010] [30 10 2010]]} {10 [[30 10 2010] [31 10 2010]], 9 [[30 9 2010]]}) |
| 03:10 | amalloy | well, now that LauJensen has proved he's the best i'm off to bed |
| 03:11 | amalloy | night folks |
| 03:11 | yayitswei | LauJensen: ah, thanks! very much appreciated. amalloy too :D |
| 03:11 | LauJensen | amalloy: dont forget to follow bestinclass.dk, sleep tight |
| 03:11 | yayitswei | night |
| 03:11 | amalloy | haha |
| 03:11 | LauJensen | :D |
| 03:21 | Nafai | Is there an easy way to call out to another process from within my clojure code? |
| 03:22 | LauJensen | Nafai: elaborate |
| 03:23 | Nafai | I want to get the output of an external program and then process it in Clojure |
| 03:23 | Nafai | It's not something I've ever had to do in Java either |
| 03:23 | LauJensen | ,(doc sh) |
| 03:23 | clojurebot | It's greek to me. |
| 03:23 | LauJensen | Nafai: In contrib there's an 'sh' function, (sh "ls" "-l") will return a string, representing the output from ls -l |
| 03:24 | Nafai | Sweet, thanks. |
| 03:24 | LauJensen | np |
| 03:43 | cpfr | Hey is there a nice way to do introspection on java class instances |
| 03:49 | hoeck | cpfr: bean? |
| 03:49 | hoeck | ,(bean "foo") |
| 03:49 | clojurebot | {:empty false, :class java.lang.String, :bytes #<byte[] [B@1d4ea6c>} |
| 03:53 | cpfr | all bean is telling me is the class |
| 03:55 | hoeck | cpfr: it uses public fields only, yes |
| 03:56 | cpfr | but this class has to have some public fields or methods |
| 03:56 | cpfr | how else would it useful |
| 03:57 | hoeck | bean only creates a map of the class public fields |
| 03:59 | jarpiain | no, bean calls the methods named getFoo() and isFoo() and returns a map of the results |
| 03:59 | hoeck | jarpiain: sorry, you're right, lived too long in clojure land |
| 04:43 | jave | hello |
| 04:44 | jave | I'm having difficulty setting headers in a compojure response |
| 04:45 | AWizzArd | jave: how do you try to do it? |
| 04:46 | jave | (GET "/header" [] {:headers {"Content-Type" "image/svg+xml"} :body "body"}) |
| 04:47 | AWizzArd | (defn handler [request] ... [{:headers {"Content-Type" "application/json"}} "<html><head></head><body>Hallo Leute</body></html>"]) |
| 04:47 | AWizzArd | I return a vector of two elements. |
| 04:48 | jave | hmm |
| 04:48 | AWizzArd | The first, a map, only contains one key/value pair, and the second is the body string. |
| 04:48 | AWizzArd | Try if this works for you. |
| 04:49 | jave | ok |
| 04:54 | xkb | if this is the input: (MyMona.core/draw-polygon graphics {:color {:red 55, :green 2, :blue 62, :alpha 231}, :points [{:x 121, :y 89} {:x 102, :y 17} {:x 3, :y 17} {:x 46, :y 82} {:x 150, :y 6}]}) How would I get :points using destructuring? |
| 04:56 | xkb | I'm using 2 nth's now |
| 04:56 | xkb | really ugly and sometimes returns errors on persistenvector not being able to do nth :? |
| 04:57 | LauJensen | java (content-type (response x y z) "image/svg+xml") |
| 04:57 | LauJensen | jave even |
| 04:58 | hoeck | xkb: (let [{c :color p :points} ...]) |
| 04:59 | xkb | hoeck: even if :points is nested in the seq? |
| 04:59 | hoeck | (let [{c :color [p0 p1 p2 p3 p5 :as p] :points} ...]) |
| 04:59 | hoeck | or {[p0 p1 & pn :as p] :points]} .. |
| 05:00 | xkb | let me try it in the repl |
| 05:01 | hoeck | and to get the x and y of each point: (let [{[{x0 :x y0 :y} {x1 :x y1 :y}] :points} ...]) |
| 05:02 | xkb | Thanks, Ill tinker around with it |
| 05:02 | hoeck | xkb: basically two rules, maps are destructured by writing the symbol to bind to first, then the key |
| 05:03 | hoeck | xkb: and for vectors, just write the structure of the vector on the left side of the let :) |
| 05:04 | hoeck | xkb: this explains all the details: http://clojure.org/special_forms#Special%20Forms--%28let%20[bindings*%20]%20exprs*%29 |
| 05:04 | xkb | cool! nice link |
| 05:05 | xkb | got alot of inspiration to rewrite my code at the conj :) |
| 05:48 | ordnungswidrig | how can I get the ns of a function? (->> foo meta :ns) only works for fn hold in a var, not for reduce, e.g. |
| 05:50 | raek | ordnungswidrig: if you have the symbol, you can use 'resolve' |
| 05:50 | raek | ,(resolve 'conj) |
| 05:50 | clojurebot | #'clojure.core/conj |
| 05:50 | ordnungswidrig | raek: I need the other way round |
| 05:50 | Chousuke | a function might not have a name |
| 05:50 | Chousuke | hmm |
| 05:50 | ordnungswidrig | Chousuke: ok, for those that have a name |
| 05:50 | Chousuke | ,(meta (fn [])) |
| 05:50 | clojurebot | nil |
| 05:50 | ordnungswidrig | ,(meta reduce) |
| 05:51 | clojurebot | {:line 786} |
| 05:51 | raek | ,(meta conj) |
| 05:51 | clojurebot | {:line 77} |
| 05:51 | ordnungswidrig | or will clojure.core map to the empty ns? |
| 05:51 | raek | the function is unaware of the name of any var pointing to it |
| 05:51 | Chousuke | I suppose the function might not even have a namespace |
| 05:52 | Chousuke | it could be an IFn instance passed to you from some java user. |
| 05:52 | ordnungswidrig | Chousuke: I see |
| 05:52 | ordnungswidrig | Chousuke: but the var has a name |
| 05:52 | ordnungswidrig | and an ns |
| 06:07 | jave | how does compojure routes relate to ring handlers? |
| 06:07 | jave | basically I'm now trying something like this, but its not working: (ring.util.response/content-type (GET "/header" [] (overview)) "image/svg+xml") |
| 06:29 | AWizzArd | ordnungswidrig: isn't the NS on the meta data? |
| 06:29 | AWizzArd | jave: did it work? |
| 06:30 | AWizzArd | you did not give feedback so far ;) |
| 06:31 | jave | AWizzArd: sorry.... |
| 06:32 | jave | it didnt work |
| 06:32 | jave | I'm scratching my head here |
| 06:35 | AWizzArd | Maybe the behaviour changed. I am using an older version of Compojure. |
| 06:35 | jave | yes maybe |
| 06:42 | raek | jave: I'm not sure you can attach middleware that way |
| 06:43 | jave | problem is there is so many conflicting docs on compojure because of the many revisions |
| 06:43 | raek | it seems like you have to wrap the whole routes thingy in the middleware, rather than just the GET part |
| 06:43 | raek | jave: I would recommend Moustache |
| 06:43 | raek | the docs are very clear |
| 06:43 | jave | ok |
| 06:44 | jave | but does moustache replace compojure, or what is the relationship? |
| 06:44 | raek | moustache is a routing lib |
| 06:44 | raek | so it replaces defroutes |
| 06:45 | jave | ok |
| 06:45 | raek | you use it with ring as I guess you use compojure with ring |
| 06:45 | jave | so, what would my simple case look like then? I just want to set the content-type header |
| 06:46 | raek | using middleware is very simple |
| 06:46 | raek | http://gist.github.com/644761 |
| 06:47 | raek | that is what I have in one of my projects |
| 06:47 | raek | the (app ...) form creates a ring handler |
| 06:47 | raek | you can prefix you routes with any number of middlewares |
| 06:48 | jave | cool ill have a look |
| 06:48 | raek | here's the moustache docs |
| 06:48 | raek | http://github.com/cgrand/moustache |
| 06:48 | raek | if you are used to reading grammars, you'll love this: http://moustache.cgrand.net/syntax.html |
| 07:00 | bartj | chouser, does clojure-jna also support calling third-party c++ libraries ? |
| 07:00 | bartj | chouser, from Clojure that is |
| 07:48 | _na_ka_na_ | Hi, can I rely on using (:sigs AProtocol) to create me helper macros? |
| 07:48 | _na_ka_na_ | Hi, can I rely on using (:sigs AProtocol) to create me helper macros? |
| 07:48 | _na_ka_na_ | or is there some other way to extract fn specs from a protocol |
| 08:16 | chouser | _na_ka_na_: I don't think it's documented anywhere, so that detail could probably change without warning. |
| 08:17 | chouser | but would likely be replaced by something else with similar information, right? So, at your own risk... :-) |
| 08:17 | _na_ka_na_ | chouser: thanks :) |
| 08:21 | ordnungswidrig | I'm playing with clojure agent. the tx spanning a dosync body will commit/rollback the state of all ref written, right? |
| 08:22 | raek | from outside the tx, all refs will seem to be untouched if the tx failed |
| 08:23 | raek | i.e., all ref changes remains transaction-local until the transaction succeeds |
| 08:23 | ordnungswidrig | raek: and in the case (dosync (dosync (alter foo …) (alter bar …)) (alter foo bonk) when bonk fails, then bar remains altered? |
| 08:24 | raek | no, the outermost transaction gets restarted |
| 08:24 | ordnungswidrig | nice |
| 08:24 | raek | also, calls to send and send-off inside a transaction is held until it succeeds |
| 08:24 | ordnungswidrig | in what way can a tx fail? exception or validator, right? |
| 08:25 | raek | that or another transaction modified a ref that the current transaction relied on |
| 08:25 | raek | in the latter case, the transaction is simply restarted |
| 08:26 | ordnungswidrig | in case of exception will the tx be rolled back and the exception bubbles? |
| 08:27 | raek | yes |
| 08:27 | ordnungswidrig | and in case of a validator? |
| 08:27 | raek | same thing |
| 08:27 | ordnungswidrig | exception? |
| 08:27 | clojurebot | http://paste.lisp.org/display/74305 |
| 08:28 | raek | both will result in that no refs were changed, and that an exception comes out from the dosync block... |
| 08:28 | ordnungswidrig | raek: Ok, thanks for the tutoring :) |
| 08:28 | raek | np :) |
| 08:29 | ordnungswidrig | raek: to give you some context: I play with event-sources / cqrs using clojures stm. |
| 08:29 | ordnungswidrig | s/event-sources/event-sourcing/ |
| 08:29 | sexpbot | <ordnungswidrig> raek: to give you some context: I play with event-sourcing / cqrs using clojures stm. |
| 08:31 | raek | note that in clojure, you can have multiple threads banging on the same refs without concurrency problems |
| 08:32 | raek | but thanks for the link. this looks interesting. |
| 08:35 | ordnungswidrig | interessting case with multiple threads. when doing command queueing / event sourcing you generally assume a serializable fixed order of events. thus you serizalize them at the outermost façade. |
| 08:36 | ordnungswidrig | however when using a STM and CAS then you can also "listen" to the events acutally applied to the refs. |
| 08:37 | ordnungswidrig | say, I don't care if the events were '(withdraw account1 200) (withdraw account2 100)' or vice-versa. |
| 08:43 | raek | I would be very interested in hearing about any findings you make in this STM + Event Souring area |
| 08:43 | ordnungswidrig | raek: any idea on how to capture the actual order of function application that where applied to refs? |
| 08:44 | raek | ordnungswidrig: well, there is add-watch |
| 08:44 | raek | but then, you only get the value before and the value after |
| 08:45 | raek | but if you store a [value event-causing-this-value] tuple in the ref, maybe it could be used anyway |
| 08:47 | raek | (def a (ref [0 {:type :new-account}])) (defn withdraw [a x] (dosync (alter a (fn [[balance _]] [(dec balance) {:type :withdrawal, :amount x}])))) |
| 08:48 | ordnungswidrig | reak: i've seen the approach to attach the event as meta value onto the agent state and use add-watcher to extract the event out of the state. |
| 08:49 | raek | interesting |
| 08:49 | raek | I don't have much experience with this, so this is all speculative ideas I have... |
| 08:49 | ordnungswidrig | but multiple agents mean multiple threads and I don't see where a "global" order of event can come from. |
| 08:50 | raek | you would need a master agent of some sort |
| 08:50 | ordnungswidrig | except the add-watchers sending the events to another agent "receiving" them |
| 08:50 | ordnungswidrig | yes |
| 08:50 | ordnungswidrig | on the watcher's side, right? not the "input" side. |
| 08:51 | raek | yes |
| 08:51 | raek | is there any need for one global event sequence? |
| 08:51 | raek | it could be constructed by merging the event sequences for all the refs |
| 08:52 | raek | if transactions are used, changes that affect multiple refs will be safe |
| 08:52 | ordnungswidrig | but merge how? the events could depend on each other in theory. |
| 08:52 | raek | if you have, say, two accounts, each in one ref |
| 08:53 | ordnungswidrig | say that e2 on ref2 depends on a certain state of ref1 which was produced by earlier event e1 |
| 08:53 | ordnungswidrig | both in different threads. |
| 08:53 | ordnungswidrig | the tx for e1 already was committed when e2 executed |
| 08:53 | raek | then e2 will be restarted with the new state |
| 08:53 | raek | you can't change refs outside transactions |
| 08:55 | raek | assuming that the change described by e2 is done in a transaction too... |
| 08:56 | chouser | don't forget about commute |
| 08:57 | cgrand | ordnungswidrig: you may also consider proxying refs you want to instrument, hence you will get access to the actual fn and args passed to commute or alter (disclaimer: half functioning brain here) |
| 08:57 | chouser | cgrand! |
| 08:57 | cgrand | chouser! |
| 08:58 | angerman | I wish there was something like Ingredients for java ... |
| 08:59 | cgrand | what are Ingredients? |
| 08:59 | angerman | http://fileability.net/ingredients/ |
| 09:00 | cgrand | thanks! |
| 09:00 | chouser | cgrand: which Guy Steele paper talked about keeping s-exprs as late in the macroexpand process as possible? |
| 09:00 | ordnungswidrig | yes, e2 sees the new state of e1. but the validator for e2 will check that a certain state of ref1 exists. e.g. |
| 09:00 | ordnungswidrig | so e2 must be later executed after e1 |
| 09:02 | cgrand | his thesis about RABBIT, and it was not only in the macroexpand phase in was in the whole compiler (macroexpansion, alpha rename, cps transform etc.) |
| 09:02 | chouser | ok, thanks |
| 09:02 | cgrand | yw |
| 09:03 | ordnungswidrig | chouser: do you have an example on commute? I understand the theory but I never saw how to use it. |
| 09:05 | chouser | ordnungswidrig: I mention it because it can allow for two transactions to touch the same ref at "the same time" without either restarting |
| 09:06 | chouser | I don't have a concrete use case for you. It turns I out don't use refs all that often. |
| 09:10 | raek | one example would be if two transactions tries to deposit money to the same bank account, commute would not cause the other transaction to restart. |
| 09:10 | raek | if T1 adds money to the account before T2 is done, it doesn't matter for T2 in this case |
| 09:12 | ordnungswidrig | reak: but when you bank has no cash initially, then withdrawal on t2 might depend on deposit on t1 event when t1 was in a prio tx |
| 09:15 | raek | yes, you would not want to use commute for withdrawals |
| 09:16 | raek | cummute is just like alter, except that the transaction does not restart if some else had changed that ref during the transaction |
| 09:18 | ordnungswidrig | so if I know the all functions applied on a ref are commuting then I can use commute instead, right |
| 09:37 | tonyl | good morning |
| 09:42 | angerman | is there a map that doesn't retain the head? |
| 09:43 | fliebel | Can anyone help me understand zippers? I get the up down left right stuff, but the same can't be said about modifying them. I want to add an item to the bottomrightmost branch. |
| 09:44 | fliebel | I also don't understand the difference between a node and a loc. |
| 09:45 | tonyl | fliebel: I am starting to learn on zippers too, but I found a good quick explanation on how to edit them http://www.exampler.com/blog/2010/09/01/editing-trees-in-clojure-with-clojurezip/ |
| 09:45 | fliebel | So I want to go from [1 2 3 [4 5 [6]]] to [1 2 3 [4 5 [6 7]]] |
| 09:45 | fliebel | tonyl: I'll look at it. |
| 09:46 | chouser | fliebel: a node is one of the things you passed in orignially: a vector or number in your example |
| 09:49 | chouser | a loc is a zipper, that is a node plus its location in the whole tree |
| 09:49 | chouser | (-> [1 2 3 [4 5 [6]]] z/vector-zip z/down z/rightmost z/down z/rightmost z/down (z/insert-right 7) z/root) |
| 09:50 | cgrand | angerman: what do you mean? |
| 09:50 | angerman | cgrand: I guess I ment something like doseq or dotimes :D |
| 09:51 | chouser | the return value of each of those steps from vector-zip through insert-right is a loc. z/root walks from that final loc back to the root loc, and converts the root loc back into a node |
| 09:51 | fliebel | chouser: And what if I don't know the amount of nesting? |
| 09:51 | chouser | fliebel: you'll have to loop. |
| 09:52 | fliebel | chouser: With 'branch?'? |
| 10:06 | ordnungswidrig | does it make sense of have a ref holding a vector of refs? |
| 10:07 | opqdonut | probably not |
| 10:07 | chouser | ordnungswidrig: yes, but may be a premature optimization. Why not just a ref of a vector of values? |
| 10:08 | ordnungswidrig | chouser: i want different stm tx contexts for the contained refs. |
| 10:08 | ordnungswidrig | chouser: and yes, it is premature optimization. |
| 10:11 | angerman | ,(float-array [[ 1 0 0]]) |
| 10:11 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number |
| 10:11 | angerman | hmm .. |
| 10:12 | mefesto | ,(float-array [1 0 0]) |
| 10:12 | clojurebot | #<float[] [F@10a3ffc> |
| 10:12 | angerman | yea, it's 1d though :/ |
| 10:12 | mefesto | ah |
| 10:15 | mefesto | maybe this? |
| 10:15 | mefesto | ,(into-array [(float-array [1 2 3]) (float-array [4 5 6])]) |
| 10:15 | clojurebot | #<float[][] [[F@aaa10> |
| 10:15 | angerman | yea. looks like that. to-array-2d did return obj :) |
| 10:16 | mefesto | oh nice |
| 10:19 | fliebel | chouser: still stuck with zippers :( http://gist.github.com/645022 |
| 10:19 | technomancy | http://p.hagelb.org/hammock.jpg |
| 10:20 | mefesto | s/is/his/ |
| 10:34 | jaley | hey guys! does anyone know if there's a function in core or contrib equivalent to this? ,(first (sort-by last (seq {:a 1 :b 2 :c 0}))) |
| 10:34 | jaley | i find myself using it quite a lot :/ |
| 10:35 | raek | I would write it without the seq call and with val instead of last |
| 10:36 | ordnungswidrig | am I correct, that the validator-fn of a ref reads the new values of any ref in the current ty? |
| 10:36 | ordnungswidrig | s/ty/tx/ |
| 10:36 | chouser | ,(apply max-key #(- (val %)) {:a 1 :b 2 :c 0}) |
| 10:36 | clojurebot | [:c 0] |
| 10:36 | jaley | raek: yes.. that's more sensible |
| 10:37 | jaley | chouser: there is also a min-key |
| 10:37 | chouser | jaley: oh indeed, thanks. |
| 10:37 | chouser | ,(apply min-key val {:a 1 :b 2 :c 0}) |
| 10:37 | clojurebot | [:c 0] |
| 10:38 | jaley | chouser: and thank you, because i hadn't found it either :p |
| 10:38 | Raynes | &(- 10) |
| 10:38 | sexpbot | ⟹ -10 |
| 10:39 | ordnungswidrig | is the difference between refs and agents sync vs. async? |
| 10:41 | raek | ordnungswidrig: validators are used when the transaction body is finished and the changed refs are about to be written |
| 10:42 | ordnungswidrig | raek: so kind of last resort |
| 10:42 | raek | ordnungswidrig: yes, but agents are also uncoordinated |
| 10:42 | raek | well, send operations are held in transactions.. |
| 10:43 | ordnungswidrig | raek: in a agent validator-fn the values of other agents that are derefenced are coordinated? |
| 10:44 | raek | hrm, wait. validators could perhaps be checked at the alter calls. didn't think of that. |
| 10:44 | raek | ordnungswidrig: only reads from refs are coordinated |
| 10:45 | raek | and by coordinated I mean read from a single point in time |
| 10:46 | ordnungswidrig | hmm |
| 10:49 | ordnungswidrig | ok, I think i've bean bitten by the uncoordinated part in agent :-) |
| 10:50 | ordnungswidrig | when I reference a value of an agent in the update function of another agent, than there is no coordination, right? |
| 10:50 | ordnungswidrig | theat means @(send a1 inc) will not necessarily return the new value |
| 10:51 | raek | exactly |
| 10:52 | raek | agents don't guarantee that |
| 10:52 | raek | the only thing you know is that the state transition function will be applied at some time in the future |
| 10:53 | ordnungswidrig | in my example in the update function I need to generade a globally unique id. managing that id with an agent would not work, but with a ref, yes, right? |
| 10:53 | raek | if you need rely on that the transition has been made, maybe agents aren't the best reference type to use in that sutuation |
| 10:54 | raek | a ref would work, since it is synchronous |
| 10:55 | ordnungswidrig | assume each agent would containt the balance of an bank account, than there would be no way to ensure that the sum of balances of all account are positive, right? |
| 11:00 | angerman | image is always black (when painted using paintComponent) though the values in the Raster are not ... |
| 11:01 | raek | i.e., alter does not return until the transition has happened |
| 11:01 | raek | ordnungswidrig: no. by the time you have checked all the accounts, they might have already changed. it sounds like a typical use case of refs... :) |
| 11:01 | raek | "no" as in "there is no way" |
| 11:02 | Raynes | Refs are the only game in town for coordinated change. |
| 11:03 | raek | Raynes: back from the conj? |
| 11:04 | ordnungswidrig | but I should get multiple threads working on this if they work on mostly distinct sets of refs, right? |
| 11:04 | Raynes | raek: I was back yesterday. |
| 11:04 | Raynes | I'm sick as hell. |
| 11:05 | raek | :( |
| 11:05 | Raynes | Blowing blood and such. |
| 11:05 | Raynes | Guess I have a cold and a sinus infection. |
| 11:05 | Raynes | Awaiting antibiotics. |
| 11:07 | raek | refs are safe to use in any number of threads combined with any number of refs. the performance might be bad if every thread alters every ref, though... |
| 11:08 | raek | ordnungswidrig: also, have you seen this? http://blip.tv/file/812787 |
| 11:09 | ordnungswidrig | raek: thanks for the pointer |
| 11:09 | Raynes | raek: If you've got the time, I'd be interested in hearing of the presents you've written me. |
| 11:10 | ordnungswidrig | raek: yes, if every tx reads every ref (like in the global balance example) then this cannot be parallelized |
| 11:14 | raek | Raynes: if course! :) |
| 11:14 | raek | wait 10 minutes and I'll commit what I'm working on right now |
| 11:15 | raek | just need to test it first |
| 11:25 | rdeshpande | howdy |
| 11:27 | rdeshpande | ls |
| 11:27 | rdeshpande | dfls |
| 11:27 | rdeshpande | oops - sorry about that |
| 11:27 | tonyl | hehe |
| 11:33 | kevins | trying to get my clojure chops up but I'm having trouble getting my imperative head around this. This produces the first 1000 digit long fib number, but I need to know how many fibs came before it (i.e. some kind of counter while it's looping..how many calls to fibs were made?) I don't really know where to put something like a counter....Have a feeling I'm using the wrong approach. |
| 11:33 | kevins | (use 'clojure.contrib.lazy-seqs) |
| 11:33 | kevins | (take 1 (filter #(= (count (str %)) 1000) (fibs))) |
| 11:34 | chouser | kevins: how about take-while instead of filter? |
| 11:36 | KirinDave | kevins: I'd rewrite it to use keep-indexed. |
| 11:37 | florianjunker | aleph's websocket support is broken. In 0.1.0 it works, in 0.1.2 it doesn't. |
| 11:38 | abrooks | I hope the videos are up soon. I keep wanting to link people to the various talks. |
| 11:38 | KirinDave | kevins: Something like this: |
| 11:39 | KirinDave | ,(take 5 (keep-indexed #(when (even? %2) [%1 %2]) (iterate inc 0))) |
| 11:39 | clojurebot | ([0 0] [2 2] [4 4] [6 6] [8 8]) |
| 11:39 | KirinDave | kevins: (when ...) is your friend for keep and keep-indexed. |
| 11:45 | angerman | how would you write a histogram function in clojure? basically I have a sequence of all values. and now I'd need a value -> count mapping. |
| 11:46 | chouser | angerman: use, or refer to the source of, 'frequencies' |
| 11:47 | angerman | hmm let's see |
| 11:48 | mefesto | that should be in core as of 1.2 |
| 12:13 | raek | how does this SNAPSHOT convention work? if I have "1.0.1-SNAPSHOT", is the next stable version "1.0.1" or "1.0.2"? |
| 12:13 | flx_ | , (doc let) |
| 12:13 | clojurebot | "([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein." |
| 12:14 | cemerick | raek: the convention is that XXX-SNAPSHOT indicates unstable/development versions of XXX. |
| 12:16 | jweiss | if my macro just expands into a defn, i don't need to worry about using gensym on the args list right? because those symbols are only inside the scope of the defn anyway... right? |
| 12:18 | dpritchett | snapshot is a prerelease designation i believe |
| 12:18 | dpritchett | so it predates 1.0.1 |
| 12:19 | dpritchett | also http://semver.org/ |
| 12:22 | LLLLO | how would you go about stripping all mark-up from a html page |
| 12:23 | apgwoz | LLLLO: have a look at tagsoup (http://home.ccil.org/~cowan/XML/tagsoup/) |
| 12:23 | raek | LLLLO: I would use enlive and do a http://gist.github.com/645239 on the interesting node |
| 12:23 | raek | LLLLO: also, envlive uses tagsoup for the parsing |
| 12:24 | apgwoz | LLLLO: what raek said, my next thing was to just pull out all the text nodes |
| 12:24 | LLLLO | hm |
| 12:24 | LLLLO | that single function does all that? |
| 12:24 | raek | an example of a titlebot that pulls out the title element http://github.com/raek/lcug-examples/raw/master/bot/src/se/raek/lcug/titlebot.clj |
| 12:24 | LLLLO | oh right, it requires to parse them into nodes first |
| 12:24 | LLLLO | what kind of nodes? |
| 12:24 | raek | however, it should use the function I posted before... currently it only takes the first text node |
| 12:25 | pdlogan | jweiss: if you are introducing new variables and splicing in a body of arbitrary expressions you need to ensure your new variables do not hide those in the body that should be "free" |
| 12:25 | raek | <foo bar="baz"><a/>quux</foo> --> {:tag :foo, :attrs {:bar "baz"}, :content ({:tag :a} "quux")} |
| 12:26 | LLLLO | tbh I first have to figure out where to put my downloaded clojure jars to be able to use them in REPL in clojurebox |
| 12:26 | pdlogan | OTOH if you are only creating new variables the programmer has explicitly designated as "new bindings" then you should be fine. |
| 12:26 | jweiss | pdlogan: ok like in a let inside the defn. |
| 12:26 | jweiss | i think i should be fine there, thanks |
| 12:26 | raek | LLLLO: use a project management tool like Leiningen or Cake |
| 12:27 | LLLLO | will that work with slime? |
| 12:27 | ivey | LLLLO: "lein swank" starts a swank server inside the project |
| 12:27 | pdlogan | jweiss: e.g. (let [a 1 b 2] (jweiss-macro ... (+ a b) ...)) |
| 12:27 | raek | yes, you run lein swank in the project and connect to it with slime-connect from emacs |
| 12:28 | raek | LLLLO: http://github.com/technomancy/leiningen#readme |
| 12:28 | ivey | LLLLO: also, http://github.com/technomancy/durendal ... durendal-jack-in starts appropriate swank with lein, starts slime and connects it up |
| 12:28 | raek | oh, neat! |
| 12:28 | pdlogan | if jweiss-macro defines a or b in a new scope then "bad macro" |
| 12:29 | raek | LLLLO: look at the project.clj file of http://github.com/raek/lcug-examples/tree/master/bot/ for an example project.clj |
| 12:29 | pdlogan | it's always safe to gensym if you want "hidden" variables |
| 12:29 | jweiss | pdlogan: my generated code won't be needing to refer to anything outside its own scope |
| 12:30 | raek | the things you are interested in are probably the line containing enlive and swank-clojure |
| 12:30 | jweiss | well, ok some things, but i know the data passed to the macro will never collide with those things |
| 12:30 | LLLLO | man.... |
| 12:30 | apgwoz | jweiss: "never" is an interesting word |
| 12:30 | LLLLO | back to make files and make command-line app, are we? |
| 12:30 | ivey | LLLLO: some of us never left... |
| 12:30 | LLLLO | I know |
| 12:30 | ivey | :-) |
| 12:31 | jweiss | well, the alternative is to have unreadable arg names on the fn my macro generates |
| 12:31 | raek | well, you do not have to worry about the CLASSPATH anymore |
| 12:31 | pdlogan | jweiss: if your macro includes the programmer's own expressions then there is a chance you could collide, that is all. |
| 12:31 | apgwoz | jweiss: the problem with macro expansion is the context that it's expanded in. that's how you get name capture. |
| 12:31 | raek | and with durendal, it seems that you don't even have to run the commands manually |
| 12:31 | apgwoz | if you can be sure that your macro only ever expands at the toplevel, then you're pretty much ok |
| 12:31 | jweiss | pdlogan: no expressions are passed to the macro |
| 12:32 | apgwoz | but, if your macro could be expanded within any other form, there's trouble |
| 12:32 | apgwoz | ... or at least potential trouble |
| 12:32 | raek | basically, Leinginen takes care of downloading the right jars and starting clojure with them on the classpath |
| 12:32 | jweiss | and i already know the context in which it should be expanded - all i'm doing is taking a data structure that defines an xmlrpc api, and defn'ing everything in there so that i have real clojure fn's instead of having to call the xmlrpc client explicitly every time. |
| 12:34 | LLLLO | hm |
| 12:35 | LLLLO | what does this do: (defn somefn [&rest] rest) |
| 12:36 | dpritchett | durendal-jack-in sure is taking its time for me, wonder if i can peek into it to see if it's working |
| 12:36 | dpritchett | i have a simple app going that i was using a manual lein swank + slime-connect process with before |
| 12:36 | dpritchett | is there a specific context i need to be in when i invoke durendal-jack-in? |
| 12:36 | ivey | dpritchett: it's a little slow for me too. it's starting swank, and i think it waits a while to make sure it's running fully |
| 12:36 | tonyl | LLLLO: [&rest] puts the rest of the arguments passed to the function in a vector |
| 12:36 | technomancy | it actually doesn't have to poll; it just waits for swank to announce it's listening on a port |
| 12:37 | technomancy | but it has no error reporting, which is awful. |
| 12:37 | ivey | yeah whoever wrote it should be ashamed |
| 12:37 | LLLLO | tony1, it doesn't |
| 12:37 | dpritchett | so where do i invoke it from? I've got core.clj open in a window and i did a jack-in and my server is still "starting" 30s later |
| 12:37 | tonyl | ,(let [f (fn [& rest] rest)] (f :wer 4 5 3 "ewr")) |
| 12:37 | clojurebot | (:wer 4 5 3 "ewr") |
| 12:37 | LLLLO | if I run it with more than 1 argument it throws an exception |
| 12:37 | technomancy | LLLLO: needs a space between & and rest |
| 12:38 | tonyl | there should be a space between & and rest or whatever you want to name the sequence of arguments |
| 12:38 | tonyl | yup |
| 12:38 | LLLLO | right... but if there is no space, why does it return some weird object? |
| 12:38 | LLLLO | ,((fn [&rest] rest) "ha") |
| 12:38 | clojurebot | #<core$rest clojure.core$rest@e6529c> |
| 12:39 | LLLLO | wat? |
| 12:39 | clojurebot | For Jswat: start clojure with -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888 |
| 12:39 | LLLLO | lol |
| 12:39 | amalloy | ,(let [&rest 1] [rest &rest]) |
| 12:39 | clojurebot | [#<core$rest clojure.core$rest@e6529c> 1] |
| 12:39 | technomancy | LLLLO: that's the value of the clojure.core/rest function, which is what the last thing in the fn resolves to |
| 12:39 | amalloy | LLLLO: ^^ |
| 12:39 | tonyl | lol |
| 12:39 | LLLLO | ok makes sense now |
| 12:41 | dpritchett | yeesh, i mustve invoked it wrong. i can only find two durendal- functions available when i tab-complete from M-x |
| 12:41 | dpritchett | even though there are plenty more in the source |
| 12:41 | replaca | chouser: do you have any idea how to get my showoff preso onto heroku, but use your showoff rather than schacon's gem? |
| 12:41 | dpritchett | was (require 'durendal) at the bottom of init.el not enough? |
| 12:41 | technomancy | dpritchett: there's a distinction between interactive M-x commands and functions that only are called from elisp |
| 12:42 | dpritchett | ah |
| 12:42 | dpritchett | so putting (require 'durendal) \n (durendal-enable) on successive lines in init.el is good enougH/ |
| 12:42 | dpritchett | or do i even need to run the enable command? |
| 12:42 | ivey | dpritchett: I don't run enable, and only call jack-in when I need it. It's the only piece I use so far. |
| 12:44 | dpritchett | thanks |
| 12:46 | LLLLO | "Closing over data is far more general than the simplistic model offered by private, protected, public, friend, et al. in OO languages." -> also 50 times slower |
| 12:46 | LLLLO | price to be paid |
| 12:47 | cemerick | LLLLO: why "50x slower"? |
| 12:48 | dpritchett | i did a quick `killall java` and and restarted emacs and durendal seems happy now. thanks for the tips |
| 12:48 | LLLLO | Don't know, but that's what my tests show |
| 12:48 | cemerick | LLLLO: I'm fairly confident your tests are wrong. :-) |
| 12:48 | LLLLO | creating closures means generating entire class :) |
| 12:48 | cemerick | only once, when the code is compiled |
| 12:48 | technomancy | 50 times slower to compile might be true, but the runtime cost is negligible. |
| 12:49 | LLLLO | no, since each closure is unique in regards to the data captured |
| 12:49 | LLLLO | it can't be created only once |
| 12:49 | cemerick | LLLLO: the bindings that are closed over changes every time you create one? Quite untrue. |
| 12:50 | LLLLO | ,(time (dotimes [n 100000] (Integer. n))) |
| 12:50 | clojurebot | "Elapsed time: 30.926 msecs" |
| 12:50 | technomancy | LLLLO: you're confusing creating a new class with creating a new instance. |
| 12:51 | LLLLO | still the times don't lie |
| 12:51 | dnolen | ,(time (dotimes [n 100000] (let [n (Integer. n)] (fn [] n))) ) |
| 12:51 | clojurebot | "Elapsed time: 21.67 msecs" |
| 12:52 | LLLLO | yes now try to make the closure function like an object with 3 fields |
| 12:52 | cemerick | odd, that was faster than *not* using a closure ;-) |
| 12:52 | dnolen | LLLLO: but why you do that? |
| 12:53 | LLLLO | I don't know...maybe because it's given as an example in every clojure book? |
| 12:53 | LLLLO | as in, what you're supposed to do with the power of closures instead of using objects |
| 12:53 | dnolen | LLLLO: what books? |
| 12:53 | LLLLO | Clojure in Action for one |
| 12:54 | LLLLO | I'm pretty sure that Programming Clojure has the same thing |
| 12:54 | amalloy | LLLLO: closures are implemented as anonymous classes with an invoke() method. their constructor takes N arguments, one for each object it closes around |
| 12:54 | amalloy | creating a closure is just a new X() - it's not slow |
| 12:54 | cemerick | LLLLO: I'd suggest pasting an example of these tests you've run, so this can get concrete. |
| 12:54 | dnolen | LLLLO: I'm pretty sure nothing of the kind is strongly recommended in Programming Clojure or Joy of Clojure |
| 12:54 | dnolen | LLLLO: so not sure what you mean by "every book" |
| 12:55 | LLLLO | also several websites advocate this |
| 12:55 | LLLLO | http://www.nofluffjuststuff.com/blog/stuart_halloway/2009/08/rifle_oriented_programming_with_clojure |
| 12:55 | LLLLO | here's one |
| 12:58 | dpritchett | hey, durendal works better when you're running the latest clojure-mode |
| 12:58 | dpritchett | thanks for folding in the repl syntax highlighting technomancy |
| 12:58 | dnolen | LLLLO: Heh, yeah I wouldn't recommend that at all. using Closures to simulate mutable objects in Clojure is a terrible idea beyond understanding that it's possible. |
| 12:58 | LLLLO | strangely the difference is smaller here than on my work computer |
| 12:59 | LLLLO | what would you do instead? |
| 12:59 | dnolen | LLLLO: defrecord |
| 12:59 | LLLLO | (defn new-int [n] |
| 12:59 | LLLLO | (fn [comm] (cond |
| 12:59 | LLLLO | (= comm :value) n |
| 12:59 | LLLLO | (= comm :radix) 10))) |
| 12:59 | LLLLO | this for instance |
| 12:59 | LLLLO | (time (dotimes [n 100000] (new-int n))) |
| 12:59 | LLLLO | "Elapsed time: 13.852232 msecs" |
| 12:59 | LLLLO | (time (dotimes [n 100000] (Integer. n))) |
| 12:59 | LLLLO | "Elapsed time: 3.096241 msecs" |
| 13:00 | LLLLO | on my work computer it was 250 vs 4 |
| 13:00 | LLLLO | or did I code that wrong? |
| 13:00 | Chousuke | you could probably use case for that |
| 13:00 | Chousuke | (case comm :value n :radix 10) |
| 13:01 | LLLLO | case? |
| 13:01 | Chousuke | (doc case) |
| 13:01 | amalloy | Chousuke: he's never calling the function; it doesn't matter what the function does |
| 13:01 | LLLLO | does it use java switch |
| 13:01 | Chousuke | hm |
| 13:01 | LLLLO | yeah I was just testing how fast the closure generation was |
| 13:01 | Chousuke | ah right. I didn't notice that. |
| 13:01 | LLLLO | if it's a bad idea |
| 13:01 | LLLLO | ,(doc case) |
| 13:02 | amalloy | LLLLO: if you're curious, try compiling to .class files and using javap -l (that's L) |
| 13:03 | amalloy | it should show you exactly how much work it is to create a closure, and you can evaluate that yourself |
| 13:03 | LLLLO | hm |
| 13:04 | jarpiain | LLLLO: case compiles into a lookupswitch of the argument's hash code |
| 13:04 | amalloy | but there's no way it's 50 times slower. even if it closed around 50 variables (not sure that's possible) it shouldn't be 50 times slower |
| 13:05 | LLLLO | yeah that's weird then |
| 13:05 | LLLLO | but I'm pretty sure I had such results this morning |
| 13:05 | LLLLO | I am thinking about way I could have screwed it up |
| 13:05 | amalloy | dotimes is not a real benchmark. you get a lot of fluctuation due to, eg, whether your computer is busy syncing email |
| 13:05 | amalloy | or whatever |
| 13:06 | dnolen | LLLLO: well we've been using Clojure for some time now and if the perf for closures was that bad we probably wouldn't be using Clojure ;) |
| 13:06 | amalloy | clojurebot: ping? |
| 13:06 | LLLLO | :D |
| 13:06 | LLLLO | hm gotta look-up the case macro on Clojure Docs |
| 13:06 | amalloy | he seems to be unstable more often now, for some reason |
| 13:06 | amalloy | sexpbot: ping? |
| 13:06 | amalloy | $ ping |
| 13:06 | sexpbot | amalloy: Ping completed in 0 seconds. |
| 13:06 | LLLLO | I have hard time reading (doc case), I don't understand the syntax |
| 13:07 | LLLLO | thank god for examples on Clojure Docs |
| 13:07 | LLLLO | ,(case first first true) |
| 13:07 | amalloy | LLLLO: clojurebot seems to be down. try sexpbot |
| 13:08 | amalloy | ->(case first first true) |
| 13:08 | sexpbot | java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.MapEntry |
| 13:08 | LLLLO | what? |
| 13:08 | LLLLO | ->(case :first :first true) |
| 13:08 | sexpbot | java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.MapEntry |
| 13:09 | LLLLO | ok this is weird |
| 13:09 | cemerick | jeez, are both bots hosed? |
| 13:10 | jarpiain | seems to be the bug I reported |
| 13:10 | jarpiain | http://www.assembla.com/spaces/clojure/tickets/438-case*-and-code-walkers |
| 13:10 | LLLLO | ->(+ 1 2) |
| 13:10 | sexpbot | ⟹ 3 |
| 13:10 | amalloy | yeah, clojurebot is hosed, sexpbot doesn't get case statements, apparently |
| 13:11 | chouser | replaca: no -- let me know if you figure out a way |
| 13:11 | amalloy | LLLLO: your case statement works fine in a real repl |
| 13:11 | cemerick | why would it be doing any code-walking though? |
| 13:11 | LLLLO | oh ok |
| 13:11 | @rhickey | anyone know what this is tryingto tell me? : |
| 13:11 | @rhickey | "/Users/rich/dev/clojure/build.xml:90: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds" |
| 13:11 | LLLLO | well the second one works, the first one doesnt |
| 13:11 | amalloy | LLLLO: that's because first isn't a compile-time constant, but :first is |
| 13:11 | chouser | replaca: I've moved all my "patches" except clojure syntax highlighting into the presentation itself, so that's the only thing missing when I push to heroku |
| 13:12 | cemerick | rhickey: you want to set includeantruntime="false" in your javac task usage (see http://www.jajakarta.org/ant/ant-1.6.1/docs/en/manual/CoreTasks/javac.html) |
| 13:12 | cemerick | Or, *it* wants you to do that |
| 13:13 | @rhickey | this message just started to appear after updating Java on my machine |
| 13:13 | @rhickey | i.e. build.xml hasn't changed |
| 13:14 | cemerick | rhickey: not sure what that indicates. I'm a long way from my ant days. |
| 13:18 | cemerick | rhickey: This may or may not help. Did you upgrade your ant install too? http://ant.1045680.n5.nabble.com/warning-includeantruntime-was-not-set-td2639463.html |
| 13:40 | amalloy | wow, i just stepped into ##java for a minute since i have to do some java for work. i now appreciate how friendly #clojure is |
| 13:40 | cemerick | yeah, it's a swamp over there |
| 13:40 | cemerick | In their defense, they're pretty constantly bombarded by complete nonsense. |
| 13:41 | amalloy | yeah, i can imagine |
| 13:51 | zkim | amalloy: man you weren't kidding, just seen: "sproingie: then WHAT is your fucking QUESTION?" |
| 13:51 | amalloy | yeah, i can understand being fed up with that guy though |
| 13:53 | amalloy | wow, his program is surprisingly close to being correct given how clueless he makes himself sound |
| 13:54 | zkim | hah |
| 13:55 | kumarshantanu | hi, is it possible to get a list of all vars in a namespace? e.g. clojure.core |
| 13:55 | zkim | kumarshantanu: http://clojuredocs.org/clojure_core/clojure.core/ns-map |
| 13:55 | cemerick | kumarshantanu: see ns-interns |
| 13:58 | kumarshantanu | zkim: cemerick: thanks |
| 14:00 | chouser | ,(dir clojure.set) |
| 14:00 | dpritchett | don't forget ##javascript - that place is scary |
| 14:00 | amalloy | chouser: clojurebot is down, sexpbot is working |
| 14:01 | amalloy | dpritchett: *shudder* never will i ever. maybe i'll try #jquery if i have problems :P |
| 14:02 | dpritchett | i just discovered that clojure-mode had a new version when durandel.el invoked a nonexistent function - i googled it and wound up in clojure-mode.el. Is there a standard way to keep my elpa stuff up to date? |
| 14:04 | dpritchett | i would recommend #coffeescript if you want js help... just don't tell jashkenas i said so |
| 14:05 | amalloy | nah, if i ever need js help it'll be with jquery *chuckle* |
| 14:05 | zakwilson | paredit seems like a Good Thing in concept, but last time I tried using it, I found it difficult to get used to. Anyone here have opinions about whether it's worth it? |
| 14:05 | amalloy | zakwilson: everyone has opinions about it. they're not all the same |
| 14:05 | zakwilson | amalloy: that tends to be the way of things when it comes to opinions |
| 14:06 | amalloy | i find it convenient, but i've only been using it for a month or two and sometimes i get frustrated cause i can't remember the keystroke for X |
| 14:06 | mabes | zakwilson: I think it is well worth it. It being able to move parens easily, and promote forms is a real time saver IMO |
| 14:07 | amalloy | but i'm definitely in love with M-<up>, M-(, and C-<right>. they're the ones i use all the time |
| 14:07 | mabes | zakwilson: I'm by no means a power user either, I just use the basics. |
| 14:07 | dpritchett | i would like paredit more if i knew basic emacs keyboard navigation I think... trying to figure out how to cut and paste something from outside of a sexp into said sexp was hard with no mouse |
| 14:07 | dpritchett | and i can't just move the parens manually |
| 14:08 | mabes | dpritchett: yeah, I've been using viper mode so I haven't even had to learn all the emacs bindings :) So far it has been pretty nice |
| 14:08 | amalloy | dpritchett: C-<right> is good if they're adjacent already |
| 14:10 | zakwilson | Conceptually, paredit and slime seem to move code editing away from *text* editing and in to a mode of interacting with the *meaning* of the code more directly. It just seems to be a bit of a learning curve. |
| 14:10 | dpritchett | i tried really hard to like viper but it had this 1 second lag on exiting insert mode that just drove me batty |
| 14:10 | dpritchett | i like to think i just set it up wrong.... vim's instantaneous mode switching is key to getting some editor flow going |
| 14:11 | dpritchett | it's hard to walk away from the turtles-all-the-way-down magic of elisp though :( |
| 14:15 | mrBliss | Is it true that finger trees "lookup items in O(n)"? http://david-mcneil.com/post/1393750407/clojure-conj-day-1-notes (search for "lookup") |
| 14:16 | chouser | mrBliss: looks like those notes got a few details mixed up. |
| 14:17 | chouser | double-list has amortized constant time for left and right ends, but the only access to the middle would be linear |
| 14:17 | chouser | counted-double-list can look up by index in O(log(n)) |
| 14:17 | zakwilson | I glanced through the PDF slides. It wasn't clear to me what finger trees are for. |
| 14:18 | mrBliss | what's the difference between the counted-double-list and the double-list (besides the faster look up times)? |
| 14:19 | chouser | :-( |
| 14:20 | chouser | mrBliss: that's pretty much it. counted-double-lists give you fast lookup by index |
| 14:20 | mrBliss | what's the trade-off? |
| 14:21 | amalloy | zakwilson: my understanding is that finger trees are a generalized functional data structure, which make it easy to implement other data structures as special cases of finger trees |
| 14:21 | chouser | oh, time during insert/remove and total meory |
| 14:21 | chouser | memory |
| 14:22 | mrBliss | chouser: thanks for the info. Do you have any idea when they'll be ready? |
| 14:22 | mrBliss | *finished |
| 14:22 | chouser | mrBliss: as soon as you've added the features you need. |
| 14:22 | chouser | :-D |
| 14:24 | zakwilson | I asked this before, but we have some different people around now. I'm doing a bunch of map lookups in a very inner loop. The maps are a few hundred to a few thousand entries, and the purpose of the lookups is to find the common keys between one and the rest. Keys are strings. What, if any speed optimizations might be possible? |
| 14:24 | mrBliss | chouser: I was planning to look into them as soon as they're finished ;-) |
| 14:26 | amalloy | chouser: what still needs work? i might be interested |
| 14:27 | chouser | zakwilson: off the top of my head, you might be able to get O(n) out of sorted-maps vs. what is probably O(n log(n)) |
| 14:27 | chouser | amalloy: mostly just making sure they implement all the clojure.lang.PersistentCollection and java.util.Collection methods properly. I think mostly what's missing there are metadata, equality, hashing, that kind of thing. |
| 14:28 | amalloy | ah, cool. sounds like i might not even need to learn how they work to help, then :) |
| 14:30 | cemerick | g |
| 14:30 | defn | well hello everyone |
| 14:31 | apgwoz | hello defn |
| 14:31 | kumarshantanu | another question -- is it possible to defn a function like this -- (defn (quote (symbol "foo")) [] (println "foo")) ; getting error, but you know the intent |
| 14:31 | apgwoz | kumarshantanu: what's the use case? |
| 14:32 | kumarshantanu | trying to defn functions (root binding) |
| 14:32 | Raynes | kumarshantanu: Not without a macro. |
| 14:32 | Raynes | Or eval, which is just bad juju. |
| 14:32 | kumarshantanu | any examples? |
| 14:33 | chouser | some options: macros, intern, alter-var-root |
| 14:33 | Raynes | Oh yeah, intern. |
| 14:33 | chouser | kumarshantanu: but a clearer description of your specific use case would be helpful |
| 14:35 | kumarshantanu | I am trying to build functions prefixed with "not-" for things like map? vector? empty? nil? etc |
| 14:35 | kumarshantanu | not-map? --> #(not (map? %)) |
| 14:35 | chouser | (complement map?) ? |
| 14:36 | _na_ka_na_ | hello. I'm trying to add a helper macro which takes a protocol and uses its :sigs to emit a deftype, only problem is that the protocol seems not to be available at macroexpand time .. if I put the macro body inside a function it works as expected |
| 14:36 | Raynes | When you find yourself doing stuff like that, remember the comp function as well. |
| 14:36 | Raynes | (comp not map?) |
| 14:36 | mabes | also, for the opposite of empty? you should use seq |
| 14:37 | _na_ka_na_ | kumarshantanu: in addition to what everyone has said .. we have if-not, when-not |
| 14:37 | cemerick | mabes: a contestable point :-) |
| 14:37 | kumarshantanu | I am trying to put them in the root so that they can be available in other namespaces -- is that a correct assumption (is it possible)? |
| 14:38 | kumarshantanu | I am asserting a lot...so "not" prefixed would be handy really |
| 14:38 | replaca | chouser: ahh, thanks. Maybe I'll just let web viewer miss out on that goodness. Are you going to push those syntax updates back to schacon? |
| 14:39 | _na_ka_na_ | kumarshantanu: what do you mean by put them in the root? |
| 14:39 | kumarshantanu | root binding, I meant |
| 14:39 | chouser | if (complement map?) and (comp not map?) are too long, please consider writing your own 'complement' with a name you like rather than mucking about in clojure.core namespace |
| 14:40 | chouser | replaca: hm, I suppose I should. |
| 14:41 | _na_ka_na_ | any ideas on how to write a helper macro which generates deftypes automatically given a protocol n some other args |
| 14:42 | _na_ka_na_ | another option is using a reify to directly give instances at runtime |
| 14:43 | _na_ka_na_ | inside a factory function |
| 14:44 | replaca | chouser: one more way to get Clojure on the map :) |
| 14:45 | amalloy | kumarshantanu: yeah, just this morning i was thinking it might be useful to (def ! complement), then you could eg (def not-map (! map?)) |
| 14:45 | chouser | _na_ka_na_: you need a new class of some kind? you couldn't just generate arguments to a call to 'extend'? |
| 14:45 | _na_ka_na_ | to give an example. (defprotocol P (foo...)) .. (helper-macro T [some params] P & some-args) => (deftype T [some params] P (foo ...)) |
| 14:46 | kumarshantanu | amalloy: In fact I just want to write (not-map? x) instead of (not (map? x)) -- not-* is more readable |
| 14:47 | amalloy | kumarshantanu: that's exactly what my def lets you do...? |
| 14:47 | amalloy | zakwilson: C-c C-c helps |
| 14:47 | kumarshantanu | intern seems to be doing it for me ---- (intern 'user 'foo (println "foo")) ; at the REPL |
| 14:47 | kumarshantanu | amalloy: yeah I need to defn some functions |
| 14:48 | amalloy | kumarshantanu: no, you don't need to defn. you can just def them with complement |
| 14:48 | kumarshantanu | chouser: I won't use it if you suggest so :) |
| 14:48 | _na_ka_na_ | chouser: you mean (deftype T [some params]) .. (extend T P {:foo ..}) ? |
| 14:48 | chouser | kumarshantanu: please consider something like (! map?) or (not! map?) instead of generating vars |
| 14:49 | amalloy | (def not-map (complement map?)) is the same as (defn not-map [x] (not (map? x))) |
| 14:49 | kumarshantanu | amalloy: yes, right...def slipped my mind for a moment |
| 14:50 | _na_ka_na_ | but I think kumar wants not- to be available in all nses like it was in clojure.core if I understand correctly |
| 14:50 | chouser | _na_ka_na_: yes. perhaps (apply extend (helper-fn T [some params] P & some-args)) |
| 14:50 | Raynes | amalloy: Dude. |
| 14:50 | kumarshantanu | chouser: okay...I am fine with (defn not-map? [x] (not (map? x))) ; not-* looks more readable |
| 14:50 | zakwilson | chouser: quick and dirty test with sorted maps reveals it to be 25% slower that way. |
| 14:51 | amalloy | Raynes: yeah? |
| 14:51 | Raynes | amalloy: Couldn't you have left a "I didn't test this" note in your pull request somewhere? :p |
| 14:51 | chouser | zakwilson: you're walking both sorted maps in a O(n) way? |
| 14:51 | _na_ka_na_ | chouser: yes that. extend is used at top-level like that ? |
| 14:52 | chouser | _na_ka_na_: yes, and is a function not a macro, so more composable and allows you to create things that are themselves more composable |
| 14:52 | amalloy | Raynes: sorry. left one last time; this time i either forgot or figured you'd remember i wasn't set up for testing |
| 14:52 | Raynes | amalloy: :p |
| 14:52 | _na_ka_na_ | chouser: thanks again! |
| 14:53 | amalloy | what's broken? i did test that it generated reasonable-looking strings |
| 14:53 | chouser | _na_ka_na_: if you actually need your function to genearte a new class on the fly, reify might useful. Not sure. |
| 14:54 | _na_ka_na_ | chouser: yes both options have their place |
| 14:55 | amalloy | Raynes: um. okay that's kinda an embarrassing commit error. format-time needs another ) |
| 14:55 | Raynes | Indeed. |
| 14:55 | Raynes | ;) |
| 14:55 | zakwilson | chouser: I'm extracting the keys from one and looking it up in all the others using the functions intersection and difference, defined here: http://github.com/zakwilson/zutil-clj/blob/master/map.clj |
| 14:56 | zakwilson | So I guess what I'm really asking is: are these definitions of intersection and difference optimal? |
| 14:56 | amalloy | feel free to amend my commit so that it looks like i never sent that :P |
| 14:57 | chouser | I mean something like (let [o (reify)] (apply extend (class o) (helper-fn ...))) |
| 14:59 | jweiss | is there a recommended alternative to deliberately capturing a scoped variable in a macro? i want to generate a fn that closes over that variable |
| 14:59 | defn | chouser: finish reading lisp : the good parts yet? ;) |
| 15:01 | chouser | defn: no, but well on my way to converting to PDF to be loaded on my book-reading device of choice. |
| 15:02 | _na_ka_na_ | chouser: how is that better than just (reify Proto ...) ? |
| 15:02 | defn | nice :) |
| 15:03 | chouser | zakwilson: my point was that if you require the input maps be sorted by the same comparator, you could walk them both in step, generating your intersection in O(n) time |
| 15:03 | chouser | possibly more complex code, but the time cost would increase more slowly |
| 15:04 | chouser | _na_ka_na_: reify is a macro, so generating args to it has to happen at compile time forcing your helper to also be a macro and therefore get *its* args at compile time |
| 15:05 | chouser | _na_ka_na_: what I showed would allow your helper to be a fn and talk all it's input at runtime, as late as you'd like. |
| 15:09 | zakwilson | chouser: I may just be a little slow, but won't that fail comparing {"a" 1 "c" 3 "e " 5} with {"a" 1 "b" 2 "d" 4 "e" 5} (because it would either walk the whole thing or revert to a normal map lookup to see that "c" isn't there, and either walk until it finds "e" or revert to a normal map lookup)? |
| 15:11 | chouser | zakwilson: I may not be thinking about it deeply enough yet, but I do think you'd have to only advance the cursor that's farther behind. |
| 15:15 | zakwilson | chouser: I think you may be right and I may be thinking about things incorrectly. I will try writing it. |
| 15:15 | AWizzArd | chouser: which things were drilled into your head at the conj? |
| 15:16 | chouser | simple == "not compound", avoid macros, seek composable abstractions |
| 15:16 | chouser | there, now nobody has to regret missing it. |
| 15:17 | pbuckley | chouser: haha :-) |
| 15:17 | pbuckley | "the conj in 8 words" |
| 15:18 | pbuckley | but you left out hammock :-) |
| 15:18 | zakwilson | Are there videos from the conj? |
| 15:18 | chouser | pbuckley: that's a sub-point under "seek" :-) |
| 15:18 | pbuckley | zakwilson: they took video, but getting it edited and ready/posted might take some time |
| 15:18 | AWizzArd | chouser: what do you mean by “simple == "not compound"”? |
| 15:19 | zakwilson | pbuckley: that's to be expected. |
| 15:19 | chouser | AWizzArd: stuarthalloway asserted that "not compound" is the definition of "simple" |
| 15:22 | _na_ka_na_ | chouser: but "not compound" is itself compound :P |
| 15:22 | chouser | heh. not a simple definition. |
| 15:22 | chouser | is there a function to get the comparator of a sorted thing? |
| 15:23 | AWizzArd | unfortunately not |
| 15:23 | Raynes | $dict simple |
| 15:23 | sexpbot | Raynes: adjective: Single; not complex; not infolded or entangled; uncombined; not compounded; not blended with something else; not complicated |
| 15:23 | AWizzArd | chouser: I wished FingerTrees would allow this. |
| 15:24 | chouser | AWizzArd: everything you customize a finger-tree with can be extracted later, I believe |
| 15:28 | alexyk | hey everybody! back in the virtual world, but it will never be the same again. I know what everybody else looks like and where he or she lives! Astonishingly, there were a few "she"s! |
| 15:28 | _na_ka_na_ | chouser: continuing the reify talk .. assuming that let is at the top level, how do I extract the class to form more instances? |
| 15:28 | chouser | zakwilson: I have a sorted-intersection-with that seems to work. Should be O(n+m), worst case, but I haven't tested the performance at all. |
| 15:28 | mefesto | alexyk: great lightning talk! :) |
| 15:28 | alexyk | mefesto: thx! |
| 15:28 | chouser | _na_ka_na_: hm, you want more instances... |
| 15:29 | _na_ka_na_ | chouser: for only one instance I could just create a helper factory fn containing reify ? |
| 15:29 | _na_ka_na_ | w/o extend |
| 15:30 | alexyk | chouser: in case you were left wondering, why I greeted your button with a promise to keep using cake, I have an explanation! :) |
| 15:30 | zakwilson | chouser: link/pastebin/etc? |
| 15:30 | chouser | _na_ka_na_: I'm trying not to recommend anything, just make you aware of options. I usually bad at doing the latter without doing the former. |
| 15:30 | chouser | zakwilson: you want it? Would hate to cheat you of the opportunity. |
| 15:31 | chouser | _na_ka_na_: if you want multiple instances of the same class, perhaps you could create the type first, then pass that class to a helper fn to generate the fns map that would be used by extend. |
| 15:31 | _na_ka_na_ | chouser: in #clojure, its too late for you to not recommend anything, everything you say is "chouser branded" :P |
| 15:31 | _na_ka_na_ | chouser: in clojure irc, its too late for you to not recommend anything, everything you say is "chouser branded" :P |
| 15:31 | zakwilson | chouser: I have the algorithm in my head already, so I don't think I'd learn much by writing it myself. That aside, your code is probably prettier than mine, so I'll improve by reading it. |
| 15:31 | chouser | noooo |
| 15:32 | chouser | _na_ka_na_: your blog is full of things that blow me away. I really must refrain from coaching you! |
| 15:33 | apgwoz | chouser: i have a patch for contrib.command-line, what's the best way to submit it-- to you directly? pull request on github clojure/clojure-contrib project? |
| 15:33 | _na_ka_na_ | chouser: that is exactly my plan :) |
| 15:33 | angerman | how would I transform keys in a hashmap? |
| 15:34 | _na_ka_na_ | chouser: my blog?! I think you are mistaking me for someone else |
| 15:34 | replaca | apgwoz: put a bug on assembla with a patch |
| 15:34 | apgwoz | replaca: ok. cool |
| 15:34 | raek | angerman: (zipmap (map ... (keys m)) (vals m)) |
| 15:34 | angerman | e.g. I have a fucntion scaler: key -> key that I want to apply to all keys |
| 15:35 | replaca | apgwoz: make sure you have a CA in and then follow the instructions here: http://clojure.org/patches |
| 15:35 | chouser | _na_ka_na_: ah, perhaps indeed. I was thinking of nakkaya.com. |
| 15:36 | chouser | zakwilson: http://gist.github.com/645575 |
| 15:37 | apgwoz | replaca: I've signed the CA, though my membership to clojure-dev is still pending, thus I can't request assembla contributor role. though is that for naught anyway, given the eventual switch? |
| 15:37 | zakwilson | chouser: thanks |
| 15:38 | amalloy | clojurebot: ping? |
| 15:40 | replaca | apgwoz: good question. I would just put a bump request on the clojure-dev list. Stuart should give you rights. I don't think they've gotten to the actual issue migration yet. |
| 15:40 | apgwoz | replaca: i can't post to clojure-dev :) |
| 15:41 | apgwoz | regardless, thanks for the help |
| 15:41 | Raynes | alexyk: That was sexpbot. |
| 15:42 | Raynes | clojurebot was passed out behind the stage. |
| 15:42 | alexyk | Raynes: aha! BTW, I missed meeting hiredman. :( What did you look like, hiredman? |
| 15:42 | replaca | hmm, you should be able to request that too. :) |
| 15:42 | alexyk | Raynes: clojurebot misinterpreted the sex in sexpbot |
| 15:42 | apgwoz | replaca: i did, a couple of weeks ago. never got processed apparently |
| 15:42 | Raynes | alexyk: Like David Liebke with uglier facial hair. |
| 15:43 | Raynes | ;) |
| 15:43 | alexyk | Raynes: fewer of those? |
| 15:43 | replaca | hmmm... |
| 15:43 | Raynes | He was standing in front of me talking to danlarkin and friends. |
| 15:43 | alexyk | Raynes: yeah, as if I could remember who stood there! I got an extra white ticket for that! |
| 15:43 | danlarkin | frienddddddddds!!!!!! |
| 15:43 | chouser | apgwoz: it's best to get some input on a patch too, before submitting. I'm no longer reading all g.group messages, but posting there is always good |
| 15:44 | alexyk | quoting Raynes, you guys are my best fwends <3 |
| 15:44 | apgwoz | chouser: yeah, i will certainly do that once I get access. |
| 15:44 | angerman | how would I go about writing a "peak"/"valley" detector on a histogram? |
| 15:44 | apgwoz | chouser: for some reason I was thinking /patches applied only to clojure core, which of course is wrong. :) |
| 15:44 | chouser | apgwoz: just the regular clojure g.group is fine. Here, all I'll add a thing that flags me if the message contains "chouser" |
| 15:45 | alexyk | angerman: partition by two, replace by the sign of the difference |
| 15:45 | angerman | I assume i could move a window with take/drop along the keys of the histogram and check if (max vals ...) == val for key, but that sounds somewhat stupid. |
| 15:45 | raek | apgwoz: is there an issue for the bug/enhancement? if not, you can create one while only being a watcher... |
| 15:45 | angerman | alexyk: it needs to be a bit more robust. |
| 15:45 | angerman | alexyk: the data is not very smooth :( |
| 15:45 | alexyk | angerman: partition by the function > or < |
| 15:46 | alexyk | with a threshold |
| 15:46 | alexyk | ie > by 3 |
| 15:46 | apgwoz | raek: oh. under support. interesting. |
| 15:46 | apgwoz | raek: i was looking only in "tickets" which doesn't have a "new ticket" button anywhere. |
| 15:47 | raek | also, if you create an account, make sure to use a username that is your real name |
| 15:48 | alexyk | angerman: http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/partition-by |
| 15:49 | danlarkin | angerman sounds like hiredman's alternate personality |
| 15:49 | chouser | cemerick: I can probably help with contrib build gruntwork, but I'm in no position to lead or make decisions there. Strikes me as right up your alley :-) |
| 15:49 | angerman | alexyk: that sounds like a good idea I'm still wondering how I'd keep it local. e.g. make sure to only have a window of +-10 datapoints. |
| 15:49 | angerman | danlarkin: sorry to disappoint you :p |
| 15:49 | alexyk | danlarkin: angerman is a fired hiredman! |
| 15:49 | alexyk | oh, that's disgruntledman |
| 15:51 | defn | heh |
| 15:51 | defn | homicidalman |
| 15:51 | alexyk | hey defn! you've made it out of the clutches of RDU! |
| 15:51 | defn | just barely! :) |
| 15:52 | defn | yet another late night on Saturday. Just got into work at 2:30pm |
| 15:52 | alexyk | defn: ALl American Food almost detained me too |
| 15:52 | defn | haha -- luckily i had chouser to keep me awake while I waited to board |
| 15:52 | alexyk | before that, that guy Hohn from DC poured us all on the shuttle some godo whisly from a bottle. Now that's hwo conferences are done. |
| 15:52 | alexyk | John |
| 15:53 | alexyk | who knows John from DC? what's his nick? that guy is my hero now |
| 15:53 | alexyk | he was there with Alex, they are from some government contractor or other; or Maryland, perhaps |
| 15:54 | alexyk | next time, gotta take a flask to the conj, I'll get those cgrand's slides the instant I see them! |
| 15:54 | _fogus_ | alexyk: I know him. |
| 15:54 | alexyk | _fogus_: cool! does he have a Twitter? |
| 15:54 | _fogus_ | good dude |
| 15:54 | defn | back to work |
| 15:55 | defn | ill be around later, ciao |
| 15:55 | alexyk | defn: later |
| 15:55 | pbuckley | alexyk: I don't know his nick on IRC, but he's @sirlyric on twitter |
| 15:55 | alexyk | pbuckley: ah ok, saw him there |
| 15:55 | alexyk | pbuckley: don't you find NH weather a letdown after NC? |
| 15:56 | pbuckley | alexyk: yeah a bit colder - it was warmer outside at night in NC that it is inside my house |
| 15:56 | _fogus_ | that's the one! Was trying hard to remember his twitter id. People should avoid handles for my convenience. :p |
| 15:56 | alexyk | pbuckley: I flew through Philly and it was 70 there. Just rain here. But programming is so much better in the rain! |
| 15:57 | alexyk | _fogus_: at least we learned you really don't have horns! |
| 15:57 | angerman | hmm. adding to the tail of a list is just not easy :( |
| 15:57 | alexyk | angerman: keep adding to the front, then revert the result :) |
| 15:58 | angerman | yea. |
| 15:58 | chouser | ok, putting "chouser" in a message to the clojure user's g.group should be more visible to me now than others. Recommended for anyone wanting me to take a patch for something. :-) |
| 15:58 | raek | angerman: you can append to the back of a vector, then run seq on it |
| 15:59 | raek | ,(loop [x 10, acc []] (if (zero? x) (seq acc) (recur (dec x) (conj acc x)))) |
| 16:00 | raek | ->(loop [x 10, acc []] (if (zero? x) (seq acc) (recur (dec x) (conj acc x)))) |
| 16:00 | sexpbot | ⟹ (10 9 8 7 6 5 4 3 2 1) |
| 16:00 | tonyl | ->(range 10 1 -1) |
| 16:00 | sexpbot | ⟹ (10 9 8 7 6 5 4 3 2) |
| 16:00 | tonyl | ->(range 10 0 -1) |
| 16:00 | sexpbot | ⟹ (10 9 8 7 6 5 4 3 2 1) |
| 16:01 | angerman | damn i ran out of mem ... now emacs hangs |
| 16:03 | chaslemley | hey guys, recently started using clojure solving euler problems and wanted to write something more non-trivial so I worked on this over the weekend, for parsing a haml type html template: https://gist.github.com/2964d548027eb63c19d7 |
| 16:04 | chaslemley | based on a ruby gem a friend of mine has built |
| 16:04 | chaslemley | i was just wondering if there's any use for something like this to interface with compojure or if it's overkill, already been done, etc |
| 16:08 | pbuckley | chaslemley: I don't know the answers to your questions, but I think it's a cool idea. |
| 16:09 | alexyk | _fogus_: just found out you interviewed Odersky! Are you a secret Scalaist? :) |
| 16:09 | chaslemley | cool, thanks |
| 16:10 | _fogus_ | alexyk: I wouldn't say secret no. |
| 16:10 | alexyk | _fogus_: man, you even got Harrop there! awesome |
| 16:11 | apgwoz | chouser: you should perhaps get your first message tagged chouser in a second or two |
| 16:11 | _fogus_ | alexyk: I don't know who that is... but he keeps coming back to comment. |
| 16:11 | alexyk | _fogus_: if you don't know who Jon Harrop is, you don't know Haskell or F# :) |
| 16:11 | lrenn | or comp.lang.lsip |
| 16:11 | AWizzArd | stuart wrote in the GG “code path for using vars is now *much* faster for the common case” — what is meant by “code path”? |
| 16:11 | raek | Is there any fuzz testing lib for clojure? |
| 16:12 | AWizzArd | regarding 1.3 Alpha 2 |
| 16:12 | alexyk | _fogus_: and you might as well keep it that way for your peace of mind :) |
| 16:12 | _fogus_ | alexyk: I guess I need to read more about Haskell then. |
| 16:12 | alexyk | he'll be surpsrised by your mildmannered replies :) |
| 16:13 | alexyk | _fogus_: he is the bane of Haskell and Lisp! And apparently Scala too |
| 16:14 | _fogus_ | alexyk: Oh... I think I see now. |
| 16:14 | chouser | apgwoz: It worked. :-) I'll take a look, but I'm beginning to think the design of contrib.command-line is too ...um... compound. |
| 16:14 | chouser | it shouldn't require a patch to add validation |
| 16:18 | apgwoz | chouser: yes, it is a bit difficult. |
| 16:18 | apgwoz | and not that friendly. |
| 16:18 | apgwoz | i do like the simplistic format of the spec though. |
| 16:19 | raek | I'm a bit puzzled regarding how to solve "the error problem". I have a function that parses a string into a map. not all strings are syntactically valid. what should the parse function do when it encounters an invalid string. |
| 16:19 | Raynes | _fogus_: The only thing you need to know about Jon Harrop is that HASKELL SUCKS F# AWESOME YAY!1!!1! |
| 16:19 | raek | my options seems to be: 1. pre/post-conditions 2. returning nil 3. throwing some exception |
| 16:20 | raek | or maybe 4. calling *syntax-error*, which the user would have to rebind |
| 16:20 | _fogus_ | Raynes: So you're saying I should abandon learning Haskell? ;-) |
| 16:21 | Raynes | In his humble opinion YES AND EVERYTHING ELSE LEARN F# YAY!1!!1! |
| 16:21 | chouser | raek: sounds about right. |
| 16:21 | raek | so, dear #clojure. how do you do error reporting? |
| 16:22 | alexyk | raek: (throw (Exception. "arrgh!")) |
| 16:22 | chouser | raek: you could bind *syntax-error* to a fn that throws an exception, then call it in your parser and do something useful with the return value |
| 16:23 | rdeshpande | well, i can't really speak for how to do this in clojure, but i would typically return some sort of symbol that corresponds to a key in a translation file (maybe a yaml) that has the readable, localized error message |
| 16:23 | chouser | this would default to Java-style expection-throwing, but allow a sufficiently concerned user to control the behavior and avoid losing the rest of the parsing if they so desired. |
| 16:30 | raek | chouser: thanks for the suggestions. :) the binding + fallback to exception way does have a clojurey feel to it, i think... |
| 16:32 | raek | also, the defdynamic thingy is in Clojure 1.3.x, right? |
| 16:33 | chouser | raek: ^:dynamic, but yes 1.3 alpha 2 |
| 16:33 | chouser | raek: for the exception to throw by default, consider clojure.contrib.condition. It may not be worth the dep, but might be worth considering. |
| 16:35 | zakwilson | chouser: I couldn't plug your sorted-intersection-with directly in to my code, but I tried it with some extracted data. It's about 10x slower. |
| 16:35 | chouser | heh. nice. |
| 16:36 | nickik | man do i wait for the videos don't really get all that new stuff |
| 16:37 | danlarkin | contrib.condition is nice |
| 16:38 | chouser | have you guys added your features to contrib yet, or still keeping them to yourselves? |
| 16:38 | chouser | contrib.condition features, I mean. |
| 16:39 | danlarkin | I think we have a patch up on assembla? |
| 16:39 | danlarkin | Oh, or maybe Steve already committed them |
| 16:40 | cemerick | chouser: Thanks. I sorta did a facepalm as I read Stu's initial email. Any expertise I have in that alley is much to my chagrin, really. :-) |
| 16:41 | chouser | cemerick: yeah, I know. |
| 16:41 | chouser | but there it is |
| 16:41 | technomancy | build conscription. =) |
| 16:41 | chouser | maybe you can talk the other stu into it instead |
| 16:42 | cemerick | chouser: after his drawn-out battle over the modularization of old-world contrib, I couldn't in good conscience ask him to lead it. |
| 16:42 | cemerick | technomancy: watch it, I may start throwing feature requests at you ;-) |
| 16:43 | chouser | technomancy: or you! I'd be happy to be required to use your One True Build Tool in exchange for having someone sanely manage contrib builds. |
| 16:44 | technomancy | is this from a specific mailing list thread or just general "how are we going to do this" discussion? |
| 16:44 | chouser | I already wrote my own pom.xml for finger trees because I thought it was what was required. I'll clearly go to any length, if only they'll tell me what to do. |
| 16:44 | amalloy | chouser: One True Build System? it looked like you were struggling to find an OTBS there |
| 16:45 | technomancy | if it's just a matter of getting hudson to deploy locally to build.clojure.org I can help |
| 16:45 | technomancy | I don't know the first thing about archiva/nexus though |
| 16:46 | cemerick | The local-install-to-repo thing is decidedly not the right thing to do. |
| 16:48 | kevins | is there way to stop the repl without killing it? (i.e. runaway function). This is especially bad in netbeans/enclojure where I currently have to stop the entire IDE. |
| 16:49 | cemerick | kevins: No. This will improve to some extent as more people adopt nrepl, which supports evaluation interrupts. |
| 16:49 | technomancy | maybe once a nexus is set up I could help getting some of the projects pointed at it |
| 16:49 | kevins | thanks. |
| 16:57 | amalloy | do we have an iterate-while construct? i often find myself wanting (take-while f (iterate g x)) |
| 17:01 | apgwoz | cemerick: with nrepl, has anyone discussed porting SLIME to use it, or creating a new mode for use with it? |
| 17:01 | apgwoz | (obviously in emacs) |
| 17:02 | technomancy | apgwoz: it will probably happen eventually |
| 17:03 | technomancy | nobody has volunteered yet. =) |
| 17:03 | apgwoz | technomancy: i think it might be beyond my elisp skills... |
| 17:03 | apgwoz | though, maybe not... i don't know :) |
| 17:04 | rata_ | hi |
| 17:04 | arbscht | apgwoz: the other way seems easier: write a clojure-side adapter like swank-clojure but for nrepl |
| 17:05 | chouser | kevins, cemerick: see 'clojure.contrib.repl-utils/add-break-thread!' to make Ctrl-C interrupt runaway tasks in the current thread. |
| 17:05 | apgwoz | arbscht: i suppose interpretting the swank protocol would be easier |
| 17:06 | apgwoz | though, that sort of bastardizes nrepl, don't you think? |
| 17:07 | chouser | ok, finger-tree slides are up at http://talk-finger-tree.heroku.com/ in a format that doesn't require downloading a giant PDF. |
| 17:07 | apgwoz | otherwise, nREPL should just implement SWANK and be done. |
| 17:07 | cemerick | chouser: There's no way to send a Ctrl-C in enclojure or ccw, AFAIK |
| 17:07 | apgwoz | chouser: oooh, smooth transitions! |
| 17:07 | chouser | cemerick: oh, sure. |
| 17:08 | Raynes | Isn't there something in Clojure to get the line separator for the system you're on? |
| 17:08 | chouser | cemerick: those who live by fancy tools may sometimes die by them. :-) |
| 17:08 | amalloy | (System/getProperty "line.separator") as i recall |
| 17:08 | Raynes | I know the Java way, but I thought I remembered something in Clojure itself. |
| 17:08 | Raynes | I might be mistaken. |
| 17:09 | muhdik_ | is clojure any good? |
| 17:09 | Raynes | It's all sorts of good! |
| 17:09 | mabes | muhdik_: this group might be biased ;) |
| 17:09 | apgwoz | Raynes: (def line-seperator #(System/getProperty "line.separator")) ? :) |
| 17:09 | amalloy | muhdik_: nah. we just like hanging out here... |
| 17:09 | arbscht | apgwoz: implementing swank isn't the easiest thing to do; the protocol is unstable, and often assumes a CL runtime (or at least a CL reader). it'd be wise to isolate swank-fu in a module like an adapter than to build nrepl around it |
| 17:09 | muhdik_ | u can make anything that you can with java in clojure i mean? |
| 17:09 | Raynes | apgwoz: Read above. |
| 17:10 | apgwoz | Raynes: i know, my comment was in response to your "I know the java way" |
| 17:10 | apgwoz | .. and was a joke :) |
| 17:10 | Raynes | Oh. I'm too ill to get jokes. |
| 17:10 | muhdik_ | or not? |
| 17:10 | chouser | muhdik_: pretty much anything worth making, anyway. :-) |
| 17:10 | apgwoz | Raynes: oh, sorry you're ill :( |
| 17:10 | amalloy | muhdik_: yes, you have access to everything java has, if you need it |
| 17:10 | Raynes | $wiki turing completeness |
| 17:10 | sexpbot | First out of 1040 results is: Turing completeness - Wikipedia, the free encyclopedia |
| 17:10 | sexpbot | http://en.wikipedia.org/wiki/Turing_completeness |
| 17:10 | muhdik_ | oh so u can make webpages? |
| 17:10 | apgwoz | arbscht: right, swank is complicated, which is why I'm asking why it makes sense to bastardize nREPL with a SWANK interpreter |
| 17:11 | muhdik_ | i mean ecommerce |
| 17:11 | apgwoz | arbscht: well, a SWANK to nREPL interpreter of course |
| 17:11 | muhdik_ | is it? |
| 17:11 | muhdik_ | hmmm |
| 17:11 | arbscht | apgwoz: for SLIME compatibility. SLIME has the same problem as swank, only on a larger scale. it seems to me that it makes less sense to reimplement a SLIME-like than a swank adapter |
| 17:12 | raek | muhdik_: there are web frameworks, so yes |
| 17:12 | muhdik_ | i mean does oracle own clojure? |
| 17:12 | apgwoz | arbscht: while it's more work, it probably does make sense, given that you no longer have to make special cases. nREPL is to clojure as SLIME/SWANK would be for CL. |
| 17:12 | muhdik_ | or just java |
| 17:12 | muhdik_ | because oracle doesnt have a clue |
| 17:13 | raek | oracle does not own clojure, rich hickey and the contributors do |
| 17:13 | apgwoz | arbscht: no one is saying the nREPL mode wouldn't be influenced (heavily) by SLIME... |
| 17:13 | muhdik_ | ok cool |
| 17:13 | arbscht | apgwoz: well, nrepl is to clojure what swank is to CL. there's no SLIME-like in nrepl. but if it makes sense to you to build one, go ahead, I'd use it. :) |
| 17:13 | muhdik_ | is clojure the same as f# in the .net world? |
| 17:14 | raek | I would say that F# and Scala are more similar |
| 17:14 | zakwilson | muhdik_: I think Scala is more limilar |
| 17:14 | zakwilson | similar |
| 17:14 | muhdik_ | clojure is like linq then? |
| 17:14 | chouser | the .net equivalent of Clojure is ClojureCLR |
| 17:14 | apgwoz | arbscht: right. at some point in time, i might be willing to attempt to take on that project... but unfortunately not now. |
| 17:14 | muhdik_ | ok |
| 17:16 | apgwoz | arbscht: of course in my previous statement with the analogy, it should have been nREPL-mode/nREPL for maximum correctness. |
| 17:16 | arbscht | apgwoz: I understand |
| 17:17 | apgwoz | arbscht: ok. just clarifying :) |
| 17:17 | cemerick | chouser: sure, sometimes; though, you can s/fancy/"simple" there, too. ;-) |
| 17:18 | chouser | so true |
| 17:18 | chouser | which reduces to something like "no tool is perfect". go figure. |
| 17:19 | jweiss | i'm trying to call apache xmlrpcclient that has 2 overloads for .execute: String,Object... and String,List. i am passing in a clojure vector so i thought it'd hit the latter, but seems to be hitting the former. type hinting as java.util.List didn't help. any suggestion? |
| 17:20 | chouser | ->(instance? java.util.List []) |
| 17:20 | sexpbot | java.lang.NullPointerException |
| 17:20 | fhd | Hi |
| 17:21 | fhd | Is there something like reify that I can use to extend classes? |
| 17:21 | fhd | reify and deftype do apparently only work with interfaces |
| 17:22 | replaca | fhd: You have to use gen-class |
| 17:22 | chouser | fhd: proxy |
| 17:22 | jweiss | chouser: not sure what the result of that sexpbot experiment should tell me |
| 17:22 | replaca | chouser: does proxy support extending? |
| 17:23 | chouser | replaca: yessir |
| 17:23 | fhd | chouser: Cool, I'll try that :) |
| 17:23 | replaca | Hah, of course! That's what I use in pprint :) |
| 17:23 | chouser | jweiss: yeah, me either. :-P Maybe you'd better paste your code somewhere. hinting to List should do it |
| 17:23 | replaca | you taught me two years ago, but I haven't done it since |
| 17:26 | jweiss | chouser: http://gist.github.com/645803 |
| 17:27 | jweiss | oops i typo'd List->list but i had it right before and still didn't work |
| 17:27 | fhd | chouser: Works, thanks :) A bit confusing though that there is deftype, proxy, reify (and I guess a few others) |
| 17:27 | chouser | replaca: :-) |
| 17:29 | chouser | fhd: yeah. and worse that the proxy syntax is rather different |
| 17:30 | fhd | By the way, can I watch the clojureconj talks online? |
| 17:30 | Raynes | How would one pprint a map with newlines inserted in the appropriate places? The default is to print it all on one line with commas separating key -> value pairs. |
| 17:30 | fhd | I heard rumours they'd be recorded |
| 17:30 | technomancy | fhd: it'll be a few weeks at least |
| 17:30 | petrilli | fhd - hopefully. I'd like to watch them again, even though I was there. |
| 17:30 | fhd | technomancy: Damn, I was really looking forward to this :( |
| 17:31 | petrilli | Also, I'd like a replay of Rich talking about pods at the BBQ... so I can listen to it 50 times to understand it hopefully. |
| 17:32 | fhd | Then again, it takes weeks until the talks are uploaded for most conferences I follow |
| 17:32 | technomancy | petrilli: well the emerginglangs talk will cover that |
| 17:32 | fhd | Don't really know why, is the world of video recording that unrestrainable? |
| 17:32 | dnolen | Raynes: pprint is useful for that. |
| 17:32 | petrilli | technomancy: awesome... I thought I got it, then had another beer, went ot sleep and woke up confused. |
| 17:32 | Raynes | dnolen: Indeed, I'm asking how one would use pprint to do the above. |
| 17:33 | Raynes | dnolen: The docs are kind of a brick wall. |
| 17:33 | Raynes | technomancy: I'm disappointed that I never got to meet you at the Conj. I just admired you from a distance. <3 |
| 17:34 | petrilli | I'm still trying to figure out if he types standing up. |
| 17:34 | pjstadig | he does |
| 17:34 | petrilli | Wow... I thought I was hardcore with a desk that raises up so I can type standing up, but I still use a Model M |
| 17:35 | chouser | fhd: & args would make args a seq not a vector |
| 17:36 | chouser | hm, but that should still implement java.util.List. |
| 17:37 | drewr | petrilli: I almost pulled out my phone to record it |
| 17:39 | technomancy | Model Ms are the best, modulo RSI concerns. if I could get a split one I would be all over it. |
| 17:40 | petrilli | technomancy: Email Unicomp... I did. They own all the patents, and also all the tooling to build it. If they knew they could sell enough, I'm sure they would. |
| 17:40 | fhd | K, gotta run. cya! |
| 17:41 | petrilli | technomancy: sales@pckeyboard.com |
| 17:43 | technomancy | Raynes: it was all a blur; so much going on. |
| 17:43 | nDuff | http://elitekeyboards.com/products.php?sub=filco_keyboards,majestouch_104key |
| 17:44 | jackdempsey | funny, i was reading about this today |
| 17:44 | jackdempsey | my msoft natural elite 4000 is still the only piece of msoft shit i use |
| 17:44 | petrilli | For me, nothing will ever trump the buckling spring keys in the IBM and Unicomp keyboards.... I type 30-40% faster. And thanks to Clojure, I've not worn out the shift key yet |
| 17:45 | nDuff | petrilli, these also use real mechanical switches; they are indeed a thing of beauty. |
| 17:46 | petrilli | nDuff: Cool. I'd need to check one out... if I ever wear this one out... my original, circa 1990 Model M still works |
| 17:47 | petrilli | Now I just need to find somewhere that doesn't think saying that "we have a fully integrated SOA architecture" is actually useful. |
| 17:49 | apgwoz | when using clojure.contrib.socket-server, is there a way to get details (i.e. for logging) such as the client's ip address? |
| 17:54 | apgwoz | from within the the handler that is. |
| 17:58 | apgwoz | ... it certainly doesn't look like it via the source, but someone might have a thought on the matter? is it a doomed thought? |
| 18:00 | lazy1 | apgwoz: The server object has :connections, my guess you can use that somehow |
| 18:02 | apgwoz | lazy1: there's no guarantee that the last conjed element is for the thread that just started. |
| 18:02 | apgwoz | so, while it'd potentially work, it'd be buggy |
| 18:02 | jweiss | so if a java method take varargs and i want to create a clojure method that calls it with however many args are in a list (NOT the list itself, that's just one arg), what do i do? there's no apply for java methods. and i can't use macro because i need to evaluate the form that creates the list |
| 18:03 | jweiss | sorry create clojure fn |
| 18:03 | apgwoz | jweiss: supply an array as the last argument. a java array |
| 18:03 | jweiss | apgwoz: yeah i tried that, somehow the lib i'm calling doesn't like it |
| 18:04 | lazy1 | apgwoz: You're right, however there might be something in the connection object you can use (maybe compare input-streams). But my guess it's a dead end |
| 18:04 | apgwoz | lazy1: yeah, we're already getting hacky when we start comparing input streams :) |
| 18:05 | lazy1 | apgwoz: Switch to aleph? (maybe, not sure if it will give you what you need) |
| 18:06 | apgwoz | lazy1: yeah, i don't want async, which is why server-socket is perfect. if only the functions in server_socket.clj weren't private, then i'd write a new create-server. |
| 18:07 | apgwoz | privacy is a double edged sword. |
| 18:09 | apgwoz | I think I'm write here, defn- functions can't be exported at all outside of the namespace they were defined in right? It's not just left out of the default namespace, correct? |
| 18:09 | apgwoz | (by default namespace, i mean, the default exports, like you'd get when you (use 'lib)) |
| 18:12 | lazy1 | apgwoz: IMO the shortest path is to copy the code and change accept-fn to pass the socket object as well) |
| 18:13 | apgwoz | lazy1: yeah, I agree. it's certainly not ideal though. |
| 18:30 | AWizzArd | http://java.sun.com/docs/white/langenv/Simple.doc2.html <-- I love point 2.2.4 :-) |
| 18:32 | AWizzArd | “Object oriented programming supersedes functional […] style.” |
| 18:33 | plathrop | How do I write java code that runs as a daemon? |
| 18:33 | Adamant | now I know why I hate Java so much |
| 18:33 | plathrop | s/java/clojure/ |
| 18:33 | sexpbot | <plathrop> How do I write clojure code that runs as a daemon? |
| 18:34 | plathrop | I've seen lein-daemon, but I'm not sure that's right for running on a production box |
| 18:34 | nDuff | plathrop, ...use a process supervision tool to run your arbitrary foreground process in the background! |
| 18:34 | plathrop | nDuff: That's an option I'd prefer to avoid. I'm an Ops guy who has bitched incessantly about devs who do that :-P |
| 18:35 | nDuff | plathrop, I'm an ops guy and I _hate_ developers who write things to only be usable as daemons. |
| 18:35 | nDuff | plathrop, daemontools or runit gives you status monitoring, automatic restarts, a consistent control interface... |
| 18:36 | nDuff | plathrop, ...ability to run triggering events on shutdown or prior to restart (ie. automated cleanup) |
| 18:36 | plathrop | Whereas I like things that fit in to the OS properly and run as real daemons. I like the *option* to run in foreground, but I want the program to be able to be a daemon too |
| 18:36 | nDuff | plathrop, ...ability to record the signal that caused your exit or the exit status... |
| 18:37 | plathrop | All valid points |
| 18:37 | nDuff | plathrop, "real daemons" are an anachronism, and modern operating systems are moving away from them; look at the movement towards Upstart. |
| 18:39 | plathrop | And who watches your watchdog daemon? |
| 18:39 | nDuff | plathrop, my watchdog daemon either _is_ my init (PID 1) process, or is directly supervised by it. |
| 18:43 | plathrop | I guess I'll look at wrapping apache-commmons daemon for my purposes. Thanks |
| 18:53 | LLLLO | ll |
| 18:58 | LLLLO | f |
| 19:03 | LLLLO | !time |
| 19:03 | LLLLO | !time |
| 19:04 | LLLLO | !time |
| 19:09 | LLLLO | !time |
| 19:09 | TheAnimal | LLLLO: 26.10.2010 01:10:23 +0200 |
| 19:13 | amalloy | damn. someone tell that boy to use a test channel |
| 19:18 | amalloy | ->(take 2 [1]) |
| 19:18 | sexpbot | ⟹ (1) |
| 19:20 | KirinDave | Sometimes it's the best feeling in the world to use gen-class |
| 19:20 | amalloy | ->(->>[nil nil 1 nil nil] (drop-while nil?) (take 2) (keep identity)) |
| 19:20 | sexpbot | java.lang.SecurityException: Code did not pass sandbox guidelines: (#'clojure.core/keep) |
| 19:20 | amalloy | ,(->>[nil nil 1 nil nil] (drop-while nil?) (take 2) (keep identity)) |
| 19:20 | KirinDave | And be like, "Dear other jvm languages, you can suck what I am giving you. If you don't want to get slapped around, I suggest you enjoy it." |
| 19:21 | amalloy | argh both of the bots hate me |
| 19:21 | amalloy | ,(->>[nil nil 1 nil nil] (drop-while nil?) (take 2) (filter identity)) |
| 19:21 | amalloy | ->(->>[nil nil 1 nil nil] (drop-while nil?) (take 2) (filter identity)) |
| 19:21 | sexpbot | ⟹ (1) |
| 19:22 | hsuh | was clojureconj recorded? |
| 19:22 | jackdempsey | hsuh: evidently yes, and videos potentially in weeks or more |
| 19:25 | plathrop | How do you implement signal handling in clojure? |
| 19:25 | KirinDave | plathrop: Like, UNIX signal handling? |
| 19:25 | plathrop | nDuff: So, if you are using a watchdog process, how do you make it so the watchdog process can nicely stop your service? |
| 19:26 | plathrop | KirinDave: yeah. I have clojure I want to run as a daemon. If I run it under upstart it will be sent a TERM segnal |
| 19:26 | plathrop | I need to make sure I clean up and exit nicely |
| 19:26 | KirinDave | plathrop: Ha. |
| 19:26 | KirinDave | plathrop: Find someone who's done that work over the jni. |
| 19:26 | KirinDave | That's the only realw ay |
| 19:27 | plathrop | oh dear |
| 19:27 | plathrop | Nobody is running clojure as unix daemons then? |
| 19:27 | nDuff | plathrop, it depends; runit _does_ allow you to override event handlers, so you can provide a command to be run in place of a SIGTERM |
| 19:27 | nDuff | plathrop, ...and that command can use whatever your preferred polite-shutdown-method may be. |
| 19:28 | plathrop | nDuff: how can that command access the internals of the service though? |
| 19:28 | KirinDave | plathrop: As much as they are java. |
| 19:29 | KirinDave | plathrop: There are still a lot of green pastures. |
| 19:29 | arohner | plathrop: check out lein-daemon |
| 19:30 | nDuff | plathrop, that's your implementation decision. Tomcat uses a command socket; I'm trying to remember the standard-ish approach that we used two jobs ago, but it's escaping me without some (ongoing) googling. |
| 19:30 | plathrop | arohner: yeah, I'm looking at it. thanks |
| 19:31 | nDuff | ahh -- it was a JMX command-line tool |
| 19:31 | nDuff | ...that we had our control scripts invoking. |
| 19:32 | plathrop | nDuff: oh, okay. that seems like adding a lot of complexity just for the luxury of not using an init script? I'm not trying to be a dick I'm really trying to understand the right way to do this. |
| 19:32 | plathrop | (I say since I've already been flamed to a crisp elsewhere for trying to figure out why you'd want to use a watchdog program) |
| 19:33 | nDuff | plathrop, *shrug*. At that time, I was sysops staff, _not_ java dev staff. Using JMX shifted a lot of pain from the ops team onto the java team. |
| 19:34 | nDuff | plathrop, ...maintaining a separate init script for every distro which happens to interpret the LSB's standards for how they should behave a little bit differently is Really Not Fun, by the way. |
| 19:35 | nDuff | well, not that much pain, as the Java folks were already supporting JMX anyhow |
| 19:35 | nDuff | so it was really saving labor all 'round |
| 19:36 | plathrop | huh. okay |
| 19:36 | plathrop | At this point this is sounding like way more of a project than I bargained for for something as simple as I'm working on |
| 21:04 | amalloy | argh i hate mutable state. please let me work in clojure instead of java |
| 21:10 | rata_ | amalloy, I sympathize with you. mutable state is hateable |
| 21:30 | TeXnomancy | mmm... new lein plugin task uses juxt |
| 21:30 | TeXnomancy | thank you trptcolin, wherever you may be. |
| 21:30 | TeXnomancy | and ivey =) |
| 21:30 | TeXnomancy | it's a little-known fact that I can't reject a patch that includes a call to juxt. |
| 21:30 | ivey | heh |
| 21:31 | ivey | that's all trtpcolin. I just merged the thing. |
| 21:31 | ivey | However, that's good to know about juxt... |
| 21:34 | amalloy | ,(((juxt juxt juxt) juxt juxt) juxt juxt juxt juxt) |
| 21:34 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (4) passed to: PersistentVector |
| 21:34 | amalloy | aww what |
| 21:34 | ivey | ->(buffalo buffalo buffalo buffalo) |
| 21:34 | sexpbot | java.lang.Exception: Unable to resolve symbol: buffalo in this context |
| 21:34 | amalloy | ,((juxt juxt juxt) juxt juxt juxt juxt) |
| 21:34 | clojurebot | [#<core$juxt$fn__3665 clojure.core$juxt$fn__3665@4218cb> #<core$juxt$fn__3665 clojure.core$juxt$fn__3665@169c6f2>] |
| 21:35 | TeXnomancy | ~o/ |
| 21:35 | clojurebot | \o ... High five! |
| 21:35 | amalloy | ,(apply ((juxt juxt juxt) juxt juxt) juxt juxt juxt juxt) |
| 21:35 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$juxt |
| 21:35 | amalloy | bah, i give up |
| 21:35 | amalloy | but i love the high five |
| 21:36 | TeXnomancy | ((malkovich malkovich malkovich) malkovich malkovich) |
| 21:37 | trptcolin | oh wow, sorry for apparently indirectly starting this :) (just got caught up on the juxt conversation) |
| 21:38 | ivey | trptcolin: buffalo |
| 21:38 | trptcolin | doh! |
| 21:39 | rata_ | ,(((juxt juxt juxt) juxt juxt) [juxt juxt] [juxt juxt]) |
| 21:39 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (2) passed to: PersistentVector |
| 21:43 | TeXnomancy | trptcolin: I think this subtask-help mechanism could be abstracted and shared |
| 21:43 | trptcolin | TeXnomancy: absolutely |
| 21:43 | TeXnomancy | I know autodoc needs a similar thing |
| 21:44 | trptcolin | there's also other stuff in lein-plugin that was essentially copied from another task (install, i think) that i was planning to simplify once we get merged |
| 21:45 | trptcolin | interesting, i hadn't thought of it being abstracted into its own thing outside of leiningen, but that makes sense |
| 21:49 | TeXnomancy | I'm thinking having subtask support in the help namespace actually |
| 21:49 | TeXnomancy | maybe subtasks could be metadata on a task, and help could check it. |
| 21:50 | trptcolin | ah, gotcha. i was just looking at autodoc for the first time - didn't realize it was already depending on leiningen anyway |
| 21:52 | trptcolin | sounds pretty clean to me |
| 21:52 | TeXnomancy | dare I say simple? =) |
| 21:53 | trptcolin | oh noez!!! ;) |
| 21:54 | TeXnomancy | pushed |
| 21:55 | Nafai | Were there videos taken of the conference? |
| 21:56 | TeXnomancy | Nafai: yes, but not professionally. |
| 21:56 | TeXnomancy | the Conjure guy brought recording gear |
| 22:05 | drewr | Nafai: no guarantee on when they'd be up |
| 22:05 | trptcolin | technomancy: cool, just pushed a typo fix. i'll tackle moving the help stuff over, as well as adding some tests for that & plugin stuff. probably not tonight though |
| 22:06 | Nafai | I'm actually wanting to see Rich's keynote |
| 22:06 | trptcolin | so if you want to grab it first that's cool |
| 22:09 | technomancy | hah; nice catch. I was debugging and left that out. |
| 22:09 | technomancy | no rush on the help moving. |
| 22:11 | trptcolin | cool. |
| 22:12 | trptcolin | Nafai: the keynote was great! 5-word summary: "Think hard. Write it down." |
| 22:12 | Nafai | Yeah, sounds inspiring |
| 22:12 | Raynes | Don't forget hammock time. |
| 22:15 | trptcolin | :) yeah +1 to technomancy for the "stop. hammock time" image |
| 22:15 | technomancy | http://p.hagelb.org/hammock.jpg |
| 22:15 | trptcolin | technomancy: how many people did you get asking about the google venn diagram today? |
| 22:15 | amalloy | haha, that's great |
| 22:16 | trptcolin | and as a follow-up, did you know there was another technomancy before that? |
| 22:17 | technomancy | trptcolin: I saw that on hacker news; the guy behind technomancy.org |
| 22:22 | jweiss | anyone got some real-life examples of error-kit use? the example in error-kit.clj is a little too simple. i can't figure out if the caller can specify his own handlers or not, and if so, do they have to be named in the with-handler form, or can they be external? |
| 22:26 | rata_ | what's the name of the function that returns [(filter pred coll) (remove pred coll)]? |
| 22:26 | rata_ | I'm almost sure there is one |
| 22:29 | jackdempsey | lol |
| 22:29 | jackdempsey | hammock time. nice. |
| 22:30 | trptcolin | ,(clojure.contrib.seq-utils/separate even? (range 10)) |
| 22:30 | clojurebot | [(0 2 4 6 8) (1 3 5 7 9)] |
| 22:32 | rata_ | thanks trptcolin |
| 22:32 | trptcolin | sure |
| 22:38 | technomancy | separate needs to be reimplemented using juxt |
| 22:38 | technomancy | it's a textbook juxt |
| 22:39 | technomancy | (juxt (comp filter pred) (comp remove pred)) |
| 22:43 | trptcolin | i was juxt looking at that |
| 22:46 | trptcolin | actually, i really was looking at it for another reason - takes 2 traversals. could be just 1 with less elegant code |
| 22:47 | technomancy | reduce! |
| 22:48 | technomancy | it's like juxt, but less indie. |
| 22:49 | lancepantz | group-by solves the same problem, i'm not sure how its performance characteristics are relative to juxt though |
| 22:50 | trptcolin | looks pretty fast to me. |
| 22:50 | trptcolin | ,(vals (group-by even? (range 10))) |
| 22:50 | clojurebot | ([0 2 4 6 8] [1 3 5 7 9]) |
| 22:51 | trptcolin | and it uses transient so you know it's fresh |
| 22:52 | lancepantz | i find myself doing group-by + destructing quite a bit |
| 22:59 | defn | Stop. Hammock time. |
| 22:59 | trptcolin | indeed. peace out |
| 22:59 | defn | night tr |
| 23:01 | defn | howdy monsieur lancepantz |
| 23:02 | defn | technomancy: can I quote you on juxt and it being less "indie" |
| 23:02 | technomancy | well, it's reduce that's no longer indie |
| 23:03 | technomancy | but I used to listen to reduce before it was on the major labels. |
| 23:03 | technomancy | (for the record) |
| 23:03 | defn | hahahaha |
| 23:03 | defn | that's /awesome/ |
| 23:03 | defn | btw, great image -- i had a similiar idea which ill need to sleep on ;) |
| 23:04 | defn | waking mind is preventing me from commiting to it |
| 23:06 | rata_ | good night :) |
| 23:07 | rata_ | see you tomorrow |
| 23:11 | lancepantz | hey defn |
| 23:11 | lancepantz | how was the flight back? |
| 23:11 | lancepantz | have to ride the bus again? |
| 23:12 | defn | not too shabby -- only trouble was i crossed my right leg over my left and promptly fell asleep. feels like i have a staph infection in my right leg as a result. |
| 23:12 | defn | going home was easy compared to the 1:30am bus ride on the way down |
| 23:13 | lancepantz | i bet |
| 23:13 | defn | still tired from the 3 nights of consecutive "stay up until 3am talking code, go to bed, wake up at 7am and go to talks for 12 hours" routine |
| 23:14 | defn | but i had a mini breakthrough at work on clojure -- sounds like people are starting to get more and more interested |
| 23:15 | lancepantz | yeah i missed the morning talks the second day |
| 23:15 | lancepantz | hung over from the night before |
| 23:18 | defn | i made it and wanted to kill myself most of the afternoon |
| 23:18 | defn | rich's talk owned, though... |
| 23:18 | lancepantz | yeah, i loved it |
| 23:19 | defn | some people were being sort of snarky about it which sort of pisses me off |
| 23:19 | lancepantz | really? |
| 23:19 | lancepantz | oh, how was the bbq btw? |
| 23:20 | defn | awesome. i broke a corona on stu's floor and made his foyer smell like beer for what i would imagine is the foreseeable future |
| 23:21 | defn | *facepalm* |
| 23:21 | defn | i think i apologized 2-400 times, cleaned it up, vacuumed, begged forgiveness, etc. |
| 23:22 | lancepantz | hehe |
| 23:23 | defn | but anyway, the {:bbq "fantastic"} |
| 23:23 | defn | chapel hill is beautiful area |
| 23:25 | defn | lancepantz: how was your trip home |
| 23:26 | lancepantz | long and sleepily |
| 23:26 | lancepantz | i can't sleep on planes |
| 23:27 | lancepantz | for that matter, i couldn't sleep at the conj either |
| 23:27 | lancepantz | so i slept til 2pm on sunday |
| 23:27 | lancepantz | didn't get to go surfing, disappointed |
| 23:27 | lancepantz | needed the sleep though |
| 23:41 | amalloy | ooc what was the mean age at the conj? am i talking to surprisingly hip old geezers, or surprisingly mature young'uns? |
| 23:42 | amalloy | (or is it rude to even ask on irc? not exactly an irc veteran myself) |
| 23:43 | maravillas | seemed like a decent mix to me |
| 23:45 | defn | in my view: the people who were young are destined to be the people who were older |
| 23:45 | amalloy | haha i like that |
| 23:46 | defn | i had a guy who was in his 50s ask me my age and then tell me he was using emacs before i was born |
| 23:46 | defn | my only response was that someday ill be in a similar position |
| 23:46 | amalloy | defn: you'll still be using emacs when he's dead! |
| 23:47 | defn | he was a nice guy -- we're all the same, hunting for a better solution to our problems |
| 23:47 | amalloy | yeah |
| 23:47 | defn | anyway, age is irrelevant, i talked to people who were 5 years my junior who put my knowledge to shame |
| 23:47 | amalloy | well yeah. i mean, Raynes was there |
| 23:48 | defn | (inc Raynes) |
| 23:49 | defn | speaking of which, we need to have karma added to sexpbot. it used to be nick++, but should be implmeneted in sexpbot as (inc nick) |
| 23:50 | defn | im gonna go read some lisp in small pieces for awhile |
| 23:50 | defn | cheers |
| 23:50 | amalloy | AS IT HAPPENS i'm in the middle of adding bits to sexpbot |
| 23:50 | defn | amalloy: nice. |
| 23:50 | amalloy | but i don't know how karma's supposed to work :P |
| 23:50 | defn | it's simple. (inc nick) gives nick +1 |
| 23:50 | defn | {:nick 1} |
| 23:51 | defn | (inc nick) => {:nick 2} |
| 23:51 | defn | (dec nick) => {:nick 1} |
| 23:51 | defn | anyway, gotta get a bit of reading in before bed, ciao |