#clojure log - Jun 15 2011

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

0:01 duck1123: I actually am making progress, but I'm using maven, so am not much help

0:01 I got it to run the feature and start my server

0:35 technomancy: does anyone use derive to specify ad-hoc type hierarchies?

0:50 dnolen: technomancy: I have in the past, why?

0:51 technomancy: dnolen: I'm just mulling over some issues of exception handling and wondering why it is that "catch" works based on types... is it because that's how it's done in Java, or because catching based on types is a good idea?

0:52 dnolen: calculating the isa? relationship on hierarchies is quite slow compared to instance?

0:52 technomancy: sure, but for exception handling that's less of an issue than arbitrary dispatch

0:53 context: https://github.com/technomancy/slingshot/tree/handle

0:54 dnolen: technomancy: so little has happened around error handling in any way in core that I think this just a part of Clojure that is particularly conservative. how do you plan do deal with catching custom error types from the Java side?

0:54 chouser: I think using types for exception categorization is pretty clumsy.

0:54 technomancy: dnolen: there's a gen-classed data-carrying exception that descends from RuntimeException

0:54 chouser: error-kit does it, but I think it was a bad idea

0:55 wouldn't we rather have tags than folders?

0:55 dnolen: technomancy: huh and that's used in core?

0:55 technomancy: dnolen: could be =)

0:55 working largely from http://dev.clojure.org/display/design/Error+Handling

0:56 chouser: leaning that way myself

0:56 dnolen: chouser: it's not that I disagree per se, it's just I thought something cool would have happened by now around error handling :)

0:56 technomancy: chouser: on the other hand, it could be that we don't like using types because it's only recently that we've been able to define low-ceremony types

0:57 (playing devil's advocate)

0:57 anyway, that link has an implementation of arbitrary-predicate catch

0:57 as well as a derive-aware catch

0:58 (bonus goodness: you can destructure, which is pretty sweet)

0:58 and the question is whether type-based catch dispatch is primarily for interop purposes

0:58 chouser: that's my understanding.

0:59 technomancy: we'll get this out on a the mailing list soon, I'm just mulling it over in my head trying to boil it down to the core issues

1:01 the open issue is whether in (catch :keyword ex [...]) :keyword should be interpreted as an ifn or as an isa? type

1:01 scgilardi: I'm in favor if isa? type (as implemented by :type metadata)

1:02 technomancy: if the former then you can just stick with try/catch; if the latter then I think it's best to introduce try/catch/handle (as I've been calling it) where handle explicitly calls out the fact that you're providing an arbitrary ifn

1:02 scgilardi: sorry, meant to wait till we had hashed it out internally more, but I got carried away =)

1:02 scgilardi: if we fix the degenerate case of partial (where we partial just an ifn), then (partial :a-keyword) becomes a great way to make it clearly a predicate

1:02 which I really think is going to be a rarely used/desired case

1:04 (partial :my-keyword) isn't currently legal, but I'm suggesting it be made legal

1:06 technomancy: no problem. good to get lots of input.

1:06 technomancy: dnolen: re: something happening by now: c.c.condition provides a fair bit of this goodness, but we haven't been using it as much as we could if it were baked in everywhere

1:07 so we're playing around with clj-nstools to let us pretend like try+ and throw+ are in clojure.core without performing actual monkeypatching

1:13 dnolen: technomancy: both c.c.condition and slingshot look interesting. I wonder if throw+/catch terminology should be avoided as it was in c.c.condition?

1:13 hiredman: condition had raise

1:14 (has)

1:14 raise/handle/handle-case

1:15 technomancy: dnolen: handler-case in c.c.condition didn't use the word catch because it was structured differently; you had to specify a single predicate up-front, and each clause matched against the value of running that predicate against the raised condition

1:15 dnolen: whereas try+ and throw+ are entirely additive; the structure is the same as try and throw

1:15 hiredman: it wasn't really a predicate

1:16 a "selector"

1:16 more like condp

1:16 technomancy: hiredman: true; exactly like condp

1:16 except for being slightly different

1:16 dnolen: even so throw/catch will probably always denote a low level Java thing. just thinking some newer should well ... look newer.

1:17 technomancy: I've been thinking of it as similar to how slurp "gained super powers" with the introduction of c.j.io

1:17 it's still called slurp, but it works on more than just filenames

1:18 but I don't really care, as long as I can throw maps, dispatch on keywords, and destructure in catch.

1:19 hiredman: it is hard to image how else something like try/catch would be structured given the limitations of the jvm

1:20 the other thing I don't think technomancy or scgilardi mentioned is slingshot exceptions carry locals information

1:20 from &env

1:22 technomancy: hiredman: yeah... actually the wiki page actually explicitly called that out as being too high a price to pay all the time. so that will probably need to depend upon (System/getProperty "clojure.debug")

1:22 but!~ cool to have.

1:23 hiredman: dunno, if you are really concerned about exception costs then try/catch instead of try+/catch

1:23 dnolen: technomancy: well one thing I never loved about ad-hoc hierarchies was that it's a global mutable thing. and I'm not a fan that complex hierarchies push towards prefers.

1:24 technomancy: dnolen: yes, that's a big downside. pulling in unrelated 3rd-party libraries could change the result of an isa? call unexpectedly

1:24 hiredman: mmm, and the isa? in try+ doesn't allow for specifing your own hierarchy

1:25 technomancy: anyway, my battery's not long for this cycle; will get this onto the mailing list soon

1:25 * technomancy &

1:25 sexpbot: java.lang.Exception: EOF while reading

4:50 tsdh: I'm trying to work with some external java objects. How can it be that (class x) returns foo.bar.Baz, but foo.bar.Baz at the REPL or (Class/forName "foo.bar.Baz") throws a ClassNotFoundException?

5:10 Klanker: am I doing something wrong.... I put 7000 integers into sorted set, then when I try to execute (into '() sort-set) it runs for more than 30 minutes

5:11 I could sort those numbers faster than clojure sorted map/set by hand

5:18 tsdh: Klanker: (into '() (sorted-set (range 0 7000))) works instantly here...

5:19 Klanker: Ditto for (into '() (sorted-set (shuffle (range 0 7000)))) where there's real sorting going on.

5:19 bsteuber: tsdh: here, too - but you mean (apply sorted-set ...)

5:19 otherwise the set just gets one element

5:20 tsdh: bsteuber: Oh, indeed. Well, still instantly.

5:22 no_mind: I have a sequence of maps and I want to create one map by merging all maps. How do I do this ?

5:22 Klanker: into?

5:22 reduce into I guess

5:24 fliebel: Or merge/merge-with

5:25 Either apply or reduce works, I've heard arguments for either.

5:25 bsteuber: ,(apply merge [{:a 1} {:b 2}])

5:25 clojurebot: {:b 2, :a 1}

5:27 tsdh: What's the clojure way to define some new exception classes?

5:28 Klanker: you can use gen-class to generate new class files

5:29 but I see no reason why not to just write a java class

5:31 tsdh: Klanker: Hm, my app is plain clojure and I guess putting in java classes will put a setup burden on me, or not?

5:31 Klanker: not really

5:31 if you just put compiled class files in classpath

5:32 tsdh: Klanker: Yeah, so I have to tell lein/cake somehow that it should also compile the java files to class files somehow.

5:49 ilyak: I have a macro with (.. some some some) in it

5:49 and apparently it doesn't get expanded

5:49 because it would then complain

5:49 How would I force macro expansion inside macro `body?

5:50 Klanker: how do I paralelize filter operation?

5:51 fliebel: $source filter

5:51 sexpbot: filter is http://is.gd/vU4rfX

5:52 fliebel: Klanker: Easiest would be to split up the task with partition and then stitch it back together.

5:52 Klanker: partition?

5:52 clojurebot: partition is probably not what you want; see partition-all.

5:52 fliebel: $source pmap

5:52 sexpbot: pmap is http://is.gd/mVHNdG

5:53 Klanker: I thought about something like pmap?

5:53 the-kenny: Looks like sexpot is off a few lines

5:54 ilyak: Is there a good doc on macros covering all obscure symbols you have to use?

5:54 fliebel: Klanker: Well, if the filter is expensive, you could run pmap and then filter identity.

5:54 Klanker: I guess

5:55 fliebel: Or (apply concat (pmap #(filter pred %) (partition 32 seq)))

5:55 Or do ith the hard way and write pfilter.

5:56 Klanker: :)

5:56 I just ran it on a part of the problem

5:56 since I need cores for work

5:57 but later when this workstation will be idle I'll just add the rest on paralel :)

6:00 beyeran: hi, is there any way to set up a clojure repl in emacs without using the ELPA package?

6:00 the-kenny: Setup Slime by hand

6:00 Then start the swank-server somehow (lein swank, whatever), M-x slime-connect

6:01 beyeran: I've tried it but after a few seconds I get a runtime exception and the server quits

6:04 the-kenny: That's strange

6:07 beyeran: It seems that I'm not the only one with this problem but the only solution I've read would be installing slime through ELPA. This isn't what I want because other Lisp dialects are configured with slime manually. Both versions would be odd.

6:09 mrBliss: beyeran: I have a working Slime setup that supports Clojure & Common Lisp at the same time (without restarting!). Do you want me to explain it?

6:11 beyeran: mrBliss: that would be nice!

6:12 mrBliss: beyeran: ok, use this version of Slime: https://github.com/hugoduncan/swank-clj/tree/develop/slime

6:12 and clone this repo: https://github.com/TerjeNorderhaug/swank-clojure

6:12 compile and install it locally,

6:13 call it swank-clojure-1.3.1-slime or something

6:13 lein plugin install swank-...

6:14 remove existing swank-clojure dependencies from your poject.cljs and you should be good to go

6:15 beyeran: mrBliss: thank you, I try it

6:27 mrBliss: and how do you actually switch between a lisp and a clojure repl?

6:28 mrBliss: C-c C-x c to bring up a list of repls and 'd' to select the default

6:28 dbgster: how do I import clojure.set into repl?

6:28 the-kenny: dbgster: (use 'clojure.set)

6:28 ilyak: (defmacro [item & args] `(.. item ~@args something)) <- what's the correst way of writing this?

6:28 i.e. one that would actually work

6:28 mrBliss: beyeran: clojure repls are started with (lein swank), slime-connect and CL repls with slime

6:29 dbgster: the-kenny: hanks

6:29 thanks

6:30 beyeran: mrBliss: very nice, thank you!

6:31 mrBliss: beyeran: I'm glad it works for you too

6:32 beyeran: mrBliss: yes, I've tried several solutions but none of them fits for me with lisp and scheme running, now it finally works!

6:32 the-kenny: mrBliss: Oh, it is possible to have multiple connections open at the same time? Nice

6:33 Didn't know that

6:33 mrBliss: beyeran: do you use slime Scheme as well? I use geiser for Scheme.

6:33 the-kenny: It's not always easy to assign a buffer to a particular connection though.

6:38 beyeran: mrBliss: Geiser? Never heard of it, I'm going to look it up

6:39 mrBliss: beyeran: Geiser is to Scheme as Slime is to CL :-)

6:40 beyeran: it only works well with Guile and Racket though

6:41 beyeran: mrBliss: looks very interesting!

6:41 ilyak: Figured it out, had misaligned ()s

6:41 beyeran: mrBliss: I've used Scheme mainly for educational reasons, not as much as CL, that may be the cause why I haven't heard of it...

6:43 mrBliss: beyeran: I've only used it (mit-scheme) for The Little Schemer, but I'm planning to do SICP. I just like tinkering with my Emacs config, so I installed geiser for fun (and SICP after my exams) ;-)

6:44 beyeran: mrBliss: Yes, it'

6:44 mrBliss: Yes, it's massive :-)

6:51 gilecham: www.freenode.org

6:58 jonasen: Feedback / proof reading request: https://github.com/jonase/cljcsv/wiki/Intro

7:03 manutter: jonasen: typo in second paragraph: separetad should be separated

7:06 jonasen: manutter: thanks

7:08 manutter: and one other typo: in "The forth line parses every row of stock data as we saw in the previous section.", should be "fourth" not "forth".

7:09 Other than that it looks pretty good, you have absolutely no need for the disclaimer about "English is not my native language" :)

7:11 jonasen: fourth, not the programming language forth! :)

7:11 manutter: Exactly :)

7:12 jonasen: Ok. I removed "Enlish is not...". Thanks for your time :)

7:12 manutter: np, anytime

7:23 zoldar: Neither I'm an English native speaker, but I think that here: "...want to provide feedback*,* do not hesitate to contact..." and here "...In order to have some data to work with*,* I visited..." commas would be helpful

7:25 and here "... replaced with ((juxt ...) #(apply ...)))*,* we'll get both the highest increase as well decrease: ..."

7:30 timvisher: hey all

7:32 i'm dealing with a utf-8 string encoded by java.net.URLEncoder and I'm trying to get it back into clojure through a compojure route.

7:32 zoldar: and this: "highest increase as well *as* decrease:"

7:33 timvisher: The title is `Musée gallo-romain de Fourvière` and the encoded url is `/thumbnail/Mus%8Ee+gallo-romain+de+Fourvi%8Fre`

7:33 Is there anything special I need to do to tell clojure that that is a utf-8 string for comparison with another string?

7:33 jonasen: zoldar: fixed

7:35 timvisher: This is the context that I'm trying to use the title in. https://gist.github.com/1026917

7:52 raek: timvisher: the URL should be encoded in UTF-8, but to me it looks like it's in Latin-1

7:52 ,(seq (.getBytes "Musée gallo-romain de Fourvière" "UTF-8"))

7:52 clojurebot: (77 117 115 -61 -87 101 32 103 97 108 ...)

7:52 timvisher: raek: ah

7:53 raek: ,(for [i (seq (.getBytes "Musée gallo-romain de Fourvière" "UTF-8"))] (format "%02x" i))

7:53 clojurebot: ("4d" "75" "73" "c3" "a9" "65" "20" "67" "61" "6c" ...)

7:53 raek: ,(for [i (seq (.getBytes "Musée gallo-romain de Fourvière" "ISO-8859-1"))] (format "%02x" i))

7:53 clojurebot: ("4d" "75" "73" "e9" "65" "20" "67" "61" "6c" "6c" ...)

7:53 timvisher: bah! I'm using the deprecated encode(String) method

7:54 I'm not specifying the encoding.

7:54 * timvisher needs to RTFM

7:57 timvisher: raek: that did it. I'm an idiot. :)

7:57 * timvisher hangs his head in shame.

7:58 opqdonut: oh my

7:58 ,(clojure.set/difference (set [0 300 :a]) [:a :b])

7:58 clojurebot: #{0 300}

7:58 opqdonut: ,(clojure.set/difference (set [0 300 :a]) [:a :b :c :d])

7:58 clojurebot: #{:a 300}

7:58 opqdonut: ,(clojure.set/difference (set [0 300 :a]) (set [:a :b :c :d]))

7:58 clojurebot: #{0 300}

8:00 raek: timvisher: anyway, cred to you for actually caring about encoding. and it's not your fault Sun made bad API design decisions...

8:01 timvisher: if you use ring, you can also use this function: http://clojuredocs.org/ring/ring.util.codec/url-encode

8:01 opqdonut: how do I report a bug?

8:01 raek: but it's just a wrapper that defaults to UTF-8 :-)

8:02 opqdonut: http://dev.clojure.org/display/design/JIRA+workflow

8:03 opqdonut: how do I find JIRA?

8:04 okay, found it

8:04 a straight link from clojure.org might be nice

8:04 raek: yeah, there are a lot of links that should be there...

8:04 opqdonut: so I have to sign up to file a bug?

8:06 raek: opqdonut: yes, looks like you need to do that

8:06 opqdonut: hmh.

8:06 raek: but you don't need to sign the Contributor Agreement or anything to just report a bug

8:06 opqdonut: yeah but it's one more account to one more web thingy

8:06 *sigh*

8:07 raek: opqdonut: make sure to do a little check on the Clojure and Clojure-dev google groups to see if this has been discussed already

8:07 opqdonut: sorry, I just want to be a user

8:08 I'll file the bug and it'll get closed if it's a dupe

8:08 but it is still present in master

8:12 fliebel: Does anyone have a good resource to make a simple NIO client/server without getting into netty and aleph?

8:15 stuartsierra: fliebel: "simple" and "NIO" don't really belong in the same sentence.

8:15 duck1123: aleph really isn't that bad though

8:15 I just recently switched, and I'm really liking it

8:15 fliebel: duck1123: I like it too, but I want to dig down to the core of it.

8:16 duck1123: then yeah, simple really won't apply to you

8:17 fliebel: stuartsierra: Hm, it's Java after all. I was hoping to do something like those async Python things, with a nice loop olling for stuff and invoking callbacks and such.

8:17 *polling

8:17 stuartsierra: It's not impossible; the Java NIO tutorials are there. But you have to mess about with byte buffers.

8:18 pyr: duck1123: can't you just use lamina2

8:18 s,lamina2,lamina

8:19 duck1123: well, lamina is what aleph is using.

8:19 he already wrote all 3 libraries for this very purpose

8:21 Klanker: does clojure demote numbers too?

8:25 stuartsierra: demote?

8:27 fliebel: Okay, maybe I should not try to take it from the NIO level, but what I want to do is experiment with different execution and dispatch methods.

8:32 gfrlog: (defn only [foos] (assert (= 1 (count (take 2 foos)))) (first foos))

8:51 tsdh: Is there a function to reverse a map, that is, swap keys and values?

8:52 Fossi: and upon duplicate values does what?

8:53 tsdh: Fossi: Best would be to error.

8:53 But we may assume the map is a partial bijection for now.

8:54 stuartsierra: tsdh: I think clojure.set/invert-map

8:56 tsdh: stuartsierra: It's actually map-invert, but that's what I've been looking for.

9:15 Borkdude: Why does this return #{(1 2)} and not #{} ? (apply intersection (set ['(1 2)]) (list))

9:16 opqdonut: the set operations are slightly broken when they're given non-sets

9:16 oh wait, no

9:16 you say _apply_

9:16 so you take the intersection of only one set, (set ['(1 2)])

9:17 ,(clojure.set/intersection (set ['(1 2)]) (set))

9:17 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$set

9:17 opqdonut: ,(clojure.set/intersection (set ['(1 2)]) (set (list)))

9:17 fliebel: opqdonut: In what way are they broken?

9:17 clojurebot: #{}

9:17 opqdonut: fliebel: http://dev.clojure.org/jira/browse/CLJ-810

9:17 Borkdude: the list could contain zero or more sets

9:18 opqdonut: they do surprising things when given non-sets. but I misread Borkdude's code, he's passing only sets

9:18 Borkdude: that's kinda like ##(apply - 1 (list))

9:18 sexpbot: ⟹ -1

9:18 Borkdude: so if it contains zero sets it is just intersection of one set, ok, that makes sense I guess

9:18 opqdonut: hmm, bad example

9:18 but yeah

9:19 Borkdude: then I will have to make a special case for this in my code

9:41 ilyak: what's the best way to transform list of lists to list?

9:41 chouser: (apply concat listlist)

9:41 opqdonut: apply concat

9:41 or flatten, if you don't have three levels anywhere

9:42 ilyak: I do

9:48 chouser: ,(apply concat '((1 2 3) (4 5 6) (7 (8 (9)))))

9:48 clojurebot: (1 2 3 4 5 6 7 (8 (9)))

9:48 chouser: ,(flatten '((1 2 3) (4 5 6) (7 (8 (9)))))

9:48 clojurebot: (1 2 3 4 5 6 7 8 9)

9:49 chouser: ,(apply concat '((1 2 3) 5 (7 (8 (9)))))

9:49 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

10:01 dnolen: https://gist.github.com/1026540 parser for Lisp in core.logic. dog slow until I get a deeper understanding of pruning ....

10:10 mrBliss: dnolen: I really like the work you're doing. Do you plan on adding comments or docstrings to core.logic? It would make reading the code examples much easier ;-)

10:22 ilyak: hi *

10:23 I have a construct like (let [^SQLQuery query (.createSQLQuery sF whatever)] (.. query (addScalar foo foo) (setParameterList bar bar)))

10:24 and clojure complains that it can not resolve calls to addScalar and setParameterList

10:24 (i.e. it would use reflection)

10:24 jweiss: i'm getting an NPE in technomancy 's serializable-fn lib, thrown by flatten. i can't figure out what i can pass to flatten to make it throw NPE

10:24 ilyak: Why is that? I think that it should be able to

10:24 (Maybe it's because this construct is located inside macro?)

10:25 gfrlog: ilyak: you're trying to call two methods on the query?

10:25 chouser: ilyak: (a) I wouldn't worry about it. turn off reflection and be happy. Or (b) make sure the *arguments* to the methods are hinted enough as well

10:26 gfrlog: oh never mind I forgot how (..) works

10:26 ilyak: gfrlog: It's hibernate query, it supports method chaining

10:27 gfrlog: jweiss: you could redef (flatten) to try to catch whatever is doing it, right?

10:27 ilyak: chouser: Arguments are literals mostly in another method

10:27 gfrlog: (just for debugging I mean)

10:27 ilyak: (since it's macro)

10:27 chouser: How would one turn off reflection and what would happen then?

10:27 chouser: sorry, turn off reflection warnings

10:27 ilyak: Oh

10:28 chouser: (set! *warn-on-reflection* false)

10:28 ilyak: But the problem is that the code is performance sensitive

10:28 chouser: oh

10:28 :-(

10:28 gfrlog: tell the code to man up

10:28 ilyak: (tho I understand that SQL query is something which would eat any constant perfomance gains)

10:28 (So I'm probably barking at the wrong tree)

10:30 Would jvm7 have invokedynamic?

10:30 (would jvm7 ever be?)

10:30 jweiss: gfrlog: yeah, but i don't want to redefine flatten, i want to know what it's choking on

10:31 it's a well-known enough fn that i would think if it were a bug it'd be fixed by now. so it's not a bug in flatten, it's just certain inputs cause NPE, someone must already know what inputs do that

10:32 gfrlog: jweiss: I don't mean redef it to make your code run, I mean redef it to find what it's chocking on

10:32 s/chocking/choking

10:32 sexpbot: <gfrlog> jweiss: I don't mean redef it to make your code run, I mean redef it to find what it's choking on

10:33 gfrlog: jweiss: e.g., redef it to wrap a call to the old (flatten) in a try block, and when it catches an error, print out the args that made it choke

10:34 jweiss: gfrlog: i see

10:34 gfrlog: (let [old-flatten flatten] (binding [flatten (fn [& args] (try (apply old-flatten args) (catch Exception e (prn "(flatten) choked on" args) (throw e))))] (do-stuff)))

10:35 jweiss: ^ that is of the top of my head, totally untested

10:36 I don't even know if the parens match

10:38 dnolen: mrBliss: yeah I will at some point, though I can't promise soon, things are far from being shaken out.

10:39 gfrlog: Can somebody explain what's up with ^dynamic in 1.3? Specifically, I thought the change meant that you couldn't do (binding [my-var ...]) on a var not declared dynamic, but yet I thought I saw a (with-redefs) somewhere that claimed to work around it somehow. Does that mean that you're still allowed to redef, but not to use the (binding) stack-thing?

10:39 cemerick: So, google spreadsheet forms are just as crummy as they were last year… :-/

10:39 dnolen: gfrlog: with-redefs changes the root binding and then restores. only good for mocking nothing else really.

10:39 jweiss: gfrlog: interesting, the underlying problem is that the lib tries to get a field .v on some object that doesn't ahve that field. probably supposed to be some internal clojure class that has it, and whatever it's analyzing isn't of that class

10:40 gfrlog: so you can change the root binding but you can't use the bindings-stack, is that accurate?

10:40 if so, I'm surprised that that change affects performance. But that's because I don't know how it's all implemented.

10:42 chouser: Rich talked about how that's implemented and why it's faster in a talk at Clojure Conj 2010

10:42 which should be available as a video somewhere.

10:42 gfrlog: chouser: I guess I wasn't listening then, cause I was there

10:42 chouser: heh. oh. :-)

10:42 gfrlog: or at least I've since forgotten

10:43 but I'll look it up to refresh, thanks

10:43 I assume it's the talk that wasn't about hammocks

10:44 mrBliss: apparently that video hasn't been uploaded :-(

10:45 gfrlog: I remember him talking about the subject but don't remember the technical details

10:46 chouser: oh no, really?

10:46 gfrlog: the clojure blip site has neither of the hickey keynotes

10:47 chouser: I'm pretty sure he talked about the global var version number, and I doubt that's documented anywhere else other than the code.

10:48 gfrlog: that rings a faint bell

10:48 faintly rings a bell? rings a very small bell?

11:00 chouser: So, I'm watching Halloway's Radical Simplicity talk

11:00 and he's dumping on my 'show' function, as is his right

11:01 and using it to demostrate the power and benefits of decomposing a problem into simple parts

11:02 But my problem with that line of reasoning is that I know the end of this story, and what we have now at the REPL instead of 'show' is lousy to actually *use* compared to 'show'

11:04 wastrel: what's show?

11:04 chouser: just lets to look at the methods and fields provided by a Java class.

11:04 halfprogrammer: reflection utility

11:06 I would have loved to have both show and whatever Halloway explained the talk. That would have made life simpler

11:28 gfrlog: leiningen's checkouts feature works splendidly

11:45 symbole: Is it wise to use clojure 1.2.1 with clojure-contrib 1.2.0? Is it recommended for their versions to match?

11:58 pjstadig: symbole: there is no 1.2.1 release of contrib AFAIK

11:59 i think it's fine to mix 'em

11:59 symbole: pjstadig: Thanks.

12:07 pao: hi all! do you suggest 1.2 or 1.3 for learning clojure?

12:08 gfrlog: 1.2 is probably more googleable...? :/

12:08 fliebel: Good point, but I wouldn't shy away from 1.3 if you get the chance.

12:09 gfrlog: I personally don't even know how to obtain 1.3 :-D

12:09 fliebel: gfrlog: That's just a matter of finding the right Lein line.

12:09 gfrlog: yeah, I figured so

12:10 dnolen: :dependencies [[org.clojure/clojure "1.3.0-alpha8"]]

12:10 gfrlog: fliebel: was that a pun?

12:10 pao: fliebel, thanks :-)

12:10 fliebel: [org.clojure/clojure "1.3.0-alpha7"] it is I believe. oh dnolen is fats!

12:10 fats

12:10 grr!

12:10 pao: fliebel, using leinin is ok even when the initial goal is only to get a repl?

12:11 dnolen: lisp parser in core.logic that's 40X faster than previously than earlier, https://gist.github.com/1026540

12:11 commited-choice for the the win.

12:11 fliebel: pao: Yea, or cake. Cake is more customizable as a standalone repl.

12:11 * pao is googling for cake ...

12:12 gfrlog: pao: I believe "lein repl" will launch a repl with no surrounding project

12:12 manutter: "googling for cake" I shoulda named my new blog that

12:13 fliebel: gfrlog: cake will do the same, but has a global project somewhere that you can customize.

12:13 gfrlog: ah hah

12:13 pao: gfrlog, but I guess I need to specify the clojure version somewhere, right?

12:13 manutter: I just typed "lein repl" with no project, and it brought up a repl without complaining

12:13 fliebel: pao: Right, lein just gets you 1.2.1, cake gets you whatever your global project is.

12:13 gfrlog: pao: oh right. So if you want to do that, then you probably need a project. I don't know nuthin bout cake, but these folk make it sound good

12:14 don't you gotta have rubygems to install cake?

12:14 fliebel: dnolen: Nice! Whats "than previously than earlier"

12:14 gfrlog: That's the easy way. You cna also get it right from github.

12:14 gfrlog: oh okay; that's more reasonable

12:15 pao: is cake that written in ruby

12:15 ?

12:15 s/that//

12:15 duck1123: clojure 1.3 is good, but be prepared to have to hack every single library you touch

12:15 fliebel: pao: It's wrapped in Ruby sause for convenience. The larges part of it is still Clojure.

12:16 pao: fliebel, thanks

12:16 dnolen: fliebel: actually much more than 40X faster, I had an earlier version that didn't do pruning, it's runtime grew exponentially on the number of tokens.

12:17 * pao after cake googling is going to eat the cake :-)

12:19 fliebel: dnolen: Interesting. Any thoughts about ambiguity? Have you compared it to the 'official' reader?

12:22 dnolen: What am I looking at here? A toy, or an aspect of something bigger(types?)?

12:22 dnolen: fliebel: no thoughts on ambiguity yet. I just got this working. I don't think core.logic DCGs will compete with a crafted parser anytime soon. it is an interested way to measure performance of core.logic on non-trivial programs tho, as well as give insight as to what needs improving.

12:23 fliebel: DCG?

12:24 dnolen: fliebel: at the moment just this is just exploration. but yes it would make it easy to build a type checker prototype purely in core.logic.

12:24 Definite Clause Grammar

12:26 Cozey: hello. is there some *warn-on-lazyness*, or other lazyness debugging technique? i have my DB getters executed out of transaction because of this - how would you debug this?

12:28 dnolen: Cozey: few techniques for laziness besides being extra careful, I think if you want to avoid the hassle, wrap your lazy-seqs in doall.

12:28 fliebel: Good old print statements also help :)

12:28 Cozey: mhm did that :-) but still haven't traced the problem

12:28 will be more extra careful :-)

12:29 dnolen: fliebel: unless those print statement are inside the lazy-seq computation.

12:29 cemerick: OK, last call for survey questions.

12:29 Also, any nominations to add to this list of options? https://gist.github.com/bc97ecc5d1c820ce93db

12:31 fliebel: cemerick: Remind me of the current list again?

12:31 hiredman: "how much wood would a woodchuck chuck if a woodchuck would chuck wood?"

12:31 fliebel: hiredman: 42

12:31 cemerick: fliebel: http://cemerick.com/2010/06/07/results-from-the-state-of-clojure-summer-2010-survey/

12:34 amalloy: you don't need to write org.clojure/clojure - plain old "clojure" is fine

12:34 fliebel: amalloy: I thought that only worked if the prefix is equal to the name?

12:35 dnolen: wow DCGs in Prolog are insanely fast ...

12:35 pjstadig: cemerick: how about frequency of releases?

12:35 amalloy: fliebel: clojure and contrib are special-cased

12:35 cemerick: pjstadig: good

12:35 * fliebel hates special cases

12:36 fliebel: cemerick: Environment stuff?

12:36 manutter: cemerick: and along with frequency of releases, dev dependencies

12:36 cemerick: fliebel: ?

12:36 fliebel: Keep it under 3 pages please :P

12:36 cemerick: manutter: "dev dependencies"?

12:36 manutter: as in "I upgraded to 1.3, and clj-foo, on which I depend, now crashes"

12:37 fliebel: cemerick: Well, are people already using 1.3 or jdk 7 and such..

12:38 cemerick: pjstadig: perhaps "Lack of public roadmap"?

12:38 fliebel: dnolen: Any idea why? I bet it's fast predicate dispatch...

12:38 pjstadig: well not just that

12:38 maybe at least bug fix releases

12:39 dnolen: fliebel: no specific ideas no ... where are the papers?!

12:39 pjstadig: cemerick: but roadmap is good too

12:40 fliebel: cemerick: Everything on your list twice. http://xkcd.com/468/

12:40 cemerick: heh, right

12:41 pjstadig: I think I'll use "Frequency/predictability of official releases"

12:41 fliebel: cemerick: I came to that when I was thinking about where people would be using clojure next year.

12:51 cemerick: Holy shit, I think Google just ate the survey I built.

12:55 gfrlog: To the cloud!

12:56 Cran1988: :D

12:57 chouser: cemerick: undo!

12:57 pao: is it safe to use clojure-contrib 1.2 with clojure 1.3.0-alpha8?

12:58 cemerick: chouser: no dice: the form builder was never saving anything, and clicking the save button seems to be a no op (aside from the mocking yellow "Saving…" label that shows up at the top of the page).

12:59 chouser: :-(

13:17 dnolen: fliebel: hmm ... I wonder if miniKanren's fair scheduling isn't the problem here. DCGs form very long chains of computations ... I've been thinking about making the search strategy configurable, bringing back depth first.

13:23 hmmm ... ISearchStrategy protocol ...

13:25 amalloy: i'm getting this weird behavior from clojure.test, and i can't find a minimal test-case to reproduce it. https://gist.github.com/1027587 is a gist showing some test cases i have, in which (every? #{1} (a function that returns '(1 1))) fails, as a test

13:25 but (every? #{1}

13:26 '(1 1)) passes

13:26 gfrlog: &(class '(1 1))

13:26 sexpbot: ⟹ clojure.lang.PersistentList

13:26 gfrlog: amalloy: your function returns a c.l.PL?

13:27 raek: amalloy: what are the classes of the numbers?

13:27 amalloy: gfrlog: no, it in fact returns a lazy-seq (which is mentioned in the gist)

13:27 raek: oh man. i bet that's it

13:27 gfrlog: oh I should go read TFG I guess

13:27 s/read TFG/RTFG

13:27 sexpbot: <gfrlog> oh I should go RTFG I guess

13:27 raek: ,(every? #{1} [(int 1) (short 1)])

13:27 clojurebot: false

13:28 gfrlog: ,(every? #(= % 1) [(int 1) (short 1)])

13:28 clojurebot: true

13:29 amalloy: raek: do you think i should map the input sequence to int, or use = instead of #{1} to test? neither seems very clear

13:29 raek: well, = has the right semantics

13:29 gfrlog: ,(hash-map (int 1) :foo (short 1) :bar)

13:29 clojurebot: {1 :foo, 1 :bar}

13:30 raek: amalloy: so I vote for =

13:31 fliebel: dnolen: Hm, sounds like an idea.

13:31 raek: ,(every? (partial = 1) [(int 1) (short 1)])

13:31 clojurebot: true

13:31 gfrlog: ,(map #(identical? % 1) [(int 1) (short 1)])

13:31 clojurebot: (true false)

13:31 gfrlog: that can't be what #{} is doing though...

13:32 amalloy: gfrlog: it's hashing them

13:32 &(map hash ((juxt int short) 1))

13:32 sexpbot: ⟹ (1 1)

13:32 amalloy: hm

13:32 raek: I suspect set-as-function uses .equals

13:32 amalloy: &(map (comp class hash) ((juxt int short) 1))

13:32 sexpbot: ⟹ (java.lang.Integer java.lang.Integer)

13:32 gfrlog: ,(identical? (hash (int 1)) (hash (short 1)))

13:32 clojurebot: true

13:32 raek: ,(.equals (int 1) (short 1))

13:32 clojurebot: false

13:33 hiredman: on 1.2 it definitely does

13:35 raek: the uniformly boxed numbers of 1.3 sounds like a good idea

13:35 dnolen: fliebel: yeah I think interleaving is great for constraints, that's why zebra is so fast. but perhaps not so much for DCGs. For example DCG for checking whitespace is 100X on input string of 1e4 vs 1e3, this is because mk starts producing answers right away where Prolog would immediately search for the longest contiguous whitespace.

13:36 might be wrong of course, need to look into it more.

13:39 cemerick: The 2011 State of Clojure survey is open: http://cemerick.com/2011/06/15/the-2011-state-of-clojure-survey-is-open/

13:40 Raynes: that one's for you, buddy :-)

13:42 hiredman: "Matadata"?

13:42 cemerick: crap :-P

13:43 such things happen after google docs fails you and you have to type things in *twice*

13:43 fixed

13:44 amalloy: cemerick: putting eclipse first on the list, you sly dog

13:44 cemerick: amalloy: it's alphabetized, except for "Command-line REPL" :-P

13:44 amalloy: *chuckle*

13:45 cemerick: Go fork emacs and call it AAEmacs.

13:45 gfrlog: why is "immutability" not on the wins list

13:45 amalloy: aquamacs already had that idea

13:46 cemerick: amalloy: good point

13:46 Aquamacs, the yellow pages strategy for emacs marketing

13:47 technomancy: Aquamacs: a tricycle bolted to the side of a humvee.

13:47 cemerick: gfrlog: gratuitous error on my part. #844, actually. Fixed now.

13:47 And yet, as hard as I might've pushed on those pedals…

13:47 dnolen: technomancy: and sadly the only way to work Mozart/OZ on OS X that's sane.

13:47 technomancy: dnolen: eep

13:48 chouser: Aquamacs: arcane development environment, now with a pretty Mac skin!

13:48 and just to be fair... gvim: arcane fixed-width text editor, now pretending to have a gui!

13:49 gfrlog: cemerick: does that mean I'm going to have to refresh the page and click all the checkboxes all over again? you don't know what that's like!

13:49 hiredman: gnu emacs is so pretty on my mac

13:50 emacs 24 with the nextstep fullscreen patch, delicious

13:52 cemerick: anyway, if someone could post that link on HN, proggit, et al., that'd be nifty

13:55 fliebel: cemerick: there you go http://news.ycombinator.com/item?id=2658246

14:01 Raynes: cemerick: Yay!

14:03 Nothing I enjoy more than filling out surveys

14:40 bdesham: is there any difference between (apply conj ...) and (into ...)?

14:41 specifically, I don't see any difference if you're dealing with maps

14:41 amalloy: into will use a transient, which will be faster

14:41 bdesham: ok

14:42 amalloy: i mean, if you look at the source of into, it's just creating a transient, then using reduce conj, then making the thing persistent again

14:43 bdesham: right

14:59 Dranik: hi all!

15:02 bdesham: hi Dranik

15:09 gfrlog: &(clojure.string/blank? ",")

15:09 sexpbot: ⟹ false

15:09 gfrlog: ah HA

15:10 sorry that was a terrible joke

15:33 mattmitchell: this is more of an emacs/paredit question but figured someone here would know... I want to turn ({:one 1}) into (:one 1) how do i do that with paredit?

15:34 raek: mattmitchell: press M-s within the curly braces

15:35 mattmitchell: raek: awesome thanks

15:35 amalloy: mattmitchell, raek: i do it by pressing M-<UP> with point before the :

15:36 i didn't even know about M-s. handy

15:38 Scriptor: mattmitchell: just found this: http://www.emacswiki.org/emacs/PareditCheatsheet

15:38 looks useful

15:39 mattmitchell: Scriptor: nice, very helpful. thanks.

15:40 halfprogrammer: I dint know it either. Thanks for the tip

15:40 lawfulfalafel: I have been trying to setup emacs for writing clojure, and at the bottom (the mode I believe) it says "Clojure Hi Paredit Fill". Is my emacs correctly setup?

15:41 amalloy: lawfulfalafel: those modes all sound fine to me

15:42 i don't use Hi, and usually not Fill either, but they're fine; and Clojure and Paredit are the key modes

15:42 halfprogrammer: lawfulfalafel: I also have installed autocomplete.el. It's real handy

15:42 amalloy: agreed

15:42 my modeline is Clojure AC Paredit Slime Abbrev

15:43 but AC is really just a gui layer over M-/ -- it's not really necessary

15:44 Scriptor: the shortcut to starting up slime and swank in one go is M-x clojure-jack-in, right?

15:45 raek: Scriptor: yes. (assuming you have a recent version of clojure-mode)

15:46 Scriptor: argh, getting 'exited abnormally with code 1'

15:46 hiredman: you are missing swank-clojure most likely

15:46 halfprogrammer: amalloy: I still like the gui it provides

15:47 Scriptor: I'm pretty sure I have swank-clojure, I can set up a repl by just using lein swank and M-x slime separeately

15:47 *separately

15:48 raek: Scriptor: M-x slime or M-x slime-connect?

15:48 vijaykiran: Scriptor: I think I saw this error when there's version conflict for swank-clojure

15:48 Scriptor: raek: M-x slime-connect

15:48 ah

15:49 raek: Scriptor: also, what version of swank-clojure? I think you need a recent one

15:49 Scriptor: looks like I have 1.3.1

15:49 (for swank-clojure)

15:50 raek: easisest way is probably to remove it from the project.clj (if it's there) and remove any old version from ~/.lein/plugins/ and then do "lein plugin install swank-clojure 1.3.1"

15:50 lawfulfalafel: halfprogrammer: okay, I installed autocomplete through the emacs-starter kit, but what do I have to add to my .emacs to use it?

15:50 I tried googling it, but none of the tutorials mention it, so I don't know if that's actually important

15:50 halfprogrammer_: ah..this flakey internet

15:50 s/internet/wifi

15:50 sexpbot: <halfprogrammer_> ah..this flakey wifi

15:51 vijaykiran: Scriptor: as raek says - I think you should remove it from dev-deps

15:51 halfprogrammer_: (add-to-list 'load-path "~/.emacs.d/plugins/auto-complete")

15:51 Scriptor: raek, vijaykiran: thanks

15:51 vijaykiran: Scriptor: see the "Update" here: http://technomancy.us/149

15:51 amalloy: halfprogrammer_: i do too, which is why i use it

15:52 halfprogrammer_: lawfulfalafel: add (add-to-list 'load-path "~/.emacs.d/plugins/auto-complete") to your .emacs file

15:53 jao: hmm. so priority-map is not in clojure-contrib 1.2, and i cannot find it elsewhere. am i missing something?

15:54 dnolen: jao: mark engelberg hasn't requested to move it into's it's own repo. Should probably post something about that on the ML.

15:54 jao: dnolen, i see. thanks. so my best bet is to get the source code, i guess.

15:55 dnolen: jao: I think it's important to express interest. priority map seems to be used quite a lot.

15:55 * halfprogrammer_ just remembers that he forgot to see today's lunar eclipse

15:56 lawfulfalafel: halfprogrammer_:thank you, that's an awesome utility

15:56 halfprogrammer_: auto-complete.el FTW!

15:56 jao: dnolen, fair enough.

15:56 lawfulfalafel: just out of curiosity, how do you guys learn about this sort of stuff?

15:56 Scriptor: lawfulfalafel: what stuff?

15:57 lawfulfalafel: useful emacs utilities

15:57 amalloy: lawfulfalafel: you learn a lot hanging out in #clojure and #emacs

15:57 lawfulfalafel: but not websites?

15:58 mrBliss: lawfulfalafel: http://www.emacswiki.org/

15:58 amalloy: uhh...how do i answer that question? "yes, sometimes i view websites?"

15:58 lawfulfalafel: well no, I mean you know, a "planet emacs" congregation of emacs blogs or something

15:58 I mean I am used to seeing it for languages, but I'm ignorant of anything like that for emacs

15:59 maybe I just have weird expectations

16:00 mrBliss: lawfulfalafel: there's a planet.emacsen.org (p.s. you have heard of 'The Google' right? ;-)

16:00 halfprogrammer: lawfulfalafel: Guess wat, there is even a nice SO question reg that

16:00 http://stackoverflow.com/questions/271924/what-is-your-favourite-plugin-in-emacs

16:02 lawfulfalafel: thank you, those links are awesome

16:05 Scriptor: where does lein store the plugins on windows, anywhere other than the project's directory?

16:07 mrBliss: Scriptor: %APPDATA%\.lein\

16:08 halfprogrammer: going to crash for the night. see you guys in the morning!

16:11 amalloy: technomancy: i've noticed that the slime repl doesn't indent things nearly as well as the clojure-mode buffers. is there an easy way to make that happen?

16:13 mrBliss: amalloy: does (setq lisp-indent-function 'clojure-indent-function) help?

16:13 amalloy: mrBliss: no difference

16:14 mrBliss: amalloy: and (set-syntax-table clojure-mode-syntax-table)

16:14 amalloy: ah, that does it. i wondered if setting the syntax table would be enough

16:15 mrBliss: thanks, i'll find someplace to add that to my slime hook

16:29 mattmitchell: anyone every see slime/swank freak out like this? https://gist.github.com/1028011

16:31 raek: mattmitchell: M-x customize-variable <RET> slime-net-coding-system --> utf-8-unix

16:31 then reconnect slime

16:35 mattmitchell: raek: awesome thanks! would've never figured that out.

16:35 Raynes: raek is the king of all things unicode.

16:35 raek: technomancy: do you think it's possible to make clojure-jack-in rebind slime-net-coding-system?

16:36 Raynes: my native language is not English; I have to

16:36 technomancy: raek: seems reasonable. should it ever be set to a value other than utf-8-unix?

16:36 Raynes: So, clojure-jack-in automatically assumes the user has leiningen? Is this configurable?

16:36 raek: technomancy: IMHO, no

16:37 amalloy: speaking of which, raek, wasn't ☃.com a link to a cute little snowman? now it looks like a dns squatter

16:37 raek: amalloy: no, that was http://☃.net/ ;-)

16:37 technomancy: Raynes: yes, it's a defvar

16:37 Raynes: Cool!

16:38 raek: Raynes: https://github.com/technomancy/clojure-mode/blob/master/clojure-mode.el#L833

16:38 amalloy: best thing ever

16:38 technomancy: raek: all I know is that sometimes macosecks does crazy things with macroman

16:38 Raynes: I might actually use slime ever now and then now.

16:38 technomancy: *mac-roman

16:38 Raynes: I usually just fire up a cake repl when I need it.

16:38 technomancy: macroman sounds like a superhero

16:39 offby1: the macroman movie is coming out this summer from Sony

16:39 raek: technomancy: some time ago I think swank-clojure changed its default encoding (I don't have to set it to UTF-8 anymore) is this correct=

16:39 ?

16:39 amalloy: offby1: last i heard someone hacked into that movie tho

16:39 technomancy: raek: ISTR doing that on the clojure side, yes

16:39 offby1: amalloy: I hear the screenplay is unhygienic

16:39 * offby1 smacks himself in the forehead

16:40 offby1: amalloy: of course, I should have said: "The script is unhygienic"

16:40 raek: yeah, I've heard that the JVM on mac osx think mac-roman is the OS default encoding (but mac osx actually uses utf-8, iirc)

16:40 technomancy: I guess the problems with platform-specific encodings like MacRoman manifest with command-line interactions, swank is isolated from that via sockets

16:41 Raynes: it doesn't just magically work with other tools though; you have to port the clojure side of jack-in.

16:41 Scriptor: are there any issues with swank-clojure on windows, regarding clojure-jack-in?

16:41 Raynes: technomancy: I know. I'm about to do that.

16:41 raek: yes, as long as we control both ends, we can set the encoding to whatever we want

16:41 technomancy: raek: cool; will fix it in clo-mo then

16:41 thanks for the heads-up

16:42 raek: os default encoding is only useful as a default for terminals and text files created locally

16:42 but is kinda build on the assumtion that text isn't transferred between computers :/

16:44 technomancy: that would be marvellous! that would make any character simply work out of the box. (now you have to config the emacs end manually, if you even know you can)

17:00 jcromartie: What's the best way to "concat" a vector?

17:00 Or... I have a structure that ends up doing lots of concatenation while "building up" the final structure (using reduce)

17:00 * fliebel awaits answer curiously

17:01 jcromartie: and I am finding that certain cases result in a stack overflow due to all of the pending lazy concats on certain values...

17:01 fliebel: jcromartie: As far as I know the answer is "don't do that", lists are more efficient with that.

17:01 or... hm

17:01 jcromartie: because I have dual needs

17:01 I need to do lots of concatenation

17:01 and I need to access it with nth

17:02 gfrlog: finger trees?

17:02 I have no idea if they concat well :/

17:02 jcromartie: line 57 here is the source of all of the concats https://gist.github.com/1023496

17:02 fliebel: yah, they are awesome for everything...

17:02 gfrlog: I propose renaming finger trees "chouser-trees"

17:03 jcromartie: (reduce train-trigrams (make-brain) (.split (slurp "/path/to/stuff.txt") "\n"))

17:03 amalloy: finger trees concat quickly, yes

17:04 gfrlog: and they also nth well?

17:04 raek: jcromartie: one way is to call doall on the intermediate results

17:04 jcromartie: good idea raek

17:04 gfrlog: why not just call vec?

17:04 jcromartie: the longest one is 3702... pretty much all one concat at a time

17:04 raek: jcromartie: then when you evaluate the first element of the resulting seq it won't trigger a cascade of forcings

17:05 jcromartie: 3702 concats

17:05 all deferred

17:05 gfrlog: ,(class (concat [] []))

17:05 clojurebot: clojure.lang.LazySeq

17:05 raek: jcromartie: using (into intermediary-vector some-elements) is another alternative

17:05 hiredman: depending on the content of your lists you could also emit [(1 2) [(3 4) (5 6)]] and then write a lazy-seq function to flatten into a single seq in a single pass

17:06 raek: interesting

17:06 jcromartie: yeah the order doesn't really matter until I'm "done" with it

17:07 to make it ready for reading

17:07 gfrlog: the order doesn't matter but you need nth?

17:07 jcromartie: yes :)

17:07 the order doesn't matter when adding

17:07 hiredman: sort of like erlang io lists

17:07 jcromartie: but I use rand-nth to select items at random

17:07 basically it's just a "bag" that I randomly pick out of

17:07 gfrlog: ah hah

17:08 lawfulfalafel: I am getting a weird bug with this code: http://pastebin.com/JMne4AAm

17:08 java.lang.Exception: Unable to resolve symbol: lst in this context (euler.clj:5)

17:08 jcromartie: instead of counting the occurrences

17:08 gfrlog: lawfulfalafel: don't reinvent the wheel! just use clojure.contrib.fib

17:09 lawfulfalafel: gfrlog: I would, but I would rather learn how to implement it myself for the euler problems

17:09 gfrlog: :) btw, (- limit 1) is (dec limit)

17:09 but that's probably not why it's failing

17:10 lawfulfalafel: ah I see

17:11 raek: lawfulfalafel: you are missing pares around the argument vectors and function bodies

17:11 gfrlog: ^

17:11 fliebel: Hm looking at the survey, I can;t remember when #clojure had 6 people, but I remember when the chunked seq stuff was new. How long ago would that be?

17:11 raek: lawfulfalafel: (defn f ([x] ...) ([x y] ...))

17:11 lawfulfalafel: ah, thank you

17:11 hiredman: pre 1.2

17:12 * hiredman remembers rich explaining a shiny new reference type called "atoms"

17:12 fliebel: hiredman: So, how many years?

17:12 jcromartie: ah!

17:12 hiredman: fliebel: check the git lot

17:12 gfrlog: fliebel: I think maybe 2

17:12 jcromartie: (merge-with into ...) was the answer

17:13 good performance all around now

17:13 love merge-with

17:13 in fact, amazingly fast compared to before

17:13 on both ends... building the index and producing text

17:22 fliebel: jcromartie: What are you making?

17:26 * fliebel submitted survey

17:33 lawfulfalafel: can someone help me understand conj?

17:33 user=> (conj 3 '(1 2)) gives me "java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IPersistentCollection (NO_SOURCE_FILE:0)"

17:34 amalloy: order is wrong

17:34 dnolen: lawfulfalafel: conj takes collection as first arg

17:34 amalloy: &(conj '(1 2) 3)

17:34 sexpbot: ⟹ (3 1 2)

17:34 brehaut: ,(conj '(1 2) 3)

17:34 clojurebot: (3 1 2)

17:34 dnolen: ,(doc conj)

17:34 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

17:34 lawfulfalafel: how do you add to the back of a list? do I have to add a call to reverse?

17:34 jcromartie: fliebel: deterministic Markov-chain-based test data generation

17:34 dnolen: lawfulfalafel: only vectors add efficiently at the back.

17:35 amalloy: lawfulfalafel: don't add to the end of a list; it's slow for immutable lists

17:35 jcromartie: fliebel: take your real data, and turn it into real-looking gibberish

17:36 "McEnroy Timerinession Pipervices, Inc." "Linklen and Muse, Weaguels" "Radicinds, LLC."

17:36 lawfulfalafel: http://stackoverflow.com/questions/1147975/in-clojure-when-should-i-use-a-vector-over-a-list-and-the-other-way-around

17:36 jcromartie: (company names)

17:36 lawfulfalafel: that's what made me think that I should use a list, since I only want to append

17:36 amalloy: aww, so cute to find questions Raynes asked two years ago

17:37 lawfulfalafel: the accepted answer is bad

17:37 fliebel: jcromartie: Have you seen that post about this on HN? Wait, I'll check my history

17:37 amalloy: arguably all the answers are bad

17:37 but the one Raynes posted himself, quoting rhickey, is true

17:38 lawfulfalafel: amalloy: really? I always thought so was pretty objective

17:38 Raynes: amalloy: I generally accepted my own answer as correct, but I didn't want to select my own answer for obvious reasons.

17:38 amalloy: lawfulfalafel: yes, it is objective

17:38 that doesn't make it correct?

17:39 lawfulfalafel: just assumed a meritocracy would push the right answers to the top

17:39 jcromartie: fliebel: hm, not sure

17:39 amalloy: lawfulfalafel: it did. Raynes's answer has more votes than the accepted answer

17:39 but accepted answers are always first

17:39 fliebel: jcromartie: http://www.cs.bell-labs.com/cm/cs/pearls/sec153.html

17:40 lawfulfalafel: lol, I didn't think of that

17:40 jcromartie: ah yes, fliebel

17:40 that's what spurred the whole thing :)

17:40 I started playing with Markov chains

17:40 Raynes: amalloy: I went ahead and accepted my own answer just now.

17:40 jcromartie: then I thought... how about using this for test data?

17:40 which we need

17:40 Raynes: Chris isn't going to notice, with his 44k reputation.

17:40 amalloy: Raynes: yeah, when the accepted answer is blatantly wrong i approve of that choice

17:40 it would have been right in java

17:41 jcromartie: and then I thought: I can use a hash of a value from the training set to seed the PRNG so that the same inputs create the same outputs

17:41 anyway

17:41 fun stuff

17:41 Markov hash functions :)

17:41 fliebel: jcromartie: I love them, I did rock-paper-scissor with a markov chain.

17:42 jcromartie: so far it's been a great learning endeavor

17:42 hopefully it pays off in usefulness

17:43 lawfulfalafel: okay, I am trying to change a list '(1 2) to this '[1 2], but paredit is making it really hard for me to figure out how

17:44 I'm looking at this and don't get which command I should use: http://www.emacswiki.org/emacs/PareditCheatsheet

17:44 amalloy: lawfulfalafel: if you find it, let me know; my method of doing this is pretty bad

17:45 chouser: %r]^Or[

17:45 fliebel: chouser: Do you have a cat?

17:45 Raynes: I'd just do M-s inside of the brackets to get rid of them and then create new brackets after the ' and before the one and then C-rightarrow to slurp up the two numbers.

17:45 chouser: that's good old-fashioned vim

17:45 Raynes: Which is equally awful.

17:46 amalloy: Raynes: i have a way more efficient version: wrap in brackets *first*, slurping only once, and then splice :P

17:46 Raynes: Hehe

17:47 raek: lawfulfalafel: if you select a piece of text and the press [ it will be wrapped in [ and ]

17:48 fliebel: chouser: Doesn't work for me. Can you explain what it should do?

17:49 amalloy: raek: i guess i knew that, but i never use it. definitely more convenient than what i'm currently doing

17:49 chouser: start on the left paren, % to bounce to the matching right paren, r] to replace it with bracket Ctrl-O to go to previous cursor position (the open paren) then r[ to fix that one.

17:50 fliebel: chouser: Ah! I was pressing ^ (start of line) and then O (insert above)

17:50 chouser: yeah, that probably should have been <C-O> or something

17:50 amalloy: chouser: i don't use vim and ^O was fairly clear to me

17:51 but i guess you could have meant ^ then O

17:58 lawfulfalafel: amalloy: you probably know this, but M-s within a parens removes them

17:58 amalloy: yes, raek said that earlier today

17:58 lawfulfalafel: lol

17:59 I just came back from googling this forever

17:59 Raynes: thanks

17:59 hiredman: M-r is also good

18:04 TimMc: M-x paredit-paren-to-square :-P

18:04 amalloy: TimMc: you are a cruel tease

18:05 TimMc: or CM^☃

18:05 err... C-M-☃

18:07 amalloy: i love the :let/:when feature in `for`

18:12 lawfulfalafel: my solution to a euler problem is really slow: http://pastebin.com/mpSrPcV8

18:13 supposed to be working with the first 4000000 fib numbers, and it's been running for a few minutes now

18:13 I think it's slow because I am misusing vectors, but not sure

18:15 the-kenny: lawfulfalafel: How costly is reverse?

18:15 you do it two times, on the same list.

18:16 (let [[item1 item2 & _] (reverse lst)]) should perform better (not sure if the syntax is correct, though

18:16 lawfulfalafel: wait, I misread the euler question

18:17 it's of all fib numbers below 4000000, not the first 4000000 fib numbers

18:17 my mistake

18:22 amalloy: lawfulfalafel: yeah, calling reverse like that is kinda crazy anyway

18:23 if you wanted something that uses the same algorithm, you could do like (let [[item2 item1] (take-last 2 lst)])

18:24 (of course, item1 item2 is an ordering that makes more sense, but this preserves identical bindings to your version)

18:24 &(let [lst (range 10), [a b] (take-last 2 lst)] {:a a :b b})

18:24 sexpbot: ⟹ {:a 8, :b 9}

18:27 gfrlog: (defmacro make-with-keys [& ks] `(hash-map ~@(interleave (map keyword ks) ks)))

18:30 amalloy: i don't really like that implementation. keywordize in amalloy-utils looks like (into {} (map (juxt keyword identity) ks))) iirc

18:30 hiredman: amalloy: can't be that

18:31 amalloy: hiredman: just checked, at https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils.clj#L30, and it is. why do you think it isn't?

18:31 it's still a macro, of course

18:31 hiredman: because juxt doesn't work like that

18:31 oh

18:32 amalloy: &(let [ks '(a b)] (into {} (map (juxt keyword identity) ks)))

18:32 sexpbot: ⟹ {:a a, :b b}

18:32 hiredman: I thought "keywordize" meant take an existing map and turn the keys into keywords

18:32 amalloy: hiredman: no, i named my function before i heard about keywordize-keys in contrib

18:32 hiredman: amalloy: you do know I've had sexpbot on ignore for almost a year now?

18:32 amalloy: hiredman: yeah, i forget :P

18:34 gfrlog: amalloy: does sexpbot have hiredman on ignore?

18:35 amalloy: no, but he does ignore s/foo/bar when coming from hiredman

18:40 lawfulfalafel: how do you efficiently remove the last element of a vector list?

18:40 technomancy: I think dissoc will do it

18:41 raek: lawfulfalafel: of a vector? pop. of a list or seq? no efficient way.

18:41 ,(pop [1 2 3])

18:41 clojurebot: [1 2]

18:44 lawfulfalafel: raek: thanks, pop is what I was looking for

18:44 gfrlog: ,(fn? [])

18:44 clojurebot: false

18:44 raek: ,(ifn? [])

18:44 clojurebot: true

18:44 gfrlog: interesting

18:45 raek: implementation vs interface, same thing with list? and seq?

18:47 lawfulfalafel: okay, I have rewritten my euler code, but it's still generating the wrong number (here's the code: http://pastebin.com/i1WDpcqd)

18:48 hiredman: lawfulfalafel: off by one error

18:50 amalloy: &(doc rseq)

18:50 sexpbot: ⟹ "([rev]); Returns, in constant time, a seq of the items in rev (which can be a vector or sorted-map), in reverse order. If rev is empty returns nil"

18:50 amalloy: &(rseq '(1 2))

18:50 sexpbot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Reversible

18:50 amalloy: hm. that's the behavior i expected, but i'm sure i've seen it behave differently before

18:51 raek: amalloy: you're not thinking about 'reverse'?

18:51 amalloy: raek: *chuckle* no, i know about reverse

18:52 but someone solved the 4clojure "reverse a sequence" problem by using rseq, and it surprised me by working

18:52 but looking at it now, i see we only use vectors and a sorted-set

18:52 raek: sounds unlikely that it would have worked for seqs

18:53 lawfulfalafel: hiredman: it's off by one?

18:53 raek: vectors and sorted-sets know how to traverse their internal structure in the reverse order

18:53 lawfulfalafel: I keep testing it with low numbers and it's behaving expectantly

18:53 amalloy: i checked, at the time, that there was a list; but we use the list as what to check answers against, not what to call the function with: http://4clojure.com/problem/23

18:54 so that solves that little mystery for me :P

18:54 hiredman: lawfulfalafel: that would be my guess, I would check the start of the sequence of numbers you are generating against the actually sequence, perhaps on the wikipedia article

18:55 gfrlog: hiredman: the euler problem specifies the start of the sequence and he's doing it right

18:56 hiredman: gfrlog: could be, but his code says 'fib' and the start of his sequence doesn't match the start of fib

18:57 lawfulfalafel: well only even numbers matter, so I don't think cutting off the 0,1 at the very beginning matter

18:57 but that's my assumption, probly wrong

19:00 gfrlog: lawfulfalafel: I've done this problem before and my answer agrees with what your code gets (4613732)

19:00 I think you're wrong about getting it wrong

19:01 lawfulfalafel: gfrlog: lol, yep you're right. I was screwing up the confirmation code.

19:01 sorry about wasting people's time with that

19:01 gfrlog: :)

19:02 amalloy: &(reduce + (filter even? (take-while #(< % 4e6) (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))))

19:02 sexpbot: ⟹ 4613732

19:02 technomancy: raek: pushed clojure-mode fix

19:02 not sure when it'll make it to a release though

19:03 lawfulfalafel: amalloy: that's a crazy awesome one-liner

19:04 gfrlog: amalloy: where's the juxt?

19:05 amalloy: lawfulfalafel: using lazy sequences instead of vectors will make your life easier most of the time

19:05 i mean, yes, vectors are great when you want them

19:05 but for generating lists, you usually don't

19:06 gfrlog: lawfulfalafel: re your apology, every good mystery has a plot twist at the end

19:15 aaelony: hi, what is the best way to write a large data structure to a file?

19:15 gfrlog: too large for (spit "filename" (pr-str data-structure))?

19:16 aaelony: probably too large for spit. Is clojure.java.io/make-output-stream a good choice ?

19:18 mattmitchell: how do you convert a hash-map to a vector or list?

19:18 raek: gfrlog: would (with-open [out (io/reader "filename")] (binding [*out* out] (pr data-structure))) be better?

19:18 then you skip the intermediate giant string

19:18 gfrlog: raek: that's the sort of thing I was thinking. Nothing mixes me up like the java IO stuff though, so it usually takes me 4 guesses

19:19 amalloy: mattmitchell: seq

19:19 &(seq {1 2})

19:19 sexpbot: ⟹ ([1 2])

19:19 raek: mattmitchell: what should the result look like, for example for the map {:a 1, :b 2}?

19:19 gfrlog: maybe ##(seq {1 2 3 4 5 7}) is slightly clearer

19:19 sexpbot: ⟹ ([1 2] [3 4] [5 7])

19:20 amalloy: gfrlog: yeah

19:20 raek: gfrlog: er. I meant writer of course... :)

19:20 gfrlog: yeah :)

19:20 zakwilson: I have some code that uses ClojureQL and it seems that the results of function calls are NOT being treated the same as using the values they return in their place. I'm probably doing something dumb here, but I'd really appreciate a second pair of eyes on this: http://pastebin.com/VMUxH9Pq

19:20 gfrlog: amalloy: ##((comp first (juxt seq)) {1 2 3 4})

19:20 sexpbot: ⟹ ([1 2] [3 4])

19:20 gfrlog: that way is clearly superior

19:21 aaelony: raek and gfrlog: thanks. also open to hearing how others deal with large outputs. (even if this is antithetical to "no side-effects" I imagine)

19:22 gfrlog: zakwilson: what the heck is going on here?

19:24 raek: technomancy: ok, I've tested it now. works perfectly!

19:25 gfrlog: zakwilson: do you have a simpler example of what you're wondering about?

19:27 zakwilson: gfrlog: no, I'm afraid not. I might be able to devise one, but I don't understand what's going wrong here at all.

19:28 gfrlog: your (items-by-cat 3) example is not supposed to throw an exception?

19:28 zakwilson: Correct

19:28 tremolo: zakwilson: it sounded like you had traced it to a line where a function didn't return what you expected. Can you elaborate on that a bit more, and maybe tell us which line it happened on?

19:29 zakwilson: tremolo: No, the function *does* return what is expected. When I substitute that value in to the copy-pasted body of items-by-cat, it works. When I call items-by-cat, it does not work.

19:30 (by "does not work" I mean it throws the exception mentioned in the past)

19:30 e

19:30 gfrlog: zakwilson: I wouldn't think this would be an issue, but one difference is that cat-and-subs will return a lazy-seq

19:30 tremolo: zakwilson: ah, ok. got it.

19:30 gfrlog: so maybe try, in your final test code, replacing [3 5] with (concat '() [3 5]) or something like that?

19:31 just to see if that makes it break

19:31 zakwilson: Well, wrapping cat-and-subs with doall didn't change the result.

19:31 However, using (concat '() [3 5]) *does* break it.

19:31 gfrlog: the clojureql doc specifically says "vector"

19:32 so try wrapping cat-and-subs with (vec)

19:32 hiredman: possibly does something disgusting like calls pr-str

19:32 zakwilson: Yep, that worked. Thanks.

19:32 hiredman: doall doesn't change how lazy-seqs are printed

19:32 gfrlog: no prob

19:33 zakwilson: This violates my expectation that Clojure collection types can be used in place of each other.

19:34 hiredman: err

19:34 amalloy: zakwilson: that's not a good expectation to have, really. they compare as equal, but that's about it?

19:34 hiredman: not pr-str

19:34 gfrlog: yeah I'm not sure why clojureql chose to do that

19:34 hiredman: pr-str would be more correct

19:34 the string problem would be if clojureql calls str or toString

19:35 zakwilson: Evidently it is not a reasonable expectation. I will assume there's a good reason I do not understand.

19:35 gfrlog: zakwilson: at the very least I think it's unusual

19:35 I didn't expect it either

19:35 hiredman: source has calls to str everywhere :/

19:36 gfrlog: hiredman: the function takes either a vector or varargs, so it probably just tests with (vec?)

19:36 amalloy: zakwilson: well, for example ##(for [coll [[1 2 3] '(1 2 3)]] (conj coll 4))

19:36 &(for [coll [[1 2 3] '(1 2 3)]]] (conj coll 4))

19:36 zakwilson: At least, I would expect a vector, list and lazy seq to be interchangable in places where the lazyness didn't matter.

19:36 hiredman: gfrlog: could be

19:37 amalloy: wow what am i doing so whrong there

19:37 &(conj [1 2 3] 4)

19:37 Raynes: sexpbot is dead?

19:37 gfrlog: hiredman put everybody on ignoring sexpbot

19:37 Raynes: amalloy: Is he?

19:37 $kill

19:38 amalloy: ,(for [coll [[1 2 3] '(1 2 3)]] (conj coll 4))

19:38 clojurebot: ([1 2 3 4] (4 1 2 3))

19:38 amalloy: zakwilson: another example of a difference

19:38 Raynes: He would if he could.

19:38 zakwilson: Especially considering that the standard sequence manipulation functions return lazy seqs.

19:38 hiredman: gfrlog: if only

19:38 Raynes: Apparently, hiredman really really likes me.

19:39 raek: zakwilson: I think the ClojureQL mini-language assigns special meaning to vectors. in most clojure code vectors and lists work equally well as sequential collection literals

19:39 gfrlog: I've used clojureql a good bit, and I was surprised by it

19:39 amalloy: raek: hiccup treats them differently too. a lot of macros do, really

19:39 hiredman: clojureql hardly seems worth it

19:39 gfrlog: hiredman: what do you use?

19:39 amalloy: though i guess the relevant hiccup layer is mostly not macros

19:39 hiredman: sql

19:40 raek: I know that in the app macro of Moustache, vectors mean special things (as you wouldn't usually put a vector in the place of a ring handler function)

19:40 gfrlog: hiredman: c.c.sql?

19:40 hiredman: gfrlog: some of c.c.sql and some direct jdbc calls

19:40 zakwilson: Hiccup uses vectors is *syntax* though. This is not a place in CQL where it seems like *syntax*; it's a value.

19:40 gfrlog: hiredman: I like the composability of cql

19:41 hiredman: gfrlog: what composability?

19:41 amalloy: zakwilson: yeah, that's a reasonable argument. i'd probably feel the same if i were using cql

19:41 gfrlog: hiredman: like I can have a function that joins some tables and limits some things, and in another namespace I can add furthur restrictions, etc.

19:42 raek: clojureql 'where' looks syntax-y to me, since you can write (and (not (= :super nil)) (= :super cat))

19:42 hiredman: gfrlog: hmmm

19:42 zakwilson: cql feels half-baked right now. I like the idea, but I'm starting to get frustrated with it. I do NOT like writing SQL by string concatination. It's 2011 - WTF are we still doing that?

19:42 gfrlog: it's been useful for me, but there are other times when spitting out some SQL is much faster and easier

19:42 raek: ...which clearly is not evaluated as Clojure code

19:44 tremolo: gfrlog: doesn't that every make query debugging a bit annoying? as in, if the query analyzer tells you that a particular join is slowing things down, how do you locate in your code where the join was "mixed in" from?

19:44 *ever make

19:44 hiredman: sql is the best language for interacting with an sql database

19:45 seancorfield: hiredman: do you have any issues with c.c.sql that you'd like to see fixed?

19:45 tremolo: yea, I see no reason why you'd need anything besides reqular old SQL

19:45 hiredman: I guess after bad experiences with nosql I am bullish on sql

19:46 zakwilson: tremolo: how do you construct your SQL queries within your code?

19:46 hiredman: seancorfield: I think a big one was the inability to get back generated ids which you have already fixed I think

19:46 zakwilson: I like relational databases. I like tools that interact with them relationally. I do not like the SQL language. Not one bit.

19:46 seancorfield: what bad experiences, hiredman ? we're looking to add mongodb at work (in addition to mysql which we're already using)

19:47 hiredman: yeah, clojure.java.jdbc returns generated keys from inserts

19:48 hiredman: seancorfield: no experience with mongo, just a lot of pain doing anything except lookups by primary key

19:48 seancorfield: i'm not finding c.j.j very extensible tho'... i want to expose more places to apply functions, such as allowing manipulation of the PreparedStatement prior to execution etc

19:48 zakwilson: Isn't the standard nosql bad experience trying to use something like a key/value store as a general-purpose queryable database when that's not what it's designed for?

19:48 amalloy: i'm pretty happy with mongo

19:48 hiredman: seancorfield: something like that might be nice

19:49 seancorfield: i think i need to redesign the API a bit to make that easier... or at least provide a new, cleaner API

19:49 amalloy: it's the most sql-like of the nosql languages, and (hiredman) you can have indexes that are basically the same as in sql

19:49 hiredman: zakwilson: I think that was a large part of it, but you'd expect at least expect something decent for dealing with secondary indices

19:49 seancorfield: amalloy:

19:49 oops

19:50 amalloy: yeah, i got the impression that adding indices was easy and (only) needed for performance

19:50 zakwilson: hiredman: I suppose, yes. Was this an application where a relational DB was the obvious Right Thing and somebody wanted to use something trendy instead?

19:50 amalloy: yes, it's trivial

19:54 hiredman: zakwilson: there was something of a push to store things in the nosql db due to concerns of scale and availability

19:54 with no analysis of access patterns

19:57 aaelony: hi, when outputing to a file everything is going to one line in the resulting file. This is despite (interpose "\n" data) ... The resulting file contains "\n" literals where the new lines should occur... all on one line...!

19:57 any way to make this an actual new line indicator?

19:58 I am using prn

19:58 zakwilson: Ahh. I figure that if my project gets to where it needs that sort of scaling, its data storage layer will have to be redesigned *no matter what*, so I'm using cql/postgres because it seems like it offers the best ways to represent and query the data. I'm starting to get a little iffy on cql though because I keep finding quirks.

20:00 seancorfield: ,(doc prn)

20:00 clojurebot: "([& more]); Same as pr followed by (newline). Observes *flush-on-newline*"

20:01 aaelony: i am already using prn

20:01 despite the docs claim, I get all one line

20:01 with "\n" literals

20:01 seancorfield: aaelony: it outputs a newline at the end - so call it on each line of data

20:01 aaelony: where the new lines should be

20:02 seancorfield: I could do that. But the "\n" literals are exactly where they need to be, I wish they would just resolve correctly

20:02 sigh...

20:03 seancorfield: if you have (interpose "\n" data) then you want newlines between each item in data, yes?

20:03 * offby1 tells aaelony's wife

20:03 seancorfield: so (doseq [line data] (prn line)) would work?

20:03 aaelony: seancorfield: yes

20:04 this is what I have: delimited-data (map #(interpose delimiter %) (interpose "\n" data))

20:04 seancorfield: what sort of thing is data?

20:05 aaelony: data is a large structure, the result of parsing lots of JSON to delimited columns

20:06 amalloy: aaelony: is data a seq or what

20:06 is his question

20:06 aaelony: sec..

20:07 seancorfield: i guess it's more "what are you _really_ trying to do?" to see if there's a more elegant solution

20:07 aaelony: clojure.lang.LazySeq

20:07 amalloy: aaelony: you don't really want interpose anyway, because it's going to return a seq like [foo "\n" bar]

20:08 use clojure.string/join perhaps?

20:08 ,(clojure.string/join \newline [1 2])

20:08 clojurebot: java.lang.ClassNotFoundException: clojure.string

20:08 aaelony: I'm looking for the best way to place actual new line breaks.

20:09 clojure.string/join \newlie [1 2] looks reasonable, I will try that.

20:09 seancorfield: aaelony: if you invoke prn on each "line" of data, you'll get new line breaks where you want them

20:10 aaelony: seancorfield: is there a way to edit the following to do that?

20:10 delimited-data (map #(interpose delimiter %) (interpose "\n" data))

20:11 seancorfield: it's more about what you're doing with that

20:11 my suggestion was construct a sequence of the things you want on separate lines and then use prn to print each thing on a separate line

20:12 aaelony: yes, that is what I thought I was doing by interposing "\n"

20:12 seancorfield: you're misunderstanding me

20:12 aaelony: please explain

20:12 seancorfield: instead of trying to construct a sequence which mixes delilmiters, data and newlines, just use the plain seq and prn each item in it

20:13 aaelony: how?

20:13 clojurebot: with style and grace

20:13 seancorfield: ,(doseq [line ["I" "am" "your" "data"]] (prn (str "|" line "|")))

20:13 clojurebot: "|I|"

20:13 "|am|"

20:13 "|your|"

20:13 "|data|"

20:13 seancorfield: assuming | was your delimiter

20:14 aaelony: I will try that, thanks!

20:17 that doesn't work... Each record should end with a new line. There are many fields that need to be delimited. No worries, I'll keep digging.

20:20 gfrlog: sometimes clojurebot's interjections seem eerily appropriate...

20:20 hiredman: sometimes?

20:20 amalloy: ,(use '[clojure.string :only [join]])

20:20 clojurebot: nil

20:21 seancorfield: aaelony: if you can structure your data as sequence of records where each record is a sequence of fields, you can manipulate it more easily when printing it

20:21 amalloy: ,(let [data '[[a b c] [1 2 3]]] (print (join \newline (map #(str "|" % "|") data))))

20:21 clojurebot: |[a b c]|

20:21 |[1 2 3]|

20:21 amalloy: oops, guess not

20:22 seancorfield: trying to insert strings and convert the whole thing to a string just to call prn once seems like a lot of work

20:22 amalloy: ,(let [data '[[a b c] [1 2 3]]] (print (join \newline (for [record data] (map #(str "|" % "|") record)))))

20:22 clojurebot: clojure.lang.LazySeq@73d7b35

20:22 clojure.lang.LazySeq@726ef65

20:22 aaelony: amalloy: I think that should do it

20:22 amalloy: rarrrgh

20:23 ,(let [data '[[a b c] [1 2 3]]] (pr-str (join \newline (for [record data] (map #(str "|" % "|") record)))))

20:23 clojurebot: "\"clojure.lang.LazySeq@73d7b35\\nclojure.lang.LazySeq@726ef65\""

20:23 amalloy: i quit

20:23 something like that

20:23 aaelony: i get it... i think that will work. I need to make a few changes..

20:24 will think it through. thanks for the input!!

20:24 cheers

20:37 gfrlog: it is hard to glance at a conversation between "amalloy" and "aaelony" and subconciously assign authorship accurately

20:37 hiredman: gfrlog: they are different colors

20:37 gfrlog: yeah? your client assigns random colors?

20:37 amalloy: gfrlog: hashes of the name

20:37 so that it's "random" but consistent

20:37 gfrlog: right

20:38 a random oracle

20:38 technomancy: hiredman has IRC synesthesia

20:38 hiredman: something like that, with overrides if desired

20:38 amalloy: even my crappy client does that

20:38 i like technomancy's answer better though

20:38 hiredman: technomancy: you smell correct

20:38 gfrlog: then apparently you all underestimate the crappiness of my client

20:38 amalloy: gfrlog: adium?

20:38 gfrlog: centerim

20:38 it's this terminal thing I found somewhere on the internet

20:39 hiredman: oh god

20:39 horrible

20:39 gfrlog: I hate it because it doesn't even distinguish between statements and "has left" events

20:39 technomancy: yeah, I've had join/parts hidden for years now. so much nicer

20:39 gfrlog: but that's how bad I wanted to run it on a headless server

20:39 amalloy: gfrlog: erc

20:39 technomancy: if someone's left, I'll notice because I can't tab-complete them anymore

20:39 amalloy: or wait, you're this vim guy

20:39 gfrlog: :)

20:39 I switched from qwerty to dvorak; I wonder how that compares to switching to emacs

20:40 hiredman: irssi in screen

20:40 or tmux

20:40 gfrlog: hiredman: yeah, I used irssi for a while actually

20:40 amalloy: tmux in screen? madness

20:40 gfrlog: but centerim lets me integrate jabber

20:40 hiredman: I have irssi in screen and sqs for growls, it is great

20:40 gfrlog: amalloy: I've used screen in tmux a few times

20:40 hiredman: there is, infact, a jabber client for irssi

20:40 gfrlog: hiredman: irssi does the coloring?

20:40 technomancy: perl user!

20:40 ~guards

20:40 clojurebot: SEIZE HIM!

20:41 hiredman: http://cybione.org/~irssi-xmpp/

20:41 gfrlog: some plugin

20:41 gfrlog: why does everybody know so many clojurebot triggers?

20:41 hiredman: nickcolor.pl

20:41 amalloy: technomancy: wait, who's the perl user?

20:41 technomancy: amalloy: irissi is extended using perl IIRC

20:41 gfrlog: hiredman: this looks to be an excellent tip

20:42 man the other day I saw sexpbot react to something clojurebot said

20:42 amalloy: clojurebot: source?

20:42 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

20:42 amalloy: gfrlog: feel free to dig through there for a command list?

20:43 gfrlog: :) I knew it was available somewhere, but that still doesn't explain why everybody knows it so well

20:43 technomancy: I really do not understand how people who write IRC clients can consider releasing them with nick highlighting turned off by default.

20:43 it's like ... like not having readline available... oh wait

20:44 amalloy: gfrlog: word of mouth, and also many of these are "standard" bot features. the bot in #emacs responds to ,guards

20:44 gfrlog: ah ha

20:44 amalloy: and just listen around, note cool commands, and then remember them :P

20:44 technomancy: amalloy: well... that was a straight-up thievery

20:44 I don't know if I'd call it standard

20:44 hiredman: technomancy: not true

20:44 amalloy: technomancy: standard...for lisp bots?

20:44 technomancy: hiredman: thievery by yours truly

20:44 hiredman: I'd never been in #emacs

20:45 I chose "," because it is whitespace in clojure

20:45 gfrlog: I always like that

20:45 technomancy: hiredman: I was refering to ,guards

20:45 hiredman: oh

20:45 right

20:45 well, yes, technomancy knows a lot of factoids because he adds them

20:45 technomancy: which I really cannot overstate my amusement over

20:45 ~gentlemen

20:46 gfrlog: ~ladies

20:46 technomancy: hmm; time for some more thievery

20:46 ~gentlemen is <reply>You can't fight in here. This is the war room.

20:46 hiredman: clojurebot: it's a thing is <reply> #who, it really is!

20:46 huh

20:46 gfrlog: I was about to start guessing which files to click on when I remembered I could clone the repo and grep for "seize him"

20:47 hiredman: gfrlog: you cannot, actually, that is learned behavior

20:47 the hell

20:47 gfrlog: well I can do it, but it doesn't help me at all :)

20:48 was amalloy sending me on a goose chase?

20:48 hiredman: ~ping

20:48 clojurebot: PONG!

20:48 technomancy: ~gentlemen

20:48 clojurebot: gentlemen is you can't fight here, this is the war room.

20:48 hiredman: clojurebot: it's a thing is <reply> #who, it really is!

20:48 clojurebot: Roger.

20:48 hiredman: ~it's a thing

20:48 clojurebot: hiredman, it really is!

20:48 technomancy: clojurebot: forget gentlemen |is| you can't fight here, this is the war room.

20:48 clojurebot: I forgot that gentlemen is you can't fight here, this is the war room.

20:49 technomancy: ~gentlemen is <reply> You can't fight in here. This is the war room.

20:49 clojurebot: Roger.

20:49 technomancy: you need a space after <reply>L

20:49 ?

20:49 hiredman: possibly

20:49 amalloy: gfrlog: i probably was sending you on a goose chase, yes

20:49 hiredman: I guess I could look at the parser or something

20:49 gfrlog: this is the craziest thing I have seen today.

20:50 ~goose

20:50 clojurebot: No entiendo

20:50 gfrlog: clojurebot: goose is Not have goose

20:50 clojurebot: Alles klar

20:51 gfrlog: ~goose

20:51 clojurebot: goose is Not have goose

20:51 hiredman: not my jdbc layer 4 driver built on top of the rest api of the agile planning website thing we use at work?

20:51 gfrlog: just got me confuseder

20:52 hiredman: not the delievery of irssi rawlog via sqs? or the interpreter written in shell? the irc bot is the crazy thing?

20:53 technomancy: I'll tell you what's crazy; when I first joined this channel there was no bot.

20:53 could hardly believe it.

20:53 gfrlog: Did I unknowingly witness all those things?

20:53 hiredman: they are on the guthub

20:54 gfrlog: I wasn't reacting to the code, I was reacting to you guyses interaction with the bot

20:54 hiredman: there is a really good sequence

20:54 lemme see

20:54 clojurebot: foo bleh blarg

20:54 clojurebot: amespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

20:54 hiredman: clojurebot: what did you say to me?

20:55 clojurebot: Huh?

20:55 hiredman: clojurebot: you heard me

20:55 clojurebot: hiredman: I'm just giving you a second chance

20:55 hiredman: clojurebot: don't make me come over there

20:55 clojurebot: Huh?

20:55 technomancy: gfrlog: you want crazy on tap, you should hang out with rudybot: https://github.com/offby1/rudybot/blob/master/quotes

20:56 gfrlog: technomancy: Golly Willickers

20:57 technomancy: tee hee "you know you're an opensource geek when someone cuts you off on the freeway and you're like \"PATCHES WELCOME!!!!\""

20:58 hiredman: that is pretty good

21:12 gfrlog_: why do I have such trouble figuring out how to use IRSSI?

21:42 dbgster: is there any examples of simple problems and solutions in clojure?

21:42 things like: given a list of n items, find the largest 2 items in the list and return it

21:43 amalloy: dbgster: you might like 4clojure.com, perhaps? not actually what you asked for, but useful for the same target audience

21:44 (that said, finding the two biggest is not such a simple problem!)

21:44 dbgster: amalloy: are you familiar with koan? i think there was a clojure type version of that

21:44 amalloy: yes, clojure koans exist

21:44 dbgster: in ruby I did it in 7 lines

21:44 amalloy: $google clojure functional koans

21:45 dbgster: k

21:45 ataggart: also this: http://rosettacode.org/wiki/Category:Clojure

21:45 amalloy: ataggart: good point

21:47 dbgster: can someone clear up wht liens does for me?

21:48 it is a project generator and build tool?

21:48 i.e it generates the structure for a project

21:48 and builds and runs it for you?

21:48 it has NOTHING to do with repl correct?

21:49 bdesham: you can do "lein repl" which will run a repl for you

21:52 if I'm distributing a library, should I use "defn-" for anything I don't expect the end user to call? what if I want to run tests against the would-be hidden functions?

21:52 amalloy: dbgster: https://gist.github.com/1028531 for this particular problem

21:53 dbgster: bdesham: and it will do what compared to the normal repl? load my proj?

21:53 amalloy: though i guess my solution isn't very robust

21:54 dbgster: amalloy: http://www.pastie.org/2075362 surprised, thought it would be a 2 liner in clojure for some reason :)

21:55 amalloy: dbgster: run your ruby version on the list [-1 -2 -3] :P

21:56 wow actually your version is wrong in a lot of ways

21:56 try it also on [10 4] - i think it returns [10 0]

21:57 dbgster: ok it works for positve numbers?

21:57 one sec

21:58 hmm..ok

21:59 amalloy: so yes, you can get a very short version provided you're not worried about getting the right answer :)

22:02 and as i said, even my version isn't perfect; it takes the first two numbers of the list and starts them as largest/second. if i used 0 0 i'd be okay for non-negative numbers, but the *right* way is to sort the first two numbers, since the algorithm assumes they're sorted

22:03 bdesham: dbgster: yes, as long as you have :gen-class in your project.clj file

22:03 although I've never quite undersood gen-class, so don't press me for details ;-)

22:04 amalloy: dbgster: updated https://gist.github.com/1028531 with a version that i think works for any seq of integers, if you're interested

22:04 but now, i'm off!

22:40 offby1: technomancy: I resemble that remark ("crazy on tap")

23:03 seancorfield__: is there a cleaner way of converting java's system properties into a clojure map than (into {} (map (juxt #(.getKey %) #(.getValue %)) (System/getProperties))) ?

23:03 ,(into {} (map (juxt #(.getKey %) #(.getValue %)) (System/getProperties)))

23:03 clojurebot: java.security.AccessControlException: access denied (java.util.PropertyPermission * read,write)

23:03 seancorfield__: heh, figured...

23:04 scgilardi: (into {} (System/getProperties)) looks like it works

23:04 seancorfield__: hmm, i thought i'd tried that earlier and got an exception... let me try it again...

23:04 tomoj: key and val also work on seq of properties

23:05 er, java.util.Hashtable$Entry

23:05 seancorfield__: thanx scgilardi - not sure why i thought that didn't work

23:05 scgilardi: you're welcome

23:06 seancorfield__: tomoj: good to know, tx

23:07 tomoj: does Properties not have a Map constructor because people are supposed to just expect Map?

23:10 seancorfield__: Properties extends HashTable and implements Map but i missed that subtlety :)

23:15 what threw me was when i first tried map over properties and got elements that printed as java class references... so i didn't try key/val (which would have worked and saved me some confusion)

23:27 (battery died unexpectedly)

23:36 bdesham: new project, I'd appreciate any comments: clj-schulze, an implementation of the Schulze voting method - https://github.com/bdesham/clj-schulze

Logging service provided by n01se.net