#clojure log - Jul 16 2011

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

0:43 mdeboard: technomancy: I'm getting that darn "java.util.concurrent.RejectedExecutionException" again... swank 1.3.2

1:44 amalloy: mdeboard: what did you do to fix it last time? (also would you mind killing mdeboard_? he's vexing my tab completion)

2:00 mdeboard: you're the one i was arguing with about github's clojure parser/highlighter, right? apparently they use pygment to color stuff

2:03 from what i can tell, whoever wrote pygment's clojure plugin just gave the scheme plugin a mild facelift and a different list of keywords - there's some stuff that's definitely not right

5:33 shtutgart: Hi. How can I specify maximum value of y-axis in the Incanter chart? e.g. (bar-chart [:a :b :c] [10 20 30]) gives me Y values from 0 to 30, but I need maximum value of 100

5:36 Dranik: hi, shtutgart! do you remember the function wrap-codepage which you've shown me?

5:37 doesn't it break CSS?

5:38 shtutgart: it shouldn't (unless your CSS files have a different encoding)

5:40 Dranik: yeah, it was in ascii...

5:40 but how about the other types of files?

5:42 shtutgart: ah, yeah, it sets content-type to text/html, so you have to wrap only the handler which serves your pages

5:44 Dranik: yep :-)

5:46 here is the best example of ho to deal with the utf8

5:46 http://code.google.com/p/world-of-meme/source/browse/src/main/clojure/net/marigolda/templating_start.clj?spec=svn42b4a10a706bab53f89a0efb50610a50bfa8444a&r=42b4a10a706bab53f89a0efb50610a50bfa8444a

5:46 see the function wrap-charset

5:56 shtutgart: yeah, it much more general. Interesting, why some similar thing doesn't included in compojure itself

5:59 Dranik: probably noone did a pullrequest or issue

5:59 let me try...

6:00 actually I don't know, probably it should be a ring middleware

6:02 shtutgart: ah, see https://github.com/mmcgrana/ring/commit/2b3f560e9d9c15a8da0ec626f0f10bf9c5014ff4

6:11 Dranik: shtutgart, dunno when it will be available for testing

6:11 but I guess it should be so

6:11 waiting for weavejester to talk to him about his commit :-)

6:59 rhebus: hello

7:00 fliebel: hi

7:00 rhebus: what's an idiomatic way of returning a map with the values modified by a function?

7:00 I've got a few options but they don't feel right

7:01 for example, (merge-with (fn [x y] (inc x)) my-map my-map) to apply inc to vals of my-map but it's horribly abusive

7:01 fliebel: rhebus: can you paste a few lines? Sounds to me like you want to do (fn foo [m] (assoc m :foo 2 :bar 3))

7:01 hm

7:02 rhebus: no, i want to apply a fn to each val of a map

7:02 shtutgart: something with update-in

7:03 fliebel: what about (into {} (zipmap (keys m) (map inc (vals m))))

7:03 &(let [m {:a 1 :b 2}] (into {} (zipmap (keys m) (map inc (vals m)))))

7:03 lazybot: ⇒ {:b 3, :a 2}

7:03 shtutgart: rhebus: btw, we have a conversation about including function update (like (update {:a 1 :b 2} :a inc :b dec)) some days ago

7:04 but I forgot to post the suggestion on the google group

7:04 rhebus: those look better than what I had

7:05 (map (fn [ [x y] ] [x (inc y) ]) my-map) was my next try, but that's a list of vectors, not a map

7:05 fliebel: rhebus: you can use (into {}) with that as well.

7:06 rhebus: so keys and vals are guaranteed to preserve respective order? that's kinda neat I guess

7:06 fliebel: zipmap is just a fancy way of avoid handling the key in the map.

7:06 rhebus: yea, that's guaranteed as far as I know.

7:07 rhebus: wait, why do you need into {} with zipmap?

7:07 &(let [m {:a 1 :b 2}] (zipmap (keys m) (map inc (vals m))))

7:07 lazybot: ⇒ {:b 3, :a 2}

7:07 fliebel: rhebus: uh, yea, I'm to used to Python.

7:07 rhebus: :)

7:08 thanks for your help, much appreciated

7:08 fliebel: In Python, zip just goes from [1 2 3] [4 5 6] to [1 4] [2 5] [3 6]

7:10 rhebus: I'm used to perl, where i'd probably copy-and-mutate

7:13 tomoj: (update {:a {:b 3 :c 4}} [:a :b] inc [:a :c] dec) too would be nice

7:13 oh, can't have both

9:50 xom_approves: hi there

9:50 is there an idomatic pattern for this? http://pastebin.com/R6FEvtJF

9:50 i'm really new to clojure, btw :)

9:51 raek: xom_approves: (map extract xml-seq) I believe

9:52 xom_approves: hm

9:52 oh right the paste is simplified

9:52 raek: map is lazy, though

9:52 xom_approves: lazy is good here

9:53 raek: but otherwise the looping code looks good

9:53 xom_approves: basically i need a custom accumulation

9:53 ah okay

9:53 raek: reduce might be applicable too

9:54 xom_approves: god, yes so simple

9:54 thanks raek

9:54 raek: (reduce #(conj %1 (extract %2))) xml-seq)

9:54 (reduce #(conj %1 (extract %2))) [] xml-seq)

9:56 xom_approves: (reduce #(merge %1 (extract %2)) {} xs) in my case

10:28 shtutgart: Hi. How can I specify maximum value of y-axis in the Incanter chart? e.g. (bar-chart [:a :b :c] [10 20 30]) gives me Y values from 0 to 30, but I need maximum value of 100

10:50 cmbntr_: account 0 off

11:38 shtutgart: ,(.getMessage (Exception. "foo"))

11:38 clojurebot: "foo"

11:39 kephale: is there a way to establish symbol bindings for a let from a map? i.e. (let-map {:a 17} [b (inc a)] (inc b))

11:39 since let is a macro apply can't be used

11:40 shtutgart: kephale: if a map should be evaluated in runtime, then no, I think

11:41 Any ideas why I'm getting "java.lang.IllegalArgumentException: foo" on (.getMessage (IllegalArgumentException. "foo"))?

11:42 (of course actually there is more code)

11:44 (try (throw (IllegalArgumentException. "foo")) (catch Exception e (.getMessage e)))

11:44 ,(try (throw (IllegalArgumentException. "foo")) (catch Exception e (.getMessage e)))

11:44 clojurebot: shtutgart: Cool story bro.

11:44 kephale: lol

11:45 shtutgart: eh... I'll better do it via private msgs

11:51 kephale: ah, push-thread-bindings

11:52 err with-bindings seems like the proper thing to use

11:53 shtutgart: but you've said you need locals?

12:00 kephale: well, i really just care about being able to establish bindings from a map, and update the map with new bindings in a sequential let-style

12:03 shtutgart: hm, probably I don't understand the whole thing, but why can't you use оыге здфшт ьфз,

12:03 sorry, I mean "why can't you use just plain map?"

12:04 Don't think that it's good to have a number of global vars for such purposes...

12:05 kephale: ,(-> {'a 7} (assoc 'b 8))

12:05 clojurebot: {b 8, a 7}

12:05 kephale: but I would also like to be able to reference the map

12:06 to get something like:

12:06 ,(-> {'a 7} (assoc 'b (inc a)))

12:06 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

12:06 kephale: clearly that shouldnt work

12:08 shtutgart: ,(let [{:keys [a b] :as m} {:a 1 :b 2}] (-> m (assoc :b (inc a))))

12:08 clojurebot: {:a 1, :b 2}

12:08 shtutgart: bad example, there should be (dec a) to see the difference :)

12:09 kephale: ,(let [{:keys [a b] :as m} {:a 1 :b 2}] (-> m (assoc :c (inc a))))

12:09 clojurebot: {:c 2, :a 1, :b 2}

12:09 kephale: ,(let [{:keys [a b] :as m} {:a 1 :b 2}] (-> m (assoc :c (inc a)) (assoc :d (inc c))))

12:09 clojurebot: java.lang.Exception: Unable to resolve symbol: c in this context

12:10 kephale: I need that ability as well

12:10 which I guess could be accomplished by wrapping an expression like that in a loop

12:11 shtutgart: yeah

12:11 kephale: cool, ty

12:11 shtutgart: but there also should be more elegant and sequntial, loop-free solution

12:14 kephale: well, if there is a way to pull the binding map out of a let

12:14 then

12:14 ,(let [{:keys [a b] :as m} {:a 1 :b 2} c (inc a) d (inc c)] d)

12:14 clojurebot: 3

12:14 kephale: does leverage the let

12:17 shtutgart: what about kind of ##(reduce (fn [m [k v]] (assoc m k (v m))) {:a 1} [[:b :a] [:c :b]])

12:17 lazybot: ⇒ {:c 1, :b 1, :a 1}

12:20 shtutgart: or ##(reduce (fn [m [k f]] (assoc m k (f m))) {:a 1} [[:b #(-> % :a inc)]]), or some combination of the two

12:20 lazybot: ⇒ {:b 2, :a 1}

13:24 Scorchin: leiningen q: should everything in :dev-dependencies and :dependencies go in :exclusions as well?

13:47 dekuderp: how does one verify a record type?

13:48 if I want to create a function with a conditional based on the record passed to it

14:44 mdeboard: technomancy: So I upgraded to swank-clojure 1.3.2, and the `lein run` dev server ran ok for a day or two, but now back to the "RejectedExecutionException" errors from before

14:44 I didn't change anything at all.

14:44 Only thing I did actually was to restart the virtualmachine in which I run ubuntu

15:05 fliebel: What do we think of Gremlin and Blueprints?

15:14 mdeboard: fliebel: Blueprints... the CSS framework?

15:14 fliebel: mdeboard: No, the graph db interface

15:19 dekuderp: when I get an error like this: Key must be integer [Thrown class java.lang.IllegalArgumentException], what kind of mistake should I be looking for?

15:20 https://gist.github.com/1086657

15:20 mdeboard: dekuderp: A traceback would be nice wouldn't it

15:20 dnolen_: first stack overflow core.logic question, fun, http://stackoverflow.com/questions/6713424/how-do-i-express-this-logic/6719627#6719627

15:21 fliebel: dnolen_: congrats, that's quite an accomplishment, but it does remind me of something cgrand said about moustache...

15:21 dnolen_: fliebel: ?

15:21 fliebel: dnolen_: He thought no one was using it because he never got questions about how it worked.

15:22 dekuderp: mdeboard: oh, now I see where the line numbers are

15:22 mdeboard: dekuderp: where

15:22 dnolen_: fliebel: if you're saying that think moustache is a lot easier to understand, I agree :)

15:22 fliebel: yea :D

15:22 mdeboard: orite

15:22 dekuderp: https://gist.github.com/1086660

15:23 I am so used to getting nice clojure errors with the offending line # at the top

15:23 Demosthenes: so i've heard the arguments from the CL people that "of course CL is used for commercial software", but they mean backend with a full lisp environment. racket? they have a handful, seems like web services. is anyone creating client software, like fat clients for windows and linux in clojure?

15:24 dnolen_: fliebel: it's a particular fun question tho, it's a tricky problem solved with very little code (tho I admit I had to think about it for a while)

15:28 dekuderp: I think my mistake is that I thought you could do ('[1 [2 3]] [1 0]) => 2

15:28 or I thought I saw someone use a trick like that to access a nested vector

15:30 dnolen_: ,(get-in [1 [2 3]] [1 0])

15:33 clojurebot: 2

15:33 dnolen_: dekuderp: ^

15:35 dekuderp: dnolen: thanks!

15:35 mdeboard: Demosthenes: I think most of the commercial production clojure products/interfaces are closed-source.

15:35 Demosthenes: mdeboard: i've picked up a few lisp dialects now, generally for unix, scripting, or backend processes. but if i need to deploy a short simple app toa windows client, my options REALLY shrink.

15:36 sbcl was great (awesome debugging!), racket's quick and simple, but neither seems suitable for me to create a short app to deploy to non-IT clients.

15:36 mdeboard: Demosthenes: Were you the guy asking about clj msis?

15:36 Demosthenes: i mean really, i need http/https, TLS/SSL, and a basic gui... :P

15:36 nope

15:37 dekuderp: what can I use to find out what kind of record a var is? I know (instance? record-name var) but I want something like (record-type? var) that returns record-name

15:38 dnolen_: ,(type 1)

15:38 clojurebot: java.lang.Integer

15:38 dnolen_: dekuderp: ^

15:38 bendlas`: hi

15:39 dekuderp: dnolen: thanks again!

15:39 bendlas`: does somebody know, if clutch is compatible with couchdb 0.10?

15:40 in particular, if you can use the clutch view server with 0.10

15:45 mdeboard: ,(min-key - 1 2 3)

15:45 clojurebot: 3

15:45 mdeboard: ,(key 1 2 3)

15:45 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (3) passed to: core$key

15:46 dekuderp: okay here is my code: https://gist.github.com/1086690 and here is the output I'm getting: https://gist.github.com/1086692

15:47 I really don't get how type is returning nothing or java.lang.Class instead of the records I use

15:50 oh I fixed it, I was using (repeat 9 Road) instead of (repeat 9 (Road.))

15:50 stupid me:P

15:52 mdeboard: dekuderp: tsk tsk

15:54 dekuderp: I kid, what you've written there is more than I could do :(

16:27 amalloy: dekuderp: advice: don't use records unless you have a strong performance need

16:28 i filled my first program with records, because i "wanted" classes. but records are (mostly) a higher-performance, lower-convenience version of hashmaps. see http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/ for a handy little flowchart about when to use what

16:28 dekuderp: amalloy: I was going to use structmaps but the clojure data structure page said I should go with records ( http://clojure.org/data_structures )

16:29 amalloy: yes, structmaps are deprecated

16:29 but take a look at cemerick's flowchart. from what i know of your application, you'll wind up at "use a regular map"

16:30 dekuderp: amalloy: thank you, that flow-chart is awesome

16:37 amalloy: dekuderp: it's good policy, btw, to define a function like (make-building args) so that you can switch from hashmaps to records whenever you need to, without needing the client code to change: you can just change the implementation of make-building

16:42 dekuderp: amalloy: so you're saying try to keep the implementation from affecting the design right?

16:42 amalloy: wellll, i would have used the word API, not design

16:43 dekuderp: lol yeah my terminology is pretty bad

17:09 seancorfield: clojure.java.jdbc still uses structmaps (because clojure.contrib.sql did) - i guess that needs to be fixed...

17:10 stuart sierra made a comment about it early on when i took over c.j.j and at the time i wasn't sure what he meant but i opened a ticket http://dev.clojure.org/jira/browse/JDBC-3

17:49 Kenjin: hello

17:57 I'm having trouble setting up clojure with emacs+slime. M-x clojure-jack-in just hangs with "Starting swank server..."

18:02 jonabbey: is emacs in the right directory?

18:02 i.e., try loading the project.clj file from lein and then run the M-x clojure-jack-in from that buffer

18:14 Kenjin: jonabbey: how do I load project.clj from lein

18:21 jonabbey: I open project.clj in emacs and run M-x clojure-jack-in and its seems slime.el is dumped in the *swank* buffer

18:27 amalloy: Kenjin: you can narrow down the problem by trying `lein swank` from the command line, followed by M-x slime-connect

18:27 if either of those steps succeeds, the problem is probably with the other step (if they both succeed, something's wrong with jack-in)

18:27 Kenjin: On the swank-clojure readme it says "From inside a project, invoke M-x clojure-jack-in". What does "from inside a project" mean?

18:27 amalloy: thank you. I'll try that

18:41 raek: Kenjin: from any file somewhere in the project tree (even outside src/ works)

18:41 dekuderp: I can use :type as a key in a map, right? or is it some clojure keyword?

18:41 Kenjin: raek: understood. thank you

18:42 raek: dekuderp: the keyword with the name ":type" is not special in any way

18:43 dekuderp: raek: thanks

18:44 amalloy: raek: it's a little special, isn't it? ##(doc type) looks it up in the metadata

18:44 lazybot: ⇒ "([x]); Returns the :type metadata of x, or its Class if none"

18:46 amalloy: not that dekuderp cares about that

18:48 Raynes: amalloy: Yeah, the keyword itself is just a normal keyboard. It just happens to be the keyword that type looks for in metadata.

18:49 The name of defn includes the letter 'd'. Doesn't make 'd' special.

18:53 Kenjin: is the issue with slime and autodoc still unresolved?

19:00 dekuderp: okay here is my new code: https://gist.github.com/1086893 and the output: https://gist.github.com/1086896

19:00 I have no clue how I'm screwing this up so badly

19:32 mdeboard: Why does this work ok: http://p.mattdeboard.net/mcount_good.html but this does not: http://p.mattdeboard.net/mycount_bad.html (note the reversal of the args)

19:39 amalloy: mdeboard: your pastes give me an nginx timeout error. try gisting instead?

19:40 mdeboard: improperly configured apache :(

19:40 try again

19:41 had to reboot servar :(

19:41 amalloy: mdeboard: you swapped args to mycount but not to recur

19:41 mdeboard: oh, gosh.

19:45 dekuderp: okay, I finally got my code working: https://gist.github.com/1086926

19:46 I tried cleaning it up and tried to use the paradigms you guys talk about, but if anyone could suggest any way I could make it simpler I'd really appreciate it

19:48 amalloy: dekuderp: it's more common to use :building for type rather than "building". keywords are pretty good at enum-like things

19:49 i'd delete the five-argument version of add-buildings and make it a (loop ... (recur)) in the three-argument version

19:53 mdeboard: awesome solution to 4clj #25 imo

19:53 #(->> % (filter odd?))

19:54 amalloy: mdeboard: isn't that just #(filter odd? %)?

19:54 mdeboard: oh, yeah probably. I chose ->> at first because I misread the problem at first.. thought there was some follow-on operation I had to do

19:55 mostly just happy I properly used ->>

19:55 amalloy: *smile*

19:55 it's an exciting thing to use

19:55 dekuderp: amalloy: I don't understand your first point. So I would have a key (:building) that matches to nothing, and then rewrite to just check if that key exists?

19:55 amalloy: dekuderp: nono, :type is fine

19:55 for example, (defn make-road [] {:type :road})

19:56 dekuderp: and then I would have (= :road (:type road-obj)), right?

19:56 amalloy: yeah

19:56 dekuderp: okay, now I get it

19:57 amalloy: dekuderp: here's a skin-deep rewrite of add-buildings: https://gist.github.com/1086948

20:00 and (defn world-obj-to-str [world-obj] ({:building "B", :road "r", :firefighter "F"} (:type world-obj))) has a lot less boilerplate

20:03 dekuderp: amalloy: in your gist you used let to define new-world, in clojure is it normal to bind a var to let if it's referenced more than once?

20:03 amalloy: that's exactly what let is for

20:04 dekuderp: for some reason I thought it was overkill to use if I wasn't defining more than 2 variables...

20:04 amalloy: i mean, you can use it for things that are only referenced once; it's often more readable that way because you can split things up

20:04 but reuse is the main goal

20:05 dekuderp: amalloy: thanks again for all this useful info

20:05 amalloy: dekuderp: nah, overkill is writing the same four lines of code twice to avoid a let :)

20:07 dekuderp: lol well now I know that's cool to try and minimize repeating code

20:08 I'm just so used to java and constantly repeating myself I guess

20:10 amalloy: heh

20:10 dekuderp: well, java has local variables too

20:10 a way you can really outdistance java is by defining local *functions* to avoid repeating sections of code

20:14 mdeboard: 4clj #23 is a SOB. #(map - (sort (map - %))) works for all the examples except the last one :(

20:14 http://4clojure.com/problem/23

20:15 amalloy: dekuderp: https://github.com/flatland/useful/blob/develop/src/useful/fn.clj#L28 is an example of that sort of thing. don't worry about understanding the whole function - it's pretty abstract and a little messy. but see how i'm defining a local function `call` to avoid rewriting that code

20:16 mdeboard: isn't this problem asking you to reverse a sequence, not sort it in reverse order?

20:16 mdeboard: Yeah. :P I was being cheap.

20:16 amalloy: *chuckle*

20:16 mdeboard: didn't even look at the third one.

20:17 amalloy: if you wanted to do it that way, btw, ##(sort-by - [1 2 3 4 5]) is simpler

20:17 lazybot: ⇒ (5 4 3 2 1)

20:17 mdeboard: ahh

20:17 was wondeirng how that worked

20:17 amalloy: and is equivalent to what you were doing, i think

20:17 mdeboard: there you have it

20:17 yeah

20:17 definitely is

20:18 I guess just running "shuffle" until they appear in the proper order would be cheap too

20:19 (a joke)

20:20 amalloy: $google bogosort

20:20 lazybot: [Bogosort - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Bogosort

20:21 mdeboard: lol

20:21 Yeah, tha

20:21 amalloy: mdeboard: quantum bogosort is a nice refinement of tha algorithm, getting it down to O(n)

20:22 mdeboard: lolirl

20:22 yeah I guess all possible permutations would exist simultaneously

20:39 amalloy: Explain:

20:39 ,(into '() [1 2 3 4 5])

20:39 clojurebot: (5 4 3 2 1)

20:39 mdeboard: why is that reversed?

20:39 amalloy: &(conj '(1 2 3) 4)

20:39 lazybot: ⇒ (4 1 2 3)

20:40 mdeboard: Ohhh

20:40 amalloy: lists (and seqs in general) conj on the left

20:40 mdeboard: oh righ tlisp reads right ot left

20:40 amalloy: uhhh

20:41 i don't understand that explanation

20:43 mdeboard: Don't fight it, it will just make this more difficult

20:50 amalloy: &(reduce (partial list 'conj) () [1 2 3 4 5])

20:50 lazybot: ⇒ (conj (conj (conj (conj (conj () 1) 2) 3) 4) 5)

20:51 amalloy: mdeboard: that's what into is doing, under the hood. and because ##(conj '(1) 2) is '(2 1), the whole thing balloons out to the left

20:51 lazybot: ⇒ (2 1)

20:51 mdeboard: ahh

21:41 tomoj: I just met the expression problem face to face for the first time I think

22:02 mdeboard: amalloy: In problems.clj for 4clj what is the ":_id" keyword? It's all ove rthe place. Is it a function? Shortcut for a query?

22:02 amalloy: mdeboard: mongodb's unique identifier. each document you store gets a new _id

22:03 mdeboard: specifically "(apply min-key :_id unsolved)"

22:03 amalloy: we (wrongly imo) hijack that to be the problem's numeric id

22:03 mdeboard: just get the smallest id among unsolved

22:03 amalloy: so http://4clojure.com/problem/23 has its data stored in mongo with an _id of 23

22:04 anyway, (apply min-key :_id unsolved) isn't *exactly* what you said. it returns the problem with the smallest id, not the smallest id

22:04 mdeboard: ah ok

22:05 yeah that makes sense

22:05 amalloy: &(let [problems [{:_id 4 :data "TEST", :_id 9 :data "SAMPLE"}]], (apply min-key :_id problems))

22:05 lazybot: java.lang.IllegalArgumentException: Duplicate key: :_id

22:05 mdeboard: kind of like an ORM in practice

22:05 amalloy: &(let [problems [{:_id 4 :data "TEST"} {:_id 9 :data "SAMPLE"}]], (apply min-key :_id problems))

22:05 lazybot: ⇒ {:_id 4, :data "TEST"}

22:06 amalloy: not really. i mean, i don't use any ORMs, but my understanding is that they're for mapping the application level notion of objects onto the table-oriented database

22:06 mongodb is a document/object centric db, so we just put maps in and get maps out

22:10 mdeboard: amalloy: http://p.mattdeboard.net/nextunsolved.html would this work to only retrieve problems whose id is greater than the last problem solved? Biggest annoyance with 4clj righ tnow

22:10 for me

22:10 I can't run lein run to test it out myself unfortunately

22:11 getitng those execution exceptions

22:11 s/test it out/play with it

22:12 amalloy: mdeboard: care to step into #4clojure?

22:12 mdeboard: sure

Logging service provided by n01se.net