#clojure log - Apr 28 2010

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

0:32 MadWombat: Hello

0:33 Raynes: Hello.

0:35 MadWombat: I have a number of functions generating data and a single function for storing this data. At this point I have something like (def fns ['f1 'f2 'f3]) (doseq [f fns] (store-data ((eval f))))

0:35 this somehow seems ugly and non-idiomatic

0:35 especially ((eval f)) part

0:36 is this "The Clojure Way" or am I not sufficiently enlightened?

0:37 technomancy: MadWombat: what about (def fns [f1 f2 f3]) (doseq [f fns] (store-data (f))) ?

0:38 assuming the f1, f2, f3, etc have been def'd when the function calling store-data is compiled

0:46 MadWombat: technomancy: interesting :) wonder why I started quoting them right away anyway

1:10 vIkSiT: mmarczyk, you mean "back" into a separate duck-streams ns?

1:10 cemerick: vIkSiT: right, (:require [clojure.contrib.io :as io]), and then use io/slurp* and io/spit, etc

1:10 mmarczyk: yes

1:10 but you can just use stuff from io, yes

1:10 cemerick: It's been suggested that it be restored, but deprecated

1:10 mmarczyk: be wary of changes in behaviour though

1:10 vIkSiT: ah I see

1:10 hmm.

1:11 mmarczyk: some of the functions act somewhat differently in addition to having been moved to a different ns

1:11 vIkSiT: i c

1:12 well, it looks like Clojure is to languages what Linux has been to OSs :) Its changing so fast!

1:12 cemerick: the perils of following the bleeding edge :-)

1:12 vIkSiT: (Not to mention that half the books haven't been written yet :P)

1:12 cemerick: vIkSiT: you can see the current state of the API here: http://richhickey.github.com/clojure-contrib/index.html

1:13 That shows where the master branch is, and there's a link at the left to get to the 1.1.x release docs.

1:13 vIkSiT: cemerick, ah, I've been using 1.2.0 Master for a while.. don't think I could go back to 1.1.x

1:14 mmarczyk: spoiled with the new toys :-)

1:16 vIkSiT: hehe totally

1:18 cemerick, wow, that list is comprehensive! How does one explore all that :)

1:19 cemerick: slowly, and only as needed :-)

1:25 vIkSiT: the graph library looks interesting

1:43 hmm is line-seq recommended to open files?

1:44 cemerick: vIkSiT: it takes a reader, but sure

1:44 vIkSiT: (line-seq (reader "filepath")) for instance.

1:44 ah, I was just guessing that since line-seq is lazy - it probably doesn't put everything in memory..

1:44 vs say, slurp

1:45 cemerick: vIkSiT: io/read-lines is probably better

1:45 vIkSiT: ah

1:45 cemerick: note the docs though

1:46 vIkSiT: cemerick, anything specific there btw?

1:46 mmarczyk: so if you might need to consume just a handful of lines, then close your reader, (with-open [r (reader path)] (let [ls (line-seq r)] ...)) might be better

1:46 defn: stu h's new screencast is awesome

1:46 cemerick: vIkSiT: regarding?

1:48 vIkSiT: cemerick, oh, nothing - I thought you were talking about soemething specific in the docs.

1:48 mmarczyk: (doc clojure.contrib.duck-streams/read-lines)

1:48 clojurebot: "([f]); Like clojure.core/line-seq but opens f with reader. Automatically closes the reader AFTER YOU CONSUME THE ENTIRE SEQUENCE."

1:48 cemerick: vIkSiT: only the fact that read-lines doesn't close the reader it opens until you consume the entire sequence, which is likely what mmarczyk was referring to

1:48 mmarczyk: see the bit in capital letters

1:48 yup

1:49 defn: it is, isn't it? :-)

1:49 vIkSiT: aah, I get mmarczyk's statement now as well, thanks!

2:04 oh I always forget to ask - on an emacs slime REPL - whats the best way to break the currently executing program/statement?

2:06 _ato: vIkSiT: C-c C-b

2:06 vIkSiT: ah thanks _ato

2:07 also, is there a way to "log" a particular REPL session into a file somewhere?

2:07 _ato: maybe C-x C-w (write-file) and enter a filename

2:08 that's a one off saving though, dunno about logging continuously

2:08 you can keep hitting save after you've named it I guess :p

2:08 vIkSiT: hehe

2:09 ah that works just fine..

2:09 I just need a log of some stuff

2:37 is there a way to create an index for an in memory clojure data structure?

2:37 (assuming you have a huge map for instance..)

3:54 carkh: vIkSiT: a map is already indexed by it's key isn't it ?

3:54 its*

4:07 LauJensen: Morning all

4:07 esj: and a good morning to you, sir.

4:07 ordnungswidrig: moin

4:09 spariev: morning

4:11 mmarczyk: good morning

4:12 spariev: isn't memfn deprecated ?

4:13 Raynes: mmarczyk: I was trying to modify a ref inside a macro inside a macro.

4:14 spariev: just received a ClojureInAction MEAP update, and found example with memfn in chapter on Java interop

4:15 Raynes: spariev: memfn existed before #().

4:15 I don't know why he would use it.

4:17 mmarczyk: hi Raynes

4:17 Raynes: Yo.

4:17 mmarczyk: are you by any chance trying to write a pair of a wrapper macro establishing state + a macro to be used inside that to update that state?

4:18 just occurred to me you might be

4:19 Raynes: I think that about nails it. It establishes some state and then does some stuff with it at the end. However, I just realized that isn't going to work like I want it to.

4:19 My macrofoo is quite weak.

4:19 mmarczyk: incidentally, it took me until now to put the pieces together and realise that I know you from all of SO, clj101 and here :-)

4:19 makes me feel a bit silly now

4:19 Raynes: ~@body tries to evaluate everything in an argument list passed to a multimethod in the other macro, and I don't see a way around that. :\

4:19 clojurebot: multimethods is what separates the boys from the men.

4:20 Raynes: Indeed.

4:20 mmarczyk: oh, well, I was thinking of posting an answer to your Q with some thoughts re: this kind of scenario

4:20 * Raynes thought it was a great idea.

4:21 mmarczyk: :-)

4:21 Raynes: mmarczyk: http://gist.github.com/381865 Is the actual example.

4:21 mmarczyk: incidentally, I find this surprising:

4:22 ,(let [g (gensym)] (= g (symbol (name g))))

4:22 clojurebot: true

4:22 Raynes: That fails. Hard. Since you wanted a more realistic example. :>

4:22 mmarczyk: not in hindsight, that is

4:22 but haven't expected it

4:22 Raynes: looking now

4:23 Raynes: Aye, that (do in defplugin is unnecessary, by the way.

4:23 Just haven't removed it.

4:24 mmarczyk: you might want to add a comment to your Q to point to that, it makes the idea come across

4:24 quite clearly

4:24 Raynes: I will once I get it less ugly and more of what I expected.

4:25 I also forgot to remove the quote from ~@body in defplugin.

4:25 That was a typo.

4:25 :p

4:25 This would totally work if not for ~@body forcing evaluating of the damned argument list.

4:26 mmarczyk: hm

4:26 ~@ has nothing to do with whether sth is evaluated or not

4:26 clojurebot: Ik begrijp

4:26 Raynes: http://gist.github.com/381870

4:26 mmarczyk: ouch, sorry, clojurebot

4:27 Raynes: mmarczyk: I guess that isn't quite what I meant.

4:27 Anyway, the arg list that is being passed to the multimethod from defcommand is being evaluated by something.

4:27 Because it gives me "whatever is not defined"

4:28 I've never really done anything significant with macros before.

4:29 mmarczyk: I'm trying to fix that atm

4:29 Raynes: Macros are fun until you realize that you're too dumb to write them. :>

4:30 Licenser_: Raynes: my experience: often a function works too

4:30 Raynes: For context, if anybody is wondering what I'm doing, I'm writing a DSL for plugins in sexpbot.

4:31 cgrand: Raynes: defplugin's body can only contain defcommand forms?

4:32 Raynes: cgrand: I've not decided on that yet.

4:32 It depends on whether or not it can contain other things without causing problems. :p

4:32 All that is really necessary in there is defcommand forms.

4:32 Technically, anyway.

4:33 You could put functions and such outside and just drop the defcommands in defplugin.

4:33 cgrand: then why bother with two separate macros?

4:33 Raynes: It doesn't really matter either way.

4:33 Because I was trying to go for the put-everything-in-defplugin scheme.

4:34 Because it would look better.

4:34 If that's too much trouble, I'll have to go that route.

4:38 mmarczyk: have you considered using clojure.contrib.macro-utils/macrolet ?

4:39 cgrand: put-everything-including-defs-and-defns?

4:39 mmarczyk: I've almost reimplemented a chunk of that just now, then realised I'd seen it in contrib :-)

4:39 (please disregard the nonsensical `almost' in the above)

4:40 Raynes: cgrand: Indeed.

4:40 * Raynes looks at macrolet

4:41 Raynes: Was that moved in contrib master?

4:42 Ah

4:42 macros

4:42 mmarczyk: http://gist.github.com/381879

4:42 I'm using latest contrib now

4:42 so yeah, maybe it was called something different before

4:42 the ns, that is

4:43 Raynes: http://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/macro-utils.clj is giving me a File Not Found

4:43 mmarczyk: the gist is just a rough sketch, btw

4:44 http://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/macro_utils.clj

4:44 Raynes: D'oh.

4:44 mmarczyk: :-)

4:45 Raynes: mmarczyk: Oh, that's cool.

4:45 cgrand: Raynes: alternative DSL designs which don't need two separate macros, https://gist.github.com/19367943286f495c96df

4:45 Raynes: mmarczyk: I can work with this.

4:46 Thanks, both of you. I like the macrolet option.

4:47 mmarczyk: cgrand's ideas look good, though -- especially the first one, looks a lot like defprotocol

4:48 Raynes: I don't think I really understand macros enough to implement either of those idea.s

4:48 ideas*

4:49 mmarczyk: that could be construed as a reason to try :-)

4:49 Raynes: Or a construed reason to kill myself.

4:49 I was pretty fond of my original idea. :\

4:50 I've already been frustrated for about 2 hours. Not sure I can handle another 10.

4:50 mmarczyk: nothing like a 10-hour-long bug hunting session, I find

4:51 I mean, I never quite get into that sort of kill-murder-destroy mood in any other way -- and it has this purifying effect, you know? ;-)

4:52 Chousuke: hmhm

4:52 I think you should try implementing both of cgrand's ideas

4:53 Raynes: Is the other idea really that bad?

4:54 mmarczyk: well actually the first defplugin with (cmdkey [args] body...) sections should be the most straightforward too

4:54 Chousuke: well the worst of it is that it captures the name cmd-list

4:54 mmarczyk: you could make that (defplugin plugin-name (cmdkey [args] body...)*)

4:54 Raynes: Capturing cmd-list should never cause any problems.

4:55 Chousuke: that would be pretty easy. you'd just get the name and a seq of cmdkey specs as parameters

4:55 mmarczyk: Chousuke: not with the macrolet approach

4:55 Raynes: And the macrolet approach uses a gynsym.

4:55 gensym*

4:55 mmarczyk: not to say I don't agree with the general sentiment, which I do

4:56 Raynes: I need an extra keyboard.

4:56 One I can beat my head against. :>

4:57 mmarczyk: hm, I seem to have forgotten to include the (let [g (ref [])] ...) bit in the gist, will fix in a sec

4:57 Chousuke: maybe you're trying too hard :P

4:57 create a simpler macro first, then expand

4:57 Raynes: I kind of just wanted this done. Immediately.

4:57 Which is more the problem than anything.

4:58 mmarczyk: ...fixed (hopefully)

4:58 Chousuke: Raynes: make a function that takes one of those (cmdkey [args] ...) things and then returns some clojure code

4:59 then do your macro like `(do whateverstuff ~@(map helper-fn cmdspecs))

5:00 cgrand: https://gist.github.com/19367943286f495c96df#L11

5:00 Chousuke: that would be a simple way to implement cgrand's first idea.

5:01 ... or that :)

5:01 Raynes: Close.

5:02 Each of these commands does more than just exist. Each of them take help string for the command and a list of words that will trigger the command.

5:02 I'm not sure how that would be possible like this.

5:04 Or wait.

5:04 Sorry, had a brainfart there.

5:04 It's all coming back to me.

5:04 :p

5:04 Chousuke: keep in mind that in principle you're just working with data structures

5:05 Raynes: Chousuke: I was thinking about it too much.

5:05 It makes sense now.

5:05 Chousuke: if you design your DSL so that the data structures are easy to modify it'll be easy to implement

5:06 Raynes: cgrand: I appreciate the head start there.

5:06 cgrand: You might have just taught me macros. :p

5:07 cgrand: Raynes: great!

5:08 * Raynes will show you guys the finished product after I'm done.

5:08 mmarczyk: :-)

5:12 cgrand: Raynes: don't look at this solution now then http://gist.github.com/381898 :-)

5:13 mmarczyk: and a working example of macrolet usage... though for a different purpose (which is ridiculous): http://gist.github.com/381904

5:26 Raynes: cgrand: Out outcomes ended up being quite similar. I just stole your clever trick to get rid of the ref.

5:26 cgrand: It's still tossing me that "whatever is not defined" stuff though.

5:27 cgrand: Raynes: can you paste your test?

5:27 Raynes: cgrand: Also, why is that `(do ..) before the ~@(for ..) important?

5:28 cgrand: http://gist.github.com/381923

5:28 "irc is not defined"

5:28 I assume it's trying to evaluate the stuff in the argument vector.

5:28 cgrand: because a macro returns only one form, so you have to group the defmethods and the dosync into a do

5:29 Raynes: cgrand: Oh, alright.

5:29 stilkov_: Is there a page somewhere that lists the performance guarantees for the various different collections?

5:29 http://clojure.org/data_structures only mentions them for some functions

5:31 Chousuke: hmm

5:31 a table would be easy to make

5:31 too bad I don't have a blog or anything to publish one :P

5:35 * Raynes yawns.

5:35 cgrand: Raynes: I can't reproduce your bug

5:35 Raynes: http://gist.github.com/381936 Is there anything wrong with my version?

5:35 stilkov_: Chousuke: I can offer a a blog that would be happy to host this :-)

5:40 Raynes: cgrand: I think I had some screwed up parens.

5:41 cgrand: Raynes: I guess beacuse your own version works as well as mine

5:41 jwr7: deftrace does not support functions with docstrings (as I've just discovered)

5:43 Raynes: cgrand: Works like a charm now. Thanks a lot, and congratulations on being part of the effort to run Clojurebot out of town. ;)

5:43 mmarczyk, Chousuke: Thanks to you guys as well. <3

5:47 * Raynes puts huge thanks in a comment above the macro.

5:48 Raynes: Now the fun part.

5:48 Converting some 30 plugins to use the new DSL.

5:49 lancepantz: can i use read-properties to read a properties file from the classpath instead of a specific file?

5:50 Chousuke: I wonder if conj to a vector is log32 or constant time

5:57 Anyone spot mistakes in this? It's all from memory and docstrings. www.gensoukyou.net/datas.html

5:57 sexpbot: "datas"

6:03 wooby: 'morning all

6:07 Chousuke: I wonder about the queue performance guarantees though :/

6:08 too bad rhickey isn't here :P

6:10 (don't tweet that url or anything, I make no guarantees of persisting stuff on my home server)

6:11 LauJensen: Chousuke: So accept stilkov's offer?

6:12 Chousuke: only after I get someone to agree with me on the veracity of that data

6:16 cgrand: Chousuke: conj on Queue is O(log32 n) (the tail of a queue is a vector)

6:16 pop is O(1) for vectors

6:17 err no

6:17 spariev: according to Chapter 5 of JoC, count on vectors is "essentially constant time", which means O(log32 n)

6:18 Chousuke: hmm, so they don't store a count value?

6:18 cgrand: pop is O(log32 n)

6:19 spariev: oh, sorry, my bad, it's o(1)

6:19 misreading on my part

6:19 Chousuke: yeah, I just checked the source

6:31 I guess the table is okay now.

6:41 Raynes: rhickey: Morning.

6:41 rhickey: hey

6:58 Chousuke: rhickey: I wrote a table summarising the performance guarantees of various data structures for certain operations: www.gensoukyou.net/datas.html any comments/corrections?

6:58 sexpbot: "datas"

7:02 rhickey: Chousuke: from an algorithmic (big-O) complexity standpoint, O(logN) and O(log32N) are the same, so big-O is not the way to distinguish those. Instead, you can say that access to an element will require max log32N hops, i.e. a concrete limit

7:03 conj and pop on vectors are O(1)

7:04 Chousuke: I suppose assoc doesn't work for sets either. I should probably note that somehow

7:06 rhickey: conj on queue is also O(1)

7:08 AWizzArd: rhickey: subvec also O(1) yes?

7:10 Chousuke: I suppose I'll just change the time guarantees constant, near-constant and logarithmic with explanations

7:11 and linear

7:13 rhickey: AWizzArd: yes

7:14 AWizzArd: gooood

7:20 patrkris: would protocols make it possible to transparently make partition fast on vectors by using subvec?

7:21 Chousuke: partition is fast

7:21 it returns a lazy sequence

7:21 so it's in effect constant tim

7:21 time*

7:22 LauJensen: Chousuke: I dont follow your logic

7:22 patrkris: the call to partition itself is fast, yes

7:23 LauJensen: patrkris: But yes, protocols would let you use specific functions for chopping up specific datatypes

7:23 patrkris: LauJensen: yes - but I guess multimethods could be used also

7:25 LauJensen: I guess.

7:27 Chousuke: I need to learn to use org-mode better :P

7:27 oh well, I guess the table is okay now.

8:16 wlangstroth: technomancy: were there really that many *jure projects? I only know of scriptjure.

8:17 Raynes: wlangstroth: Compojure, conjure, enclojure, etc.

8:18 LauJensen: technomancy: that last commit was a joke right?

8:18 wlangstroth: Raynes: I completely forgot about those - LauJensen: Pretty sure that was a joke - doesn't Compojure use lein?

8:19 Raynes: Surely it's a joke.

8:20 LauJensen: Raynes: If it was anybody other than phil who made it, I wouldnt even have asked :)

8:20 Raynes: :p

8:20 wlangstroth: He *has* kept it up there for a while, though

8:21 Raynes: Now my bot has a newly designed plugin system with an implicit help system, and all the plugins have been updated to the reflect the changes. That took a while.

8:21 Huge commit, that was.

8:21 26 files changed, 575 insertions(+), 455 deletions(-)

8:21 LauJensen: wlangstroth: Yes, and deep down in every American there's a communist screaming to get out, so I wouldnt put it past to him to feel like he should control how we name our projects :)

8:22 Raynes: Hey! :<

8:22 wlangstroth: LauJensen: It's so true. We Canadians admitted to our socialism long ago.

8:22 mmarczyk: in fact, at this very moment, he is following this conversation and laughing in an evil manner at those who are trying to believe this is all a joke

8:24 "Leiningen!" he shouted. "You're insane! They're not creatures you can fight--they're an elemental--an 'act of God!' Ten miles long, two miles wide--*jure projects, nothing but *jure projects! And every single line of code of each one of them a fiend from hell..."

8:24 Raynes: $help (

8:24 sexpbot: Raynes: Evalutate Clojure code. Sandboxed, so you're welcome to try to break it.

8:24 Raynes: It's beautiful.

8:24 mmarczyk, cgrand: I love you guys. <3

8:25 mmarczyk: :-)

8:25 LauJensen: mmarczyk: You must restrain yourself! We dont know for sure yet!

8:26 mmarczyk: pleased to make your acquaintance, Mr. Sexpbot

8:26 * Raynes puts more advanced hooking onto his todo list.

8:26 LauJensen: $(dorun (pmap count (partition 2 (range 10e9))))

8:26 Raynes: The core code is a mess right now because of a lack of sophisticated hooking.

8:26 sexpbot: Execution Timed Out!

8:27 LauJensen: Nice work Raynes

8:27 Raynes: LauJensen: Thank you. <3

8:27 It uses clj-sandbox for that. Courtesy of Licenser_.

8:28 mmarczyk: LauJensen: there's this strange feeling deep down in my gut, of truly the most dire portent, I fear

8:28 wlangstroth: That's the most sophisticated "Execution Timed Out!" I've ever seen.

8:29 mmarczyk: $(.hash "asdf")

8:29 sexpbot: No matching method found: hash for class java.lang.String

8:29 mmarczyk: (ouch)

8:29 $(.hashCode "asdf")

8:29 sexpbot: 3003444

8:29 fogus: $(#(% %) #(% %))

8:30 mmarczyk: $(.getDeclaredMethod Integer "parseInt" (into-array Class [String]))

8:30 sexpbot: DENIED!

8:30 rfg: $(def x 5)

8:30 sexpbot: DENIED!

8:30 Raynes: Oh yeah, that reminds me of a big.

8:30 bug*

8:30 LauJensen: $(future (+ 2 2))

8:30 sexpbot: DENIED!

8:30 Raynes: If it returns nil, it doesn't print anything.

8:30 That's something I forgot to fix from ages ago, because it isn't on my TODO list. :>

8:30 mmarczyk: $(eval :foo)

8:30 sexpbot: DENIED!

8:30 mmarczyk: $:foo

8:30 sexpbot: Command not found. No entiendo lo que estás diciendo.

8:31 rfg: $*clojure-version*

8:31 sexpbot: Command not found. No entiendo lo que estás diciendo.

8:31 mmarczyk: $(do *clojure-version*)

8:31 sexpbot: DENIED!

8:31 mmarczyk: $(identity *clojure-version*)

8:31 sexpbot: DENIED!

8:31 Raynes: It's 1.2.

8:31 But that var isn't whitelisted.

8:31 mmarczyk: the secretive Mr. Sexpbot :-)

8:31 $(clojure.contrib.find-namespaces/find-namespaces-on-classpath)

8:31 sexpbot: clojure.contrib.find-namespaces

8:32 rfg: $(System/getProperty "java.class.path")

8:32 sexpbot: DENIED!

8:32 Raynes: Right now, you can do less with him than you can with clojurebot, because of manual whitelisting. Lot's of useful stuff is whitelisted (everything in the core API docs, nearly).

8:32 * Raynes notes that sexpbot is also in #clojure-casual for more extended playtime.

8:33 mmarczyk: why'd he return 'clojure.contrib.find-namespaces for $(clojure.contrib.find-namespaces/find-namespaces-on-classpath) ?

8:33 #clojure-casual ? is there such a channel? :-)

8:33 Raynes: I don't know.

8:33 fogus: $(let [$ identity] (#(% $) #(% $)))

8:33 sexpbot: clojure.core$identity__3929@e62a39

8:33 Raynes: mmarczyk: Indeed.

8:35 mmarczyk: $(ns-resolve *ns* '*clojure-version*)

8:35 sexpbot: DENIED!

8:35 Licenser_: mmarczyk: if you break the sandbox you get a cookie :P

8:36 mmarczyk: oh! oh!

8:36 lemme get the code then

8:37 Licenser_: mmarczyk: changing the code to break it does not cound :P

8:37 mmarczyk: that much is understood :-)

8:37 Licenser_: elsewhre http://github.com/Licenser/clj-sandbox

8:37 sexpbot: Page has no title.

8:37 Raynes: Uh oh.

8:37 That isn't good.

8:37 Licenser_: I broke sexpbot

8:38 heh

8:38 Raynes: He's supposed to ignore github titles.

8:38 * Raynes investigates.

8:38 mmarczyk: still, I shall learn the anatomy of the target, so that I may most swiftly concoct the lethal poison with which to corrupt it

8:38 Licenser_: mmarczyk: appriciated

8:39 I claim it to be more secure then clojurebot :P

8:39 Raynes: Oh, I see.

8:42 <Licenser_> elsewhre http://github.com/Licenser/clj-sandbox

8:42 There we go.

8:42 Good bot.

8:43 mmarczyk: $(meta #'+)

8:43 sexpbot: {:macro false, :ns #<Namespace clojure.core>, :name +, :file "clojure/core.clj", :line 716, :arglists ([] [x] [x y] [x y & more]), :inline-arities #{2}, :inline #<core$_PLUS___3797 clojure.core$_PLUS___3797@15ed7e7>, :doc "Returns the sum of nums. (+) returns 0."}

8:44 mmarczyk: $(.alterMeta #'+ assoc :name '-)

8:44 sexpbot: Tried to call: alterMeta on #'clojure.core/+ which is not allowed.

8:44 mmarczyk: :-)

8:44 Licenser_: :)

8:44 good aproach but no cookie yet

8:45 mmarczyk: this only serves to strengthen our resolve (and hopefully the awaiting cookie grows larger in time)

8:45 Licenser_: just more

8:46 you know there is a limit of cookie size to create but the ammount of cookies - while certenly limited - is way more extenedable

8:46 mmarczyk: "You silly wabbit..." :-D

8:46 Raynes: Well, _ato` just broke sexpbot.

8:47 You guys are on a roll today. :p

8:47 Licenser_: _ato`: is good at breaking things

8:47 mmarczyk: Licenser: oh, I should have realised you'd have a lazy sequence of cookies

8:47 Licenser_: of cause

8:48 if my stove could laziely evaluate it I even could make a unlimited sized cookie but sadly it's a java stove and I don't have a clojure wrapper yet

8:49 mmarczyk: $(symbol "asdf")

8:50 oh the bothersome legacy stoves

8:51 Licenser_: $(symbol "asdf")

8:51 sexpbot: result: asdf

8:51 Raynes: Not as fixed as I thought.

8:52 mmarczyk: hm

8:53 $(throw (RuntimeException. "asdf"))

8:54 Raynes: mmarczyk: You might want to wait until the bot is online. :p

8:54 Works better that way.

8:55 mmarczyk: the very same idea has occurred to me ;-)

8:58 right, um, so I was going to retry that; here goes:

8:58 $(throw (RuntimeException. "asdf"))

8:58 sexpbot: asdf

8:59 spariev: $(str "b" (reduce (fn [x y] (str x "i")) "i" (take 30 (repeat :cookie))) "g cookie")

8:59 sexpbot: result: biiiiiiiiiiiiiiiiiiiiiiiiiiiiiiig cookie

8:59 spariev: just experimenting with lazy seq of cookies

8:59 Licenser_: good work spariev

8:59 Raynes: Cookies taste good.

9:00 mmarczyk: $(str #=(println "Regrettably, one must work harder than this for one's cookie."))

9:00 sexpbot: EvalReader not allowed when *read-eval* is false.

9:08 fogus: Clojure API needed. http://www.flyobjectspace.com/

9:08 sexpbot: "Fly Object Space"

9:09 mmarczyk: $(() ())

9:09 sexpbot: clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn

9:10 mmarczyk: $(the-ns 'user)

9:10 sexpbot: result: user

9:11 mmarczyk: $(.getMapping (the-ns 'user) 'resolve)

9:11 sexpbot: DENIED!

9:11 mmarczyk: :-(

9:12 obviously not gonna work, but hey... I've just thought of at least a dozen convoluted ways of calling Clojure functions by name :-)

9:17 Chousuke: ,(resolve 'foo)

9:17 clojurebot: nil

9:18 Chousuke: ,((resolve (symbol (apply str '[e v a l]))) '(+ 1 1))

9:18 clojurebot: 2

9:18 Chousuke: :P

9:18 mmarczyk: oh my :-)

9:19 Chousuke: I don't think there's any way to prevent arbitrary evaluation without actually explicitly somehow removing eval from the sandbox ns and all ways of getting to it.

9:19 mmarczyk: you're talking to the wrong bot, though :-)

9:19 $(resolve 'foo)

9:19 sexpbot: DENIED!

9:19 mmarczyk: ,(resolve 'foo)

9:19 clojurebot: nil

9:20 anars: ,(doc resolve)

9:20 clojurebot: "([sym]); same as (ns-resolve *ns* symbol)"

9:20 Chousuke: $(var resolve)

9:20 sexpbot: DENIED!

9:20 Chousuke: $(ns-resolve *ns* 'foo)

9:20 sexpbot: DENIED!

9:20 Chousuke: hmm, they've been more thorough :P

9:20 $'resolve

9:20 sexpbot: Command not found. No entiendo lo que estás diciendo.

9:21 Chousuke: $(do 'resolve)

9:21 sexpbot: DENIED!

9:21 Chousuke: ... very thorough :P

9:21 $(ns-mappings *ns*)

9:21 sexpbot: DENIED!

9:21 Chousuke: hmmh

9:24 LauJensen: Chousuke: I wonder if you ask Raynes nicely, if he won't give you your own special channel wherein you can practice :)

9:24 Raynes: I already did. :\

9:24 They just haven't listened. :p

9:24 kzar: #clojure-casual I think

9:25 Raynes: LauJensen: Every time people play with the bot, I note that it's in #clojure-casual as well for extended playtime.

9:30 At least chouser didn't have to see me make a fool of myself.

9:30 * Raynes hugs chouser

9:31 Chousuke: heh

9:31 LauJensen: mmarczyk: you're switching to mouse ?

9:31 cemerick: You got me there :)

9:32 Chousuke: http://github.com/technomancy/leiningen/commit/39732d5b649dedb70b14e88fe561dfc9ddb31611 \o/

9:33 wlangstroth: LauJensen: I'm guessing the concern for American roots had more to do with being sued than incurring a tax.

9:34 LauJensen: wlangstroth: as cemerick pointed out yes - though I hold a small grudge against your main man Al Gore, who wants to tax all of my precious CO2

9:35 cemerick: ah, the blunt cludgel of tax policy :-)

9:36 wlangstroth: LauJensen: I didn't realize you were the one responsible for so much CO2.

9:36 * wlangstroth is still Canadian

9:36 LauJensen: Yea thats my bad Im afraid

9:38 wlangstroth: I mean, I knew you were responsible for a lot of hot CO2, but ...

9:39 LauJensen: wow, cheap shot

9:40 wlangstroth: it was *right there* - how could I not take it? Besides, there's no technical discussion that I would interrupt.

9:40 LauJensen: yea I completely understand, now get going, I believe there are trees that need hugging - right ABOOT now :)

9:42 Raynes: Oh. I accidentally did :reload-all instead of :reload.

9:42 Good stuff.

9:43 wlangstroth: I believe you mean "A-BOAT", which is how we really say it. Hold on - there's an unhugged tree outside.

9:45 LauJensen: where *are* you, anyway - I want to at least know what part of Scandahoovia I'm insulting

9:46 Raynes: Now the bot has reload functionality. No more shutting him down just to fix a bug.

9:49 powr-toc: Is there a variant of catch that allows you to catch nested

9:49 exceptions? I'm using c.c.sql and it throws RuntimeExceptions, yet

9:49 the errors we need to catch are causally 2 deep

9:50 LauJensen: wlangstroth: Im in the middle of everything, aka Denmark

9:50 clojurebot: what time is it?

9:50 underdev: Time to get ill!

9:50 Raynes: powr-toc: clojure.stacktrace.

9:50 rfg: Denmark FTW

9:50 Raynes: powr-toc: (catch Exception e (.getMessage (clojure.stacktrace/root-cause e)))

9:51 AWizzArd: SQL-Gurus: I want to insert the contents of a vector 'v' into a table 't'. Only at runtime it is clear what the table is and how many elements the vector contains. Is there a better solution than (format "INSERT INTO %s (%s)" t (str/join \, (repeat (count v) \?)))

9:52 ,(format "INSERT INTO %s (%s)" "table" (str/join \, (repeat 5 \?)))

9:52 clojurebot: java.lang.Exception: No such var: str/join

9:52 AWizzArd: where str/join ==> clojure.contrib.string/join

9:52 ,clojure.contrib.string/join

9:52 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.string

9:53 zmila: AWizzArd - preferably you create sqls with different known tablenames, and then on run-time dispatch and select one of it

9:57 AWizzArd: zmila: clean and bureaucratic (:

9:57 Hallo bendlas

9:57 bendlas: hi AWizzArd

9:58 zmila: AWizzArd - RDBS performs better with prepared statements, it's not good to parse query on each insert.

10:00 mattcodes: yikes never expect this many people in a clojure chat room, tried join expecting id be setting up the room :)

10:01 bendlas: yeah, clojure has taken off

10:01 chouser: mattcodes: only a couple years late :-)

10:02 mattcodes: probably working through rubylearning clojure 101 course and programming clojure book (using intellij as IDE). still struggling to see benefits although i guy i follow on twitter has said it runs their forex system

10:02 i guy --> 1 guy

10:03 chouser: mattcodes: benefits compared to what?

10:04 slyphon: chouser: a poke in the eye with a sharp stick

10:04 chouser: oh, sorry, i meant VBScript

10:04 chouser: Clojure benefit #1: doesn't poke you in the eye

10:04 * slyphon laughs

10:04 mattcodes: coming from working with c# since 1.0 and getting alright in it (not ayende or udi dahan level) when would you use it in production? i watch a presentation the other day that social aspect make programming language successful - wealth of resources, pool of applicants for jobs, getting comfortable with clojure now but still cant see much benefit over java/c#

10:05 so someone is using in forex, just for algorithms like moving average or to host whole app, you write an app with you and your other collegaue, try going monster.com and getting a replacement

10:05 slyphon: that's a very CTO way of looking at it

10:06 mattcodes: playing devils avocadate because as much as Im improving and groking the concept I need a real excuse other than kool aid to follow it. e.g. peers of mind go scala meet ups (and have for 12 months) but come back and architecture and write everything in c#

10:06 Raynes: mattcodes: Clojure isn't as buried as you might think.

10:06 chouser: just watching this now: http://vimeo.com/11236603 ...an excelent presentation of one of the kinds of problems Clojure helps you solve better than a lot of other languages.

10:06 slyphon: or, you and your buddy *write* monster.com in whatever language makes you most productive, sell it to a bunch of guys who will *hire* some team of monkeys to code it into PHP while you enjoy flying around the world on a plane-that-never-lands

10:06 Raynes: mattcodes: It's experienced extremely aggressive growth in the past year or so.

10:07 mattcodes: i want to like it - dont get me wrong - to be a polygot programmer surely is a good thing but i dunno perhaps im asking questions too early

10:07 will check out the vimeo vids

10:07 slyphon: mattcodes: i'm writing a scheduler for a render farm with it

10:08 stilkov_: Chousuke: Thanks for the O() table, excellent

10:08 mattcodes: slyphon, and what benefits do you get over Java? presumably your utilising the stm?, for normal (most) apps thread per request im still not swaded

10:09 Chousuke: stilkov_: feel free to reformat it if you want to publish it in a blog or something

10:09 mattcodes: is it just because we have got into a habit of abusing mutable objects in java/c# etc?

10:09 Chousuke: stilkov_: org-mode exports contain a lot of extraneous stuff but it should be pretty easy to find the table in there.

10:10 mattcodes: (sorry I am playing devils avodcate here)

10:10 stilkov_: Chousuke: thanks, will do and link here

10:11 Chousuke: stilkov_: don't link to my domain though. it's just a temporary storage for stuff.

10:12 mattcodes: immutability makes things easier even if your application isn't multithreaded

10:12 stilkov_: Chousuke: have you considered gh-pages?

10:13 Chousuke: stilkov_: I guess I could take a look.

10:13 mattcodes: is anyone writing CRUD style apps in clojure? blogs, forum software, crm, sales, etc..

10:15 fogus: chouser: As always, a great video by Stu.

10:17 chouser: I'm trying to take his intro slide as a lesson. I already know about protocols and yet by the time he was done with that slide I *really* wanted to watch the rest to see all the things he teased.

10:17 I want to write chapter intros like that. :-)

10:17 wait, is this a public forum?

10:18 Raynes: _ato is evil.

10:19 chouser: Raynes: heh, did he hack it?

10:20 Raynes: chouser: He executed brainfuck to set the bot's nick.

10:21 _ato: $bf +++++++++++++.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.-----.------.++++++++.-------------------------------------------.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.---.++.------.+++++++++++++++.------------.+.++++++++++.

10:21 bfwin: {:ptr 0, :cells {0 115}}

10:21 [13 78 73 67 75 32 108 105 107 101 116 104 105 115]

10:22 Chousuke: :P

10:23 fogus: That is a cool hack

10:25 I would have never thought of that in a million years

10:25 Raynes: It's fixed now.

10:25 fogus: _ato is a beast.

10:25 fogus: Raynes: Good thing he's on our side... or is he? :O

10:25 Chousuke: how is the bf interpreter capable of changing the bot's nickname? :/

10:26 Raynes: fogus: :p

10:26 Chousuke: \rNICK

10:26 Chousuke: aha

10:26 Raynes: None of my commands filter newlines and carriage returns. He's finding those flaws.

10:26 Chousuke: hmm

10:27 wonder if that works with clojurebot too

10:28 Raynes: Doubt it.

10:28 Chousuke: it filters newlines but I'm not sure about CRs

10:28 ,(print "\rNICK testbot") ; something like this?

10:28 clojurebot: NICK testbot

10:28 Raynes: It filters them.

10:29 technomancy: LauJensen: it doesn't stop you from using lein with compojure, it just stops you from generating new *jure projects

10:29 -

10:29 Raynes: technomancy: You're actually serious, aren't you. o.o

10:30 Chousuke: technomancy: I approve

10:30 wlangstroth: technomancy: cenjureship!

10:30 Chousuke: there was this new library called "matchure" and my first thought before "cool!" was "oh no, another bad pun :("

10:30 Raynes: I approve, but wow.

10:30 Balls, man. You have them.

10:31 wlangstroth: oh, at least it wasn't "matjure"

10:31 Chousuke: well it's just as bad

10:31 fogus: Thankfully my super-secret project "jurey-rig" still works

10:32 wlangstroth: there's no filter for *all* bad puns

10:32 fogus: that's terrible

10:32 fogus: I died just a little inside

10:34 _ato: $ lein new injure-technomancy -- Exception in thread "main" java.lang.IllegalArgumentException: *jure names are no longer allowed.

10:34 likethis: Command not found. No entiendo lo que estás diciendo.

10:34 LauJensen: technomancy: Ok, so if this is not a joke, please explain why you should decide what my projects should be called and not me/my clients?

10:34 * Raynes lols

10:37 wlangstroth: LauJensen: because Phil rules (which should go in the error message, if you ask me)

10:37 Chousuke: LauJensen: because nothing will actually prevent you from naming your project whatever you want.

10:37 LauJensen: leiningen will just refuse to help you

10:37 technomancy: LauJensen: if you really want to you can create a project skeleton then rename it

10:37 it's just ... encouragement =)

10:38 fogus: technomancy: I think you didn't go far enough... you should refuse any name that has a 'j' somewhere in the middle. :p

10:38 Chousuke: :P

10:38 technomancy: as to whether it's a joke or not, well it's an open question.

10:39 arkahn: how does sexpbot understand bf?

10:41 _ato: arkahn: http://github.com/Raynes/sexpbot/blob/master/src/sexpbot/plugins/brainfuck.clj

10:41 LauJensen: technomancy: I think its in poor taste. I agree that we've all had enough of these J-themed names, in fact I would probably vote for a renaming of Clojure itself, but I think its way over the line that you try to police it via restrictions on the use of lein

10:41 Raynes: arkahn: I didn't write that, by the way.

10:41 arkahn: _ato: excellent : ) Thank you

10:42 Raynes: I'd still be proud ; )

10:44 technomancy: if there weren't a workaround I'd consider reverting it, but it's just an easter egg.

10:57 Licenser_: h

11:03 LauJensen: technomancy: thats it, I'm forking leiningen: Attention everybody, may I present: Leinjure

11:05 wlangstroth: LauJensen: will we all be forced to pronounce it "line-yoor"?

11:06 LauJensen: absojutely

11:06 technomancy: oh man, I should have seen that coming. =)

11:07 actually you could just implement that as a plugin

11:07 spariev: LauJensen: you can do what you want in your leijure time :)

11:07 LauJensen: leinjure will projibit plugins

11:07 technomancy: "lein newjure" => it automatically adds "jure" to the name of the project you're trying to generate

11:07 LauJensen: perfect!

11:07 wlangstroth: technomancy: you're a genius!

11:08 LauJensen: gejinus!

11:08 wlangstroth: LauJensen: I wasn't going to do it

11:09 I think we're only serving to illustrate the wisdom of technomancy's decision

11:20 stilkov_: Chousuke: http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html

11:20 sexpbot: " Clojure Performance Guarantees - Stefan Tilkov's Random Stuff"

11:23 chouser: that's a nice table

11:23 Chousuke: stilkov_: looks good. and hopefully is free of errors :P

11:23 chouser: is vector and queue conj really constant?

11:24 Chousuke: chouser: Rich said so

11:24 wlangstroth: stilkov_: nice chart - it's also true that this channel is great

11:24 AWizzArd: chouser: I understood Rich in that way: the performance has an upper limit. Thus, it is not constant, but typically below this limit.

11:24 spariev: chouser: and it's written in your book :)

11:25 about queue, at least

11:25 LauJensen: chojer: read the logs from 2 hours ago approx

11:25 Chousuke: :P

11:25 chouser: all the near-constant things have upper limits too

11:25 zmila: stilkov_, please add some colors to the table cells - according to performance

11:26 chouser: our book isn't yet perfect... ;-)

11:26 stilkov_: zmila: good idea

11:26 Chousuke: chouser: I think they might be something like initially linear but constant after n > something.

11:28 chouser: I see calls in PersistentVector.cons() to newPath and pushTail, which are both recursive.

11:28 So I'm surprised those are O(1). But far be it from me to contradict rhickey.

11:28 wlangstroth: Chousuke: would that n have to do with the 32-bit hash implementation?

11:28 Chousuke: wlangstroth: no?

11:29 AWizzArd: chouser: http://clojure-log.n01se.net/date/2010-04-28.html#06:41

11:29 sexpbot: "#clojure log - Apr 28 2010"

11:32 rhickey: chouser: pushTail will only be called 1x in 32

11:32 wlangstroth: Chousuke: I mean what's the limit on bagwell hash tries?

11:32 Chousuke: wlangstroth: I'm the wrong person to ask about such things

11:33 chouser: stilkov_: rather than saying "increases linearly" in the definition of "linear", you might consider saying "when the collection is twice as large the operation takes twice as long"

11:33 jowag: so, it seems that if I specify :library-path "/" in a project.clj, "lein clean" will delete my filesystem :)

11:33 chouser: rhickey: so (log32 n)/32 ?

11:34 Chousuke: you might want to clarify the "(e.g. 3.9 as long for a million elements than for 10 instead of 6)" too since it took me a long time to understand what that meant :P

11:34 stilkov_: that was for you ^

11:34 stilkov_: chouser: agreed on both parts - it doesn't help there's a "times" missing ;-)

11:36 rhickey: chouser: but log32N is always less than 32 for all data sizes we might consider

11:38 stilkov: that 3.9 times as long is a bit disconcerting. It is important to look at the absolutes rather than ratios. to get to 1 milltion: 1 hop from 32 to 1k, one hop from 1k to 32k, 1 hop from 32k to 1million = 3 hops

11:39 1 billion = 5 hops

11:39 chouser: ok, I see.

11:40 rhickey: binary tree is 20 hops to 1million

11:40 AWizzArd: and 1 msec ==> 3k hops?

11:40 rhickey: AWizzArd: ?

11:43 AWizzArd: ,(time (let [hm (hash-map :a 1 :b 2 :c 3)] (dotimes [i 1000000] (get :b hm))))

11:43 clojurebot: "Elapsed time: 209.814 msecs"

11:43 AWizzArd: ,(double (/ 1000000 209.814))

11:44 clojurebot: 4766.126187956953

11:44 rhickey: oh please

11:44 AWizzArd: 4766 gets per msec

11:44 rhickey: let's not waste time with microbenchmarks again

11:45 AWizzArd: Why is it then important how many hops we need to one million/billion?

11:48 chouser: AWizzArd: that has to do with relative amount of work and is useful for choosing the correct collection/algorithm combination

11:49 AWizzArd: Yes, though "hops" is an abstract thing for my poor human brain. "Time" says me more.

11:49 chouser: actual timing of large numbers of trivial operations depends on a lot of variables, most of which are both hard to control for and hard to control, and very few of which impact algorithm decisions

11:50 sattvik: AWizzArd: When deciding on a data structure for a given purpose, it is important to know the algorithmic performance guarantees of the structure. With that information and knowledge about how the structure will be used, the correct structure can be chosen. Ops/sec don't really tell you anything; they are highly dependent on the conditions of the test. Not least of all, they are unrealistic for most scenarios.

11:50 AWizzArd: When I hear: you can do 5k gets on Maps up to 100k elements, 3k gets on maps to 1 mio elements and 2k gets on maps to 1 bil elements, all per msec, then this gives me some information that I understand (:

11:50 sattvik: yes

11:50 rhickey: AWizzArd: and when the optimizer figures out that code doesn't do anything and optimizes it to instant, will it be very fast then?

11:50 wlangstroth: AWizzArd: but then you'd have to follow that up with your system configuration stats

11:51 rhickey: I've been auditing some of the seq fns for inclusion in core, not sure I want to include indexed

11:51 I think it leads to bad perf code

11:51 I instead have map-indexed, where the mapping fn will get passed the index and the item

11:52 indexed == (comp map-index vector)

11:52 er, map-indexed

11:53 * ordnungswidrig likes log32

11:53 chouser: I wish I had all the clojure code I'd ever written indexed somewhere by idiom.

11:53 clojurebot: Yes, Clojure can do that!

11:54 AWizzArd: ^^

11:54 chouser: Then I could find the 5 places I've used indexed and see how well map-indexed would fit.

11:54 rhickey: thinking about the filter analogue, I've come up with keep, like filter, but yields the result of the function if truthy, rather than the item

11:54 then we could have keep-indexed as well

11:54 chouser: ooh, for (filter identity (map ...))

11:55 hiredman: grep --include "*.clj" -R indexed src/*

11:55 wlangstroth: rhickey: I've reached for something like that twice now, so I'd be all for that

11:55 chouser: any chance of getting multi-seq walking on any of these? keep in particular.

11:55 wlangstroth: (keep, that is)

11:56 stilkov_: rhickey: not sure whether my understanding of hop is correct

11:57 the amount of time for some operation increases with the number of elements, either not at all, or logarithmically, or linearly, or something we don't hope for

11:58 rhickey: stilkov_: being trees, the cost of trees increases with their depth, one hop is nav from node to node

11:59 stilkov_: and the depth increases with log32(n) - right?

11:59 rhickey: stilkov_: you can compare the rations between log32 and log2, but it doesn't tell the absolute value story well

11:59 zakwilson: keywords are substantially faster as map keys than strings, right?

11:59 stilkov_: rhickey: ah, so you're not saying my explanation is wrong, just misleading

12:00 rhickey: e.g. in a binary tree, going from 33 items in the tree to 1 million mean going from 5 hops to twenty, in a clojure data structure it means going from 3 hops to 3 hops - same cost

12:01 ordnungswidrig: rhickey: so why is 32 the sweet spot?

12:03 rhickey: and 1-32 all take the same cost, no ratios at all, so it is not a continuum. Also in absolute terms, at max a Clojure tree (of a billion items) will take as many node navs as a binary tree with 32 items

12:05 oops sorry, s.b. 3 hops to 4 hops above

12:05 stilkov_: 3.9 something

12:05 rhickey: OK, will update accordingly. Thanks for the explanation.

12:06 dnolen: rhickey: ++ for map-indexed. I don't need indexed collections often, but when I do, that would be nicer than using indexed which is always a bit of a pain.

12:09 technomancy: I guess the only problem with map-indexed vs indexed + map is that then you have to have -indexed versions of all your seq-consuming functions, right?

12:10 rhickey: technomancy: you can always (map-indexed vector...), it is simply a better primitive than indexed

12:11 technomancy: oh sure, that makes sense

12:12 rhickey: stilkov_: in practice people will not see lookup perf change significantly with data structure size:

12:12 (let [v1k (into [] (range 10))

12:12 v1m (into [] (range 1000000))]

12:12 (time (dotimes [_ 1000000] (rand-nth v1k)))

12:12 (time (dotimes [_ 1000000] (rand-nth v1m))))

12:12 "Elapsed time: 257.341 msecs"

12:12 "Elapsed time: 461.878 msecs"

12:12 technomancy: still a little awkward more if you want to use it in a doseq, but maybe it'll grow on me. I like the concept.

12:13 stilkov_: rhickey: so the "near-constant" moniker seems very much justified

12:14 eyeris: The docs give the declaration (struct-map s & inits). Could someone translate this to english?

12:14 rhickey: stilkov_: right, even though some aspect is growing with a logarithmic relationship to the size, it becomes dominated by the constant factors

12:14 eyeris: I'm clearly not understaning what is expected for inits.

12:15 As a lisp-noob I thought & inits meant "and the rest of the arguments are converted to a list"

12:15 So I tried (struct-map my-declared-struct :key1 val1 :key2 val2)

12:15 hiredman: the docs for what?

12:16 eyeris: The api docs on the web site.

12:16 http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/struct

12:16 hiredman: right, but the api docs cover EVERYTHING

12:16 so specificly that is the docstring on struct

12:16 eyeris: Or, for (struct-map)

12:16 Chousuke: eyeris: the list of inits is a list of init values, not a list of key/val pairs

12:17 hiredman: ,struct-map

12:17 clojurebot: #<core$struct_map__5559 clojure.core$struct_map__5559@323ee8>

12:17 hiredman: ,(doc struct-map)

12:17 clojurebot: "([s & inits]); Returns a new structmap instance with the keys of the structure-basis. keyvals may contain all, some or none of the basis keys - where values are not supplied they will default to nil. keyvals can also contain keys not in the basis."

12:17 hiredman: eyeris: looks like you are confusing struct-map and struct

12:17 eyeris: So I just have to supply values for the keys in the order that their appear in defstruct?

12:17 Chousuke: huh. that docstring is confused

12:18 eyeris: yes

12:18 stilkov_: ,(do (defstruct my-declared-struct :key1 :key2) (struct-map my-declared-struct :key1 1 :key2 2))

12:18 clojurebot: DENIED

12:18 Chousuke: (doc struct)

12:18 clojurebot: "([s & vals]); Returns a new structmap instance with the keys of the structure-basis. vals must be supplied for basis keys in order - where values are not supplied they will default to nil."

12:18 stilkov_: eyeris: yields {:key1 1, :key2 2} in my REPL

12:19 Chousuke: right, so struct-map takes k/v pairs (though the docstring is confusing) and struct takes init vals

12:20 rhickey: chouser: you can extend them to N colls as a patch if you like :)

12:20 stilkov_: eyeris: so what problem do you run into with your code?

12:20 eyeris: stilkov_: I was initially confusing struct and struct-map as hiredman pointed out.

12:21 AWizzArd: rhickey: do you plan to add a Foo/create to records before 1.2?

12:22 rhickey: AWizzArd: dunno

12:22 eyeris: I initially used your invocation with struct instead of struct-map. Assuming that I misunderstood the & notation, reading the word keyvals in the struct-map documentation, I put my :key val sequence into a map. I realized that I needed struct-map, but then I forgot to remove the map braces :)

12:25 AWizzArd: rhickey: in principle it could be advantageous to ship 1.2 without that and just wait a while and see what the users are doing. New features can be added later. But then print-dup could be adpoted maybe, to not print as #=(user.Foo/create {:x 1000})

13:26 slyphon: chouser: around?

13:26 chouser: w'sup?

13:26 clojurebot: http://github.com/hiredman/clojurebot/tree/master

13:26 slyphon: chouser: could you look at something for me and tell me if i'm "doing it wrong"?

13:27 https://gist.github.com/9ddaa20d37a4a4be4d07

13:27 KirinDave_: Oh shit

13:28 slyphon: chouser: i'm just not sure if i'm missing something, like line 100

13:28 stylistically speaking

13:28 does this look like what clojure test code should look like?

13:29 chouser: yeah, I'm not the best person to ask about this.

13:29 slyphon: oh :)

13:30 i guess it's just that i don't work with a bunch of other clojure developers, and i know i'm learning, so i always have that voice in the back of my head saying "you're doing it wrong"

13:30 digash: (defn ^bytes [] (byte-array 10)) (String. (bytes10))

13:30 chouser: slyphon: oh, it's good to ask, but I haven't done enough with clojure.test to really know the idioms

13:30 * slyphon nods

13:30 digash: throws an exception Unable to resolve classname: clojure.core$bytes__4916@27443628

13:30

13:30 slyphon: chouser: who do you think i should ask?

13:31 chessguy: so someone at my work is looking for implementations of this function, but i don't know the clojure libraries well enough to do it without a painstaking search

13:31 digash: does anybody know why? I am on the latest 1.2

13:31 chessguy: here's the ruby implementation

13:31 str.split('/').reject(&:blank?).reverse.join(', ')

13:31 pretty darn expressive

13:31 slyphon: that's "rails"

13:32 so some of the expressiveness has been handed to you

13:32 chessguy: well, sure you can use libraries

13:33 doesn't make it a different language

13:33 chouser: does &:blank? just match empty strings or also whitespace?

13:33 chessguy: empty strings

13:33 slyphon: blank means "is nil or empty string"

13:33 doesn't barf on nil

13:34 chouser: (->> "abc/def/ghi" (.split #"/") (remove empty?) reverse (str/join ", "))

13:34 slyphon: wuuuuu!

13:35 (.split #"/") really?

13:35 nice

13:35 * slyphon didn't know that

13:35 chessguy: ,((->> "abc/def/ghi" (.split #"/") (remove empty?) reverse (str/join ", ")) "/C=US/O=U.S. Government/OU=DoD/OU=CENTCOM/OU=People/CN=Smith Bob A xyz123")

13:35 clojurebot: java.lang.Exception: No such var: str/join

13:36 slyphon: HAH

13:36 chessguy: you're leaking classified information there

13:36 chessguy: about Bob Smith?

13:36 slyphon: *joke*

13:36 zakwilson: ,(reverse (filter #(not (= "" %)) (.split "foo/bar/baz//qux" "/")))

13:36 clojurebot: ("qux" "baz" "bar" "foo")

13:37 licoresse: emacs clojure-test-mode, is that working well with 1.2?

13:37 zakwilson: ,(reverse (remove empty? (.split "foo/bar/baz//qux" "/")))

13:37 clojurebot: ("qux" "baz" "bar" "foo")

13:37 licoresse: I'm new to tests and clojure

13:38 chouser: zakwilson: I recommend (.split #"regex" "string") over (.split "string" "regex-in-a-string")

13:39 zakwilson: chouser is more of an authority than I am. Listen to him.

13:39 dnolen: (->> "abc/def/ghi" (split #"/") (remove blank?) reverse (join ", "))

13:39 if you're using clojure-contrib 1.2.0

13:40 chessguy: that's nice

13:40 though i'd rather have a function i could pass the string into

13:40 slyphon: uh

13:40 you just wrap the above in (fn blah [s] ...)

13:40 chessguy: yeah, i know

13:41 but it's not that way now

13:41 zakwilson: ,(#(->> % (split #"/") (remove blank?) reverse (join ", ")) "foo/bar/baz//qux")

13:41 clojurebot: java.lang.Exception: Unable to resolve symbol: join in this context

13:41 zakwilson: ,(#(reverse (filter #(not (= "" %)) (.split #"/" %))) "foo/bar/baz//qux")

13:41 clojurebot: Nested #()s are not allowed

13:42 zakwilson: ,(fn [x] (reverse (filter #(not (= "" %)) (.split #"/" x))) "foo/bar/baz//qux")

13:42 clojurebot: #<sandbox$eval__12354$fn__12356 sandbox$eval__12354$fn__12356@174c643>

13:42 zakwilson: ,((fn [x] (reverse (filter #(not (= "" %)) (.split #"/" x)))) "foo/bar/baz//qux")

13:42 clojurebot: ("qux" "baz" "bar" "foo")

13:42 zakwilson: There... NOW it has enough parens to be proper Lisp!

13:43 slyphon: zakwilson: hah!

13:43 chessguy: lol

13:46 licoresse: how do I organize the test-files under test/ ? SHould I follow the same directory-structure as my clj files? Should there be a 1-to-1 mapping of source and test-source?

13:46 Trying to figure out the C-c t command in clojure-test-mode

13:47 (the one that switches from source to test-source)

13:48 technomancy: licoresse: the test toggle is kinda half-baked; there aren't any good conventions yet for mapping between test and impl.

13:48 licoresse: technomancy: ok

13:49 That means, I should'nt worry too much about where to put the tests...

13:49 as long as they are under test/

13:49 technomancy: correct?

13:49 technomancy: I like to have src/foo/bar.clj map to test/foo/test-bar.clj personally, but yeah, anything under test/ works

13:50 stuartsierra: technomancy: I liked Halloway's suggestion of test/foo/bar_test.clj, results in better sorting

13:50 technomancy: stuartsierra: sure, good point.

13:51 licoresse: stuartsierra: yes

13:51 technomancy: we currently have test/foo/test/bar.clj, which is lousy because stack traces often just give the last segment, so you can't distinguish between impl and test. =\

13:52 wlangstroth: chouser: for the above matching, is there any reason not to use re-seq?

13:53 Borkdude: What's the deal with str-utils and str-utils2, which should I use?

13:53 chouser: wlangstroth: not really -- just which is more natural for the regex you want. they're sort of complements of each other.

13:55 stuartsierra: Borkdude: neither :)

13:55 Borkdude: In 1.2, both are deprecated in favor of c.c.string.

13:55 Borkdude: stuartsierra: just use the things you need from either or both?

13:55 oh

13:56 stuartsierra: Borkdude: str-utils2 will be faster than str-utils(1), should support all the same functionality.

13:56 Borkdude: how do I disuse a namespace?

13:56 stuartsierra: You mean unmap the symbols you referred with "use"?

13:56 Borkdude: yes

13:57 stuartsierra: Can't. Just create a new namespace to work in or restart the REPL.

13:57 Borkdude: ah

13:57 chouser: (re-seq #"[^/]+" txt) seems clumsier than (.split #"/" txt) ...besides not meaning *exactly* the same thing

13:57 kotarak: (doc ns-unmap)

13:57 clojurebot: "([ns sym]); Removes the mappings for the symbol from the namespace."

13:57 kotarak: Borkdude: could be tedious

13:58 (doc ns-interns)

13:58 clojurebot: "([ns]); Returns a map of the intern mappings for the namespace."

13:58 Borkdude: stuartsierra: I made a new ns and used c.c.string, I get this:

13:58 repeat already refers to: #'clojure.core/repeat in namespace: user2

13:58 stuartsierra: oh yeah

13:59 c.c.string contains names that clash with core

13:59 You can't "use" it without ":only".

13:59 Or, alternately, "(require '[c.c.string :as s])"

14:00 wlangstroth: chouser: right, thanks

14:00 mabes: does anyone know of a congomongo clojure 1.2 compat fork? There doesn't appear to be any on github or clojars...

14:02 Borkdude: I was just wondering if split also was a function in c.c.string or if it still should be called using direct java interop

14:03 but apparently it's not in there

14:03 kotarak: mabes: I seem to remember I used it with 1.2. What problem do you see?

14:03 mabes: kotarak: I haven't dug into it yet, but when I try to 'use' it I get: java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (coerce.clj:1)

14:04 stuartsierra: Borkdude: "split" is in c.c.string

14:04 kotarak: mabes: then you have to recompile it with 1.2 (or use the source files directly). I'm not sure whether it uses gen-class. I think, that part is in Java and hence independent of the clojure version

14:05 mabes: kotarak: ah, that makes sense. I'll try recompiling it with 1.2 update any require/use statements if needed.

14:07 wlangstroth: does anyone know if the precise difference between using a list and a vector with use/require is documented anywhere?

14:07 stuartsierra: there is no difference

14:08 the implementation doesn't care

14:08 somnium: mabes: my branch on clojars isnt aot-compiled, not sure of the forks. planning to overhaul it 1.2rc is available, but Ive heard reports of it working with 1.2 as is

14:08 Borkdude: stuartsierra: can you use :only within a normal (use ...)?

14:09 chouser: Borkdude: yes, please always use :only anytime you use 'use'

14:09 wlangstroth: stuartsierra: okay, thanks - I think I was getting confused with the examples

14:12 lambdatronic: hi folks. I've got a really confusing map problem.

14:12 Borkdude: chouser: can you give an example of (use ...) with :only then? I never can remember the syntax

14:13 lambdatronic: @borkdude: (:use [foo.bar.baz :only (fun1 fun2 fun3)])

14:13 chouser: exactly

14:13 somnium: anyone know of any examples of using datalog? and does it support backtracking?

14:14 chouser: :as works too. I basically never use 'require' anymore, just (:use [foo.bar :as bar :only []])

14:15 wlangstroth: lambdatronic: confusing map problem?

14:15 Borkdude: lambdatronic: that is not what I meant

14:15 lambdatronic: So...for some deeply mysterious (to me anyway) reason, I've got a map of vectors to structs: {[0 0] s1, [0 1] s2, ... [n m] sN}; however, I can't look up the structs by key in this map. I create a vector [0 1] (or whatever) and attempt (mymap [0 1]) and I'm just getting nils.

14:15 Borkdude: I mean (use ...), not (:use ...)

14:16 lambdatronic: now, I've even attempted = tests between the vector I create and the keys in the map, and they're coming up =.

14:16 But still...just nils.

14:16 I'm using Clojure 1.1.0

14:16 master

14:17 Am I missing something totally obvious here?

14:18 somnium: ,(let [m {[0 1] :a} k [0 1]] (m k))

14:18 clojurebot: :a

14:18 stuartsierra: Borkdude: (use...) is the same as (ns ... (:use ...)) except you have to quote all the symbols.

14:19 lambdatronic: @somnium right, I tried that, and it works from the REPL.

14:19 so there's something going wrong inside my function that I can't suss out.

14:19 somnium: lambdatronic: maybe pastie the problematic section?

14:19 lambdatronic: will do. just a sec.

14:21 Borkdude: stuartsierra: ah tnx

14:21 gtg

14:22 chouser: is there a better way to write #(compare (first %1) (first %2)) ?

14:23 I wrote a 'compare-by' to do that, but I wonder if I missed something like that in core somewhere.

14:23 opqdonut: (defn comparing [f] #(compare (f %1) (f %2))), and then use (comparing first)

14:23 :)

14:23 chouser: yeah

14:23 's what I did. :-)

14:23 slyphon: so, if i wanted to encapsulate a jms Consumer and present it as a seq of messages, how would i go about doing that?

14:23 chouser: actually, I used defn :-P

14:23 * slyphon looked at enumeration-seq but that's just clojure.lang.EnumerationSeq/create

14:24 chouser: #(apply compare (map f %&)) meh

14:25 slyphon: ooh

14:25 take-while...kinda...

14:26 wlangstroth: chouser: by "better" do you mean faster? The first one reads fine, is what I mean

14:26 slyphon: chouser: any insights into how to go about using lazy-seq

14:26 ?

14:26 chouser: no, not faster. more succinct, abstracted

14:27 slyphon: little. yellow. different. clojure.

14:27 chouser: slyphon: One rarely needs to use lazy-seq directly.

14:27 slyphon: hrm

14:28 mabes: somnium: I just tried bumping the clojure deps to 1.2 in the congomongo project itself, and it is blowing up when I try to use it with the same error (java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (coerce.clj:1)) This is with the latest 1.2 so something may have changed since the last time someone tried using it with 1.2

14:28 slyphon: i basically want to yield (.receive consumer) until it returns nil (marking the end of the sequence)

14:28 mabes: somnium: this is all I did: http://github.com/bmabey/congomongo/commit/67647703384239b7e13a71a026c77c307f55e64c

14:28 * slyphon can't help but think of this in ruby/python terms

14:30 slyphon: anyone?

14:31 chouser: (take-while identity (repeatedly #(.receive consumer)))

14:31 * slyphon looks up what identity does

14:32 chouser: that'll stop on a false too

14:32 slyphon: hah

14:32 zakwilson: ,(identity 4)

14:32 clojurebot: 4

14:32 slyphon: excellent, i was about to use "for"

14:32 zakwilson: ,(identity 'foo)

14:32 clojurebot: foo

14:32 zakwilson: this relies on the property that nil is treated as false, and everything that isn't nil or false is treated as true

14:33 * slyphon nods

14:33 slyphon: that much i get

14:33 chouser: thanks

14:34 chouser: you could use (complement nil?) if you need to allow false's to get through

14:34 slyphon: hmm

14:34 nah, anything that gets through should be a Message

14:34 but yeah

14:40 somnium: mabes: ah, you dont need user in the project.clj. I should take that out. may need to rename some things with c.c.1.2-master though.

14:48 lambdatronic: alright.

14:48 so I created a minimal test case and pasted it here: http://paste.lisp.org/display/98512

14:48 Just load it into a repl and run (clj-span.test/test-me)

14:49 You should be able to see that the problem is in whatever is coming out of find-viewpath.

14:49 Those vectors won't work as keys in the evil-map, although literal vectors do.

14:49 Any help I can get here would be deeply appreciated. This bug has been biting me for a few days now.

14:51 Don't suppose anyone is up for taking this case?

14:59 slyphon: you know what would be cool in clojure-mode, highlighting #_ comments

14:59 lambdatronic: @slyphon agreed

14:59 * slyphon has nowhere near the emacs-fu necessary to attempt that

14:59 tcrayford: explain #_ comments

15:00 * tcrayford has never seen that term before

15:00 lambdatronic: it's a reader macro that blocks the reader from reading the next form

15:00 LauJensen: If you haven't heard about protocols, here's the 101: http://www.bestinclass.dk/index.php/2010/04/prototurtle-the-tale-of-the-bleeding-turtle/

15:00 sexpbot: "ProtoTurtle — The tale of the bleeding turtle | BEST IN CLASS"

15:00 lambdatronic: so #_(foo bar baz) is just entirely skipped

15:00 slyphon: ,(#_(list :a :b) (list :c :d))

15:00 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

15:00 slyphon: hrm

15:00 tcrayford: I might have a look

15:00 slyphon: ,([#_(list :a :b) (list :c :d)])

15:00 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentVector

15:01 slyphon: word?

15:01 clojurebot: http://gist.github.com/54847

15:02 slyphon: ,(concat (str "foo") (str "bar"))

15:02 clojurebot: (\f \o \o \b \a \r)

15:02 slyphon: ,(concat #_(str "foo") (str "bar"))

15:02 clojurebot: (\b \a \r)

15:02 tcrayford: gotcha

15:02 chouser: ,(concat (comment (str "foo")) (str "bar"))

15:02 clojurebot: (\b \a \r)

15:03 slyphon: yeah, it doesn't highlight (comment) either

15:03 :)

15:03 chouser: ,(+ 1 2 #_(whoa horsey!) 3)

15:03 clojurebot: 6

15:03 slyphon: (it does in vim-clojure)

15:03 tcrayford: I have some trouble with clojure mode highlighting mutliline strings with sexps in them

15:03 stuartsierra: First cut at 1.1 backwards compatibility from 1.2 contrib to 1.1 contrib is in master now.

15:03 chouser: ,(+ 1 2 (comment (whoa horsey!)) 3)

15:03 clojurebot: java.lang.NullPointerException

15:03 slyphon: riiigh

15:03 t

15:03 chouser: stuartsierra: thanks for doing that. I'm sure it'll ease some pain.

15:04 tcrayford: stuartsierra: is the api for lazytest final?

15:04 stuartsierra: I haven't added any deprecation warnings yet, interested to see if anything happens with the metadata idea on the list.

15:04 tcrayford: no

15:04 tcrayford: I'm mostly concerned about how results look

15:05 was thinking of writing a runner for emacs (something like clojure-test-mode)

15:05 stuartsierra: you mean the output of spec-report?

15:05 mabes: stuartsierra: so no deprecation warnings, but all c.c.1.1 will work on 1.2?

15:05 stuartsierra: mabes: as of this moment, yes. Deprecation warnings may get added.

15:05 tcrayford: yeah, I think

15:06 stuartsierra: tcrayford: the report format is the least developed part; thus most likely to change.

15:06 tcrayford: if you were going to write a runner, I'd prefer it operate directly on the output record types, e.g. TestResultContainer

15:07 But even those are not API-stable right now.

15:07 tcrayford: aye

15:07 once those are, I'll have a crack

15:07 or if I get bored in the meantime

15:07 stuartsierra: I don't think it will change significantly from this point, but no promises.

15:08 tcrayford: ofc

15:08 I might give it a go when these exams are over

15:09 stuartsierra: Someone wrote an auditory test monitor: http://is.gd/bJ5Yb

15:09 sexpbot: "bgruber's lazytest-listen at master - GitHub"

15:10 tcrayford: heh

15:10 that's pretty cool

15:10 I like having green bar red bar type stuff (like java IDEs) though

15:11 stuartsierra: yeah, I thought about doing a little swing widget with that

15:12 webben: tcrayford: I've seen an implementation of those bars for vim.

15:12 tcrayford: you can get something similar out of emacs. I hacked clojure-test-mode to do that

15:12 webben: by @garybernhardt probably, the inspiration for my one

15:12 webben: tcrayford: maybe

15:13 tcrayford: A swing widget might be interesting

15:13 I keep on getting tempted to write a clojure ide in clojure

15:14 webben: you could update waterfront

15:14 somnium: so, as an experiment, I took a chunk of code that used a combination of refs and thread-local-vars, and rewrote it with a state monad.

15:14 Aside from the moral victory of being completely stateless, they looked almost identical. The only real gain seemed to be zero bugs related to laziness under the monad.

15:15 slyphon: hrm, it seems like clojure.test sometimes swallows exceptions

15:15 mabes: somnium: fyi, this commit updates congomongo to c.c 1.2: http://github.com/bmabey/congomongo/commit/8798072f28d563b22d4d18553ab8c03e858d74bb

15:16 somnium: mabes: cool

15:16 tcrayford: somnium: zero (apparent) bugs is a very nice thing to have no?

15:17 mabes: stuartsierra: do you see lazy-test and circumspec ever merging or collaborating more closely? i.e. the watcher functionality seems to be duplicated to both projects.

15:18 tcrayford: iirc stu halloway is depreceating circumspec at some point soon

15:18 in favour of lazy-test

15:18 stuartsierra: mabes: lazytest is intended to subsume circumspec

15:18 and eventually replace clojure.test

15:19 tcrayford: would clojure-core be tested with lazytest at that point?

15:19 mabes: stuartsierra: ah, ok. That makes sense.

15:19 stuartsierra: tcrayford: maybe

15:19 mabes: stuartsierra: in that intention shared by stuart? (the other stuart)

15:19 stuartsierra: mabes: yes

15:20 Basically, we came at it from opposite directions.

15:20 S. Halloway wrote circumspec by adding features he wanted in clojure.test.

15:20 I started by rewriting the core internals from scratch.

15:20 mabes: stuartsierra: yeah. I have been trying out circumspec (I'm a big rspec user) and I like certain things about it.. the macro nature of it has gotten in the ways at times

15:21 stuartsierra: With lazytest, I hope to provide convenient macros for all the common cases but open the door for constructing tests functionally as needed.

15:21 I'm not there yet.

15:21 slyphon: :)

15:21 stuartsierra: what are you doing talking in here then? go!

15:21 * slyphon whipcracks!

15:21 stuartsierra: heh

15:22 slyphon: ;)

15:22 stuartsierra: seriously, I do need some feedback. What works about the current syntax, what doesn't work, ...?

15:22 slyphon: where is it?

15:22 clojars?

15:22 tcrayford: http://github.com/stuartsierra/lazytest

15:23 I'm not sure about the `is` macro's syntax

15:23 the wording feels a little strange (coming from rspec anyway)

15:23 stuartsierra: yeah

15:23 mabes: stuartsierra: well.. I haven't taken too close a look at lazytest.. but from what I have seen it looks nice.

15:24 stuartsierra: tcrayford: I tried "should" but that was too long

15:24 mabes: Along those lines.. I didn't like how the word "spec" simply replaced "test"

15:24 tcrayford: heh

15:24 stuartsierra: tcrayford: and I don't like Rspec's habit of mixing language keywords in with doc strings

15:24 tcrayford: maybe the project should be called lazyspec

15:24 stuartsierra: mabes: originally "spec" was "testing" actually

15:24 mabes: in rspec we originally had "specify" (still there I think but not used by many)

15:25 stuartsierra: I renamed it to "spec" because it was shorter. "test" is already taken in clojure.core

15:25 tcrayford: if lazytest replace clojure.test, spec would get renamed to test?

15:25 stuartsierra: clojure.core/test has been around since 1.0, although it doesn't do much

15:26 I thought about making the syntax even more abstract, like renaming "spec" to "T" (for test) and "is" to "A" (for assertion)

15:26 mabes: right, well, so the whole point of rpsec, BDD in general, was to have the tests read like an english sentence. So, if you are trying to make it like rspec I think taking an approach similar to circuspec (as far as syntax is concerned) makes more sense IMO.. Otherwise I don't see value in using BDD terminology as opposed to traditional TDD...

15:27 stuartsierra: mabes: I'm trying to do BDD-style english sentences. The difference from Rspec or circumspec is that the macro names aren't part of the sentence.

15:28 tcrayford: I liked circumspecs old munging of predicates (personally), but it was kinda klutzy

15:28 stuartsierra: I found that Rspec forced me to write sentences in a particular way, not necessarily the most clear.

15:28 mabes: BTW.. I'm very opinionated in this area, so please don't take this as criticisms against all your hard work on it

15:28 stuartsierra: not at all

15:29 I want to discuss this kind of stuff, to figure out what direction I should go.

15:29 somnium: tcrayford: it was cool to be able to save a set of statements and have the luxury of running (seemingly) side-effecty code under any previous snapshot, with-out needing set-up/tear-down macros or doalls.

15:30 tcrayford: somnium: aye. Was this on congomongo or some other code I can have a look at?

15:30 somnium: tcrayford: ah, this is for a compiler experiment that has gone on for far too long, but may be out soon :/

15:31 tcrayford: I'd be interested in seeing the monady stuff

15:31 monads really are very cool

15:32 wlangstroth: stuartsierra: with that naming convention, I'm sure you would get some takers. Just call it "T&A"

15:32 stuartsierra: ha!

15:32 mabes: I know they aren't idomatic clojure but they seem like a tool that any FP programmer should have in their toolbox (disclaimer: I just started to learn about mondas)

15:33 tcrayford: its kinda funny how simple they are

15:33 and how powerful

15:34 somnium: tcrayford: the core of its here, (I found c.c.monads to be slightly too magical)

15:34 http://gist.github.com/360303

15:34 tcrayford: somnium: cheers

15:34 slyphon: so, it seems there's no simple way to "inherit" a defmulti stack

15:34 and overload only one or two of the methods within

15:34 somnium: Ill admit to probably trying too hard to make it look haskell :)

15:35 tcrayford: heh, do notation in clojure :P

15:35 I was more interested in the code that used the state monad, as opposed to the implementation of it :P

15:35 but still interesting

15:36 mabes: stuartsierra: WRT direction of lazy-test.. I think it would be very valuable to have the specs be allowed (encouraged?) to be written in such a way that when tacked onto the metadata of that function they provide great documentation...

15:36 zakwilson: I'm uncertain about the utility of monads in most Clojure code, but one thing I'd like to see in a dynamically-typed language is a deeply-integrated maybe type.

15:36 mabes: stuartsierra: for example, this doco plugin for rspec allows that for ruby: http://lsegal.github.com/yard-spec-plugin/

15:36 tcrayford: mabes: have you seen Ioke's documentation?

15:36 mabes: tcrayford: Yes! that is exactly what I'm talking about

15:36 stuartsierra: mabes: I tried that in clojure.test and nobody used it.

15:37 tcrayford: mabes: so so cool for understanding the language

15:37 mabes: tcrayford: except I don't like the word "should" in documenation

15:37 tcrayford: aye

15:37 docs are what it DOES

15:37 stuartsierra: mabes: The problem is it bloats your source code files, especially when the tests/specs depend on external libraries that the main code doesn't need.

15:38 mabes: I stopped using "should" in any of my specs once I realized that they are executable documentation and should be written as such

15:38 tcrayford: stuartsierra: I think he meant having it in external files, just referencing implementation files

15:39 mabes: stuartsierra: seems like that would be an acceptable trade-off for development. For production I don't think you would ship the extra meta-data.

15:39 stuartsierra: clojure.test supports that explicitly, the "with-test" macro.

15:39 But nobody uses it.

15:39 I tried using it myself and found it cluttered the source too much.

15:40 mabes: stuartsierra: does that append the tests to the metadata?

15:40 stuartsierra: yes

15:41 tcrayford: does anybody here have any ide/tooling type things they'd like to see added to emacs for clojure?

15:42 mabes: stuartsierra: hmm.. well, the problem I am running into is that I/my team is duplicating a lot of the docstring verbage in the tests. So, it seems natural to pull the test verbage (not the entire tests) out into some metadata. Plus docstrings tend to get stale more than the test descriptions do...

15:42 stuartsierra: tcrayford, mabes: What I'm working toward now is having specs/tests in a separate file from the main source, but defined in such a way that they attach themselves to metadata in the main source. The "describe" macro will be part of this, with significant changes.

15:42 somnium: Im curious, in general is (comp f g) slower than (fn [blah] (f-body (g-body blah))), or does the jit make such considerations irrelevant?

15:43 stuartsierra: mabes: yes, I want to avoid duplication as much as possible. Of course, you don't have to include doc strings in the tests if they're redundant.

15:43 tcrayford: stuartsierra: that'd add enough to get something like ioke's documentation features

15:43 stuartsierra: exactly

15:43 chouser: would it be wrong to present a mutable work-queue as a seq?

15:43 mabes: tcrayford, stuartsierra: yeah, all I'm after is something similar to what ioke provides

15:43 * hircus seconds somnium

15:43 chouser: oh, nm, of course it's wrong.

15:44 tcrayford: ooh, if its on the metadata, I can get 'jump to spec for this function' kinda stuff going (and probably jump to function for this spec as well)

15:44 probably as a swank plugin

15:45 stuartsierra: yes, that would be useful, and the kind of thing I want to enable

15:46 lambdatronic: hey folks. it's me again. I've still got the problem with map lookups not working on a collection of vector keys.

15:46 tcrayford: if the metadata for the spec said which var it was attached to (if any), that'd be easy

15:46 lambdatronic: the paste is here: http://paste.lisp.org/display/98512

15:47 mabes: stuartsierra: cool, well now that I know where the whole direction of the clojure testing libs is going I'll start experimenting with lazy-test some more and see if I can provide any useful feedback/patches

15:47 lambdatronic: Any chance anyone has the energy to help me with this?

15:47 stuartsierra: lambdatronic: too much code, can you narrow it down to a specific problem?

15:47 lambdatronic: yes, the specific problem is the output of find-viewpath.

15:47 just that one function.

15:48 it's creating a sequence of vectors ([0 0] [0 1] [0 2])

15:48 stuartsierra: I mean reduce the code to one example that fails

15:48 lambdatronic: The example is that one, stuart. I don't mean for anyone to study the rest. It's purely the find-viewpath function (which stands alone).

15:48 it creates this sequence of vectors, which won't work as lookup keys in the evil-map.

15:49 the evil-map is really just any boring map with vector pairs of integers as its keys.

15:49 I can try to make a smaller example though.

15:49 stuartsierra: So what's the problem?

15:50 lambdatronic: test-me is trying to illustrate it.

15:50 If I have a map (in this case, evil-map) which has vectors of integers as its keys.

15:50 and I try to do a lookup in it using a literal vector, it works.

15:51 if I try to do the lookup like so (map evil-map list-of-vecs), that also works.

15:51 provided a generate the list-of-vecs like so: for [i (range 3) j (range 3)] [i j])

15:51 however...

15:52 when I try the lookup as (map evil-map list-of-vecs) when the list-of-vecs is created by find-viewpath, this fails and returns a sequence of nils.

15:52 so my problem reduces to: why are the vectors from my find-viewpath function any different than those created with (for [i (range 3)

15:52 j (range 3)] [i j]) ???

15:55 stuartsierra: huh

15:55 I don't know.

15:56 they look the same

15:56 lambdatronic: i know. I'm trying to make a smaller test-case.

15:56 just a moment

16:00 hoeck: lambdatronic: maybe it boils down to:

16:00 ,(.equals [1 1] [(long 1) (long 1)])

16:00 clojurebot: false

16:00 lambdatronic: ...@hoeck: brilliant!

16:00 stuartsierra: I had a hunch it might be that, but I couldn't find the differences

16:01 lambdatronic: yeah, I was looking at it every which way too.

16:01 stuartsierra: ah

16:01 Math/round returns a long, not an int

16:01 lambdatronic: the keys are always clojure.lang.PersistentVector both in the map and from find-viewpath.

16:01 and they check out as =

16:01 that's the root of it, then I guess. So hashing on maps isn't using =, I take it.

16:02 stuartsierra: ,(.equals 2 (Math/round 1.5))

16:02 clojurebot: false

16:02 stuartsierra: yes, hashing is required to use .equals instead of Clojure =

16:03 lambdatronic: Well, sob.

16:03 stuartsierra: just coerce the result of Math/round back to Integer with "int"

16:03 lambdatronic: thanks, guys. you just resolved a seriously frustrating problem for me. well maybe. Let me try this fix.

16:04 * lambdatronic runs off to type furiously

16:07 hoeck: had the same problem just recently while parsing a binary file, and I wondered why I didn't find any of the symbols I coded into a hashmap like (get {0xff TYPE_INT, ..} parsed-byte)

16:07 cgrand: btw to "normalize" numbers there is clojure.lang.Numbers/reduce

16:07 lambdatronic: huh. seems like that's it after all. absolutely brilliant work guys.

16:07 cgrand: ,(class (clojure.lang.Numbers/reduce (long 1)))

16:07 clojurebot: java.lang.Integer

16:08 lambdatronic: eh?

16:08 @cgrand by normalize you mean what exactly?

16:09 patrkris: LauJensen: in your example where you define a macro turtle-motion, the macro has a reps parameter - where is that used? (In your latest blog post)

16:10 LauJensen: patrkris: The macro just served to show the train of though which let up to the finaly iterative sotluion, I talk myself out of actually using the macro, but the reps is use in the reduce call

16:10 patrkris: LauJensen: ok, good - just thought I was misunderstanding something

16:15 cemerick: stuartsierra: #79 actually makes 1.1/1.2 cross-compat more difficult, not less

16:15 hoeck: lambdatronic: Numbers/reduce converts a number to its best-fitting datatype

16:15 tcrayford: technomancy: need to test that patch on clojure 1.2 at some point soon

16:15 stuartsierra: cemerick: why?

16:16 cemerick: The various signature and fn name changes still need to be unraveled by any codebase that wants to target both, and choosing which impl to use is still easiest by eagerly loading whereever the new impls are in a try/catch.

16:16 lambdatronic: @hoeck will this always be Integer or Double for clojure types or will it also include BigDecimal, etc?

16:17 stuartsierra: cemerick: I want to discourage people from trying to target both.

16:17 hoeck: lambdatronic: e.g. a long in the range of 2^31 < x <= -2^31 to an int

16:17 cemerick: hrm, so roughly the same difficulty level.

16:17 lambdatronic: ah, gotcha

16:17 cemerick: stuartsierra: I'm with you there, but that's not my call in a variety of projects.

16:17 stuarthalloway: if anybody is bored please test the recent commits to clojure and contrib

16:17 cemerick: (though I'll be lobbying more and more in those venues as the weeks wear on)

16:18 LauJensen: stuarthalloway: Thanks for doing that fantastic screencast on protocols, great job!

16:18 cemerick: Anyway, I'm not arguing against restoring the old namespaces, just pointing out that doing so doesn't impact 1.1/1.2 compat.

16:18 stuartsierra: It's my fault: by making breaking changes in 1.2 , people started trying to support both with conditional loads.

16:18 stuarthalloway: LauJensen: glad you liked it

16:18 stuartsierra: That is not sustainable or even sane.

16:19 stuarthalloway: while you guys are discussing 1.2 breakage I just broke contrib :-)

16:19 stuartsierra: heh

16:19 oh well

16:19 at least it wasn't me this time :)

16:19 stuarthalloway: and we aren't planning on turning back from it, but I would welcome review of the changes

16:19 cemerick: stuartsierra: Perhaps not sane, but it works. *shrug* Anyway, I don't think the breaking changes were a bad move.

16:20 patrkris: stuarthalloway: will you be doing more videos on deftype, defrecord and reify?

16:20 kotarak: stuarthalloway: bug in reductions (f) should be (list (f)) or [(f)], mailed Rich already. The patch in Assembla is correct, however it's against contrib.

16:20 wlangstroth: stuarthalloway: ditto about the screencast - well done

16:20 chouser: stuarthalloway: my only complaint about your screencast is the title. I would have watched it sooner if I had known it was the best available description of the expression problem. :-)

16:21 stuarthalloway: chouser: clearly I suck at titles. BTW love the title for your book

16:21 kotarak: hopefully Rich is on it

16:21 patrkis: dunno yet, time constraints :-)

16:22 chouser: heh. thanks. The machinations that finally led to it were amazingly painful.

16:22 stuartsierra: cemerick: conditional loads should still work, by the way, as long as you try the newer version first.

16:22 cemerick: stuartsierra: right, yes. That's why I backed away from my "makes things harder" assertion.

16:23 stuartsierra: ah, I see. OK.

16:23 cemerick: Though if someone didn't think about it too much, and eagerly loaded duck-streams, and then falling back to 1.2 stuff.... :-/

16:24 stuartsierra: Well, then their code will break on 1.3. :)

16:24 But hopefully by then we'll have succeeded in abolishing contrib altogether.

16:24 cemerick: right, I was suggesting that in that scenario, they might actually prefer 1.2 stuff, but not think about the fact that duck-streams might reappear in 1.2.

16:25 Anyway, it's all water under the bridge now. :-)

16:25 stuartsierra: yep

16:25 cemerick: I will henceforth lobby for contrib namespaces to be timestamped monthly, so as to prevent people from thinking it's a standard library. :-P

16:25 stuartsierra: heh

16:25 chouser: stuarthalloway: you might consider putting those contrib fns back in contrib with deprecation notices, instead of the breaking changes.

16:26 cemerick: clojure.contrib.error-kit201026

16:26 stuarthalloway: considering, but not doing it yet

16:26 how can I have the fns in with colliding names? You won't get far enough to have a deprecation notice

16:27 cemerick: for those concerned about 1.2-SNAPSHOT compatibility?

16:27 chouser: hm.

16:27 * cemerick grumbles and walks over to the sidebar

16:27 technomancy: cemerick: the other option is to spin libs out of contrib into independent any-clojure-version-works libraries: http://clojars.org/clj-io

16:27 sexpbot: "clj-io | Clojars"

16:27 stuarthalloway: note today's problem applies only to seq fns promoted to core

16:27 stuartsierra: technomancy: that's the way forward for sure

16:28 chouser: hm, for explicit :use :only cases, right. bleh.

16:28 stuarthalloway: everything else will be promoted to its own namespaces

16:28 cemerick: technomancy: Yeah, I think that's the side of things I came down on some months ago when there was a discussion about the charter of contrib.

16:28 technomancy: makes more sense for things that aren't destined for promotion clojure itself, but it neatly sidesteps a lot of pain

16:28 stuarthalloway: spinning things out makes it too easy to ruin provenance

16:29 reducing likelihood of ever being promoted to clojure

16:29 cemerick: There's a lot of stuff in contrib that is barely touched, and likely never heading into core, though.

16:29 * technomancy glances at c.c.logging

16:29 stuartsierra: probably 9/10 of it

16:29 cemerick: technomancy: not a fan?

16:30 chouser: the likelihood of error-kit ever being promoted is already zero

16:30 technomancy: cemerick: no, we use it and it's decent

16:30 cemerick: I just wish it were an independent library so it could introduce breaking changes in a 2.0 release

16:30 cemerick: ah, right

16:31 tcrayford: the monad stuff in contrib could probably be a separate library as well

16:31 technomancy: stuarthalloway: is there still a plan for "clojure.lib"? or has it just been boiled down to "get io and some other fns into clojure itself"?

16:31 stuarthalloway: technomancy: there are assembla tix for it

16:32 nothing called lib

16:32 the io stuff goes to clojure.java.io

16:32 stuartsierra: not clojure.io?

16:32 technomancy: ok cool; that's what I thought

16:32 cemerick: that's surprising

16:32 stuarthalloway: stuartsierra: no, the io fns are very host-y

16:32 stuartsierra: that makes sense

16:32 stuarthalloway: cemerick: antecedent?

16:41 rhickey: keep - non-nil or truthy?

16:43 vote now or forever hold your peace

16:44 chouser: ooh, if I vote now I can whine later?

16:44 rhickey: erm, probably not

16:45 stuartsierra: I don't understand the question

16:45 rhickey: I'm inclined towards non-nil

16:45 chouser: my first thought was truthy, so it's like 'if'

16:45 rhickey: stuartsierra: keep is like filter except instead of returning x when (pred x) is true, it returns (pred x)

16:46 chouser: but non-nil means you can always use it and filter further if you *really* want to remove falses, which would surely be rare.

16:46 technomancy: filter considers truthiness, so if we're going to say keep is like filter, it should probably be the same.

16:47 rhickey: I think it will often be used with when, and to select e.g. settings that exist, such setting might be false

16:47 chouser: (filter (complement nil?) ...) vs. (filter identity ...)

16:47 stuartsierra: ok

16:47 I like non-nil then

16:47 rhickey: technomancy: we won;t necessarily say it is like filter if it isn't, most important to make it useful first

16:48 chouser: it's still like filter, just the pred changes, right?

16:48 I mean, the specific predicate is in question

16:48 rhickey: no, the predicate is user supplied, this is about the interpretation of its result

16:48 chouser: (filter (complement nil?) (map f coll))

16:49 f is user-supplied

16:49 rhickey: (remove nil? (map f coll))

16:49 technomancy: it's also a lot like "some", but without stopping at the first

16:49 rhickey: but more efficient

16:49 technomancy: yes, exactly

16:49 chouser: oh, sorry -- it was take-while I was using today that had no complement.

16:50 so yes, I think remove nil? is best, though the docs should be a bit loud about it not being a normal truthy check.

16:50 technomancy: I can't think of any other core seq fns work by way of non-nil rather than truthiness. are there others?

16:51 rhickey: technomancy: I wish some worked non-nil often

16:52 AWizzArd: rhickey: do you have an example for that?

16:52 rhickey: but when you are using keep you really care about the values, only sometimes with some

16:52 technomancy: as long as the docs are extra-explicit, it could work.

16:52 slyphon: is there a mechanism through which one can "extend" a multifn? i'm specifically trying to tweak some of the behavior of clojure.test/report

16:52 (without having to cut/paste)

16:53 amatos: How can I access a enum constant defined inside a Java class? I have a enum called Type inside a class called TradePeriod. I am trying to use TradePeriod.Trade.IN_SAMPLE. TradePeriod/Type/IN_SAMPLE doesn't work, neither does TradePeriod$Type/IN_SAMPLE.

16:53 stuartsierra: slyphon: defmethod clojure.test/report should work...

16:54 LauJensen: rhickey: My vote is on non-nil

16:55 slyphon: stuartsierra: yeah, but then there's no way to "super" ?

16:55 * slyphon likes non-nil?

16:55 stuartsierra: slyphon: multimethods have no "super"

16:55 slyphon: yes, i know

16:55 i mean conceptually

16:55 chouser: it'd be interesting to relegate 'false' to strictly interop situations, that is no core functions return it.

16:56 slyphon: if it were a regular var i'd bind over it

16:56 hrm, that wouldn't work either

16:56 blah!

16:56 technomancy: I'm just not used to ever thinking about the difference between false and nil.

16:57 there are a lot of functions for which I don't even know which they return

16:57 slyphon: technomancy: i've used it in the past to indicate "no action"

16:58 when changing global state

16:58 LauJensen: technomancy: we could unify false and nil in a new var 'faljure'

16:58 replaca: technomancy: and while we're at it, let's rename true to t. Then the lisper in me will be at peace :-).

16:58 slyphon: "call start: nil" "you already called start on this: false"

16:58 * chouser laughs

16:59 pjstadig: lein doesn't reject at the var level...yet

16:59 replaca: (I'm only sort of kidding...)

16:59 stuartsierra: replaca: the earliest pre-1.0 versions of Clojure used t/nil instead of true/false/nil

16:59 technomancy: LauJensen: great idea!

16:59 stuartsierra: But t/nil was confusing for Java interop.

17:00 replaca: stuartsierra: This is how McCarthy made the world and thus it was meant to be!

17:00 stuartsierra: http://globalnerdy.com/wordpress/wp-content/uploads/2007/10/john_mccarthy_successories_poster.jpg

17:00 slyphon: replaca: "a foolish consistency..." though

17:01 then again, fuck knuth

17:01 LauJensen: slyphon: You should watch your language

17:01 replaca: What I love about it is that the symbols are so short

17:01 slyphon: LauJensen: sorry

17:02 LauJensen: np

17:02 technomancy: if Knuth were here, he'd wash your mouth with soap

17:03 slyphon: technomancy: :D

17:03 rhickey: keep - "Returns a lazy sequence of the non-nil results of (f item)"

17:03 slyphon: i was only being pejorative

17:03 ooh

17:03 rhickey: that's nice

17:04 stuartsierra: rhickey: so 'keep' is like (remove nil? (map f coll)) ?

17:04 chouser: + "Note, this means false return values from (f item) will be included."

17:04 LauJensen: stuartsierra: but where does 'like' start and stop ?

17:05 rhickey: stuartsierra: yes, but more efficient. Also coming: keep-indexed (and map-indexed)

17:05 stuartsierra: ok

17:05 * chouser is already using 'keep'

17:05 LauJensen: keep - "Returns a lazy sequence of the non-nil results of (f item), no faljures"

17:06 slyphon: stuartsierra: if i bind over a multifn with my own version, is there a way of keeping a reference to the original so that i can call it?

17:06 wlangstroth: LauJensen: You should watch your languaje

17:07 slyphon: wow, i can't believe he called me on the f-word

17:07 wlangstroth: slyphon: the f-bomb is reserved for heavy debugging

17:07 * slyphon laughs

17:07 technomancy: wlangstroth: I prefer "reserved for legacy JVM interop"

17:09 stuartsierra: slyphon: sure, just def a reference to it

17:09 like (def old-report clojure.test/report)

17:09 slyphon: mm'kay

17:09 oh, that makes sense

17:10 wlangstroth: technomancy: oh man. That phrase is way worse than swearing.

17:11 slyphon: stuartsierra: in theory, then, if i (binding [test/report my-report]), have that old-report def, and define (defmethod my-report :default [m] (old-report m)), any method cases i don't explicitly define should fall through to the original?

17:11 rhickey: chouser: you have a homemade keep?

17:12 or just prepping for the push?

17:12 stuartsierra: slyphon: yes

17:12 slyphon: ok, cool :)

17:12 ty

17:12 stuartsierra: np

17:12 slyphon: stuartsierra: that's what i kind of meant by "super"

17:16 chouser: rhickey: I have a homemade keep as of 15 minutes ago.

17:16 rhickey: chouser: chunk-aware?

17:16 chouser: I was staring at code that could use it, so I'm using it.

17:16 no.

17:16 looking forward to your efficient version.

17:17 wlangstroth: no pressure

17:20 rhickey: tuned up into, added map-indexed, keep, keep-indexed

17:22 AWizzArd: oh good :)

17:23 wlangstroth: the crowd applauds

17:39 hamza: gents, any way to get prev item used in a map operation i need to calculate some delta values?

17:40 technomancy: hamza: if it's a vector you could use the brand-new map-indexed function

17:40 raek: you could use partition with some step

17:41 kotarak: ,(partition 2 1 [1 2 3 4 5 6])

17:41 clojurebot: ((1 2) (2 3) (3 4) (4 5) (5 6))

17:41 hamza: ,(doc map-indexed)

17:41 clojurebot: Excuse me?

17:41 kotarak: hamza: map-indexed is ca. 10 minutes old

17:44 hamza: hehe thanks both technomancy, kotarak. partition worked will check out map-indexed.

17:44 AWizzArd: hamza: http://github.com/richhickey/clojure/commit/9b78d483959e912a2ef77ff649b893b035144549

17:45 There you can see the doc strings.

17:53 technomancy: clojurebot: ticket #20

17:53 clojurebot: {:url http://tinyurl.com/3yrgpwo, :summary "GC Issue 16: Pretty printing", :status :new, :priority :normal, :created-on "2009-06-17T11:58:37-07:00"}

17:54 * technomancy wonders if that's going to be promoted at some point in the future

18:08 The-Kenny: huh, that would be nice

18:10 slyphon: hrm, is it possible to start a repl from the repl?

18:10 Chousuke: probably,

18:10 slyphon: (with-some-kind-of-state* (fn [] start-a-repl-in-here))

18:11 er

18:11 yeah, but with the correct syntax and stuff

18:11 ;)

18:11 * slyphon is thinking like how in irb you can call 'irb' to get a sub-shell

18:12 slyphon: oooh

18:12 repl-in

18:17 cemerick: so the equivalent of indexed is (map-indexed #(vec %&) some-seq)?

18:18 slyphon: well, that certainly doesn't work in slime!

18:18 * slyphon sighs

18:18 replaca: sometime folks complain about regular expression strings, other times they complain about CL format strings. But how about a mixture:

18:18 (GET (re-pattern (cl-format nil "/~@[~a/?~]" prefix)) (home-page prefix))

18:19 slyphon: and on *that* note

18:19 * slyphon takes a break

18:20 AWizzArd: cemerick: hmm yes, looks good

18:20 cemerick: You probably want #(vector % %2) if you care about the cost of gathering rest args, but...

18:21 replaca: technomancy|away: Yes, pprint is going into 1.2 - decided today

18:21 cemerick: That's some micro-optimization there...

18:21 technomancy: replaca: wow, nice.

18:21 * replaca doesn't get to sleep for the next few days :-)

18:22 technomancy: for the greater good

18:22 replaca: indeed

18:24 technomancy: wow, that really whittles down the amount of contrib usage for us.

18:24 especially if logging is spun off.

18:29 The-Kenny: Can someone show me a correct combination of clojure, contrib and swank-clojure for use with clojure 1.2-master-SNAPSHOT?

18:30 My current project.clj fails with java.lang.IllegalStateException: Var swank.swank/start-server is unbound (using M-x swank-clojure-project)

18:31 http://gist.github.com/382829 That's my project.clj

18:35 technomancy: The-Kenny: drop "-master" from contrib

18:36 The-Kenny: technomancy: I think I've tried that, but I'll try again

18:36 No, not working :(

18:38 technomancy: weird; works for me

18:39 The-Kenny: Was there some important change to swank-clojure.el? Maybe mine is outdated

18:40 technomancy: recent changes have been mostly about edge-cases

18:40 could try lein swank tho

18:45 The-Kenny: Fails too :( "group-by already refers to bla"

18:45 Looks like someone out there don't want me to use clojure 1.2

18:46 technomancy: oh... that's new breakage as of like an hour ago; cripes.

18:47 The-Kenny: hm :(

18:48 Chousuke: errors like these are just teaching people to avoid :use :P

18:49 lancepantz: anyone know if read-properties can be used to load a properties file as a classpath resource instead of a path?

19:14 * raek just discovered http://github.com/technomancy/leiningen/commit/39732d5b649dedb70b14e88fe561dfc9ddb31611

19:17 AWizzArd: ,(doc add-classpath)

19:17 clojurebot: "([url]); DEPRECATED Adds the url (String or URL object) to the classpath per URLClassLoader.addURL"

19:17 livingston: having your build tool forbid names doesn't seem like the greatest of ideas? unless there is a technical reason this is just kinda silly

19:27 technomancy: what's wrong with silly?

19:27 slyphon: technomancy: stop that! it's silly!

19:28 * slyphon adjusts his cap and puts his riding crop under his arm

19:30 rhudson: Is Leiningen really going to abjure -jure?

19:32 lancepantz: hahahah, i thought he was just kidding about that

19:46 stuarthalloway: technomancy: collision with group-by is killing swank

19:46 are the semantics the same? can it be simply removed from swank.util?

19:46 technomancy: stuarthalloway: I am one step (about 15 minutes) ahead of you. =)

19:47 stuarthalloway: awesome!

19:47 technomancy: my fix loads it conditionally; the semantics are the same (just no transients in swank's version)

19:47 or rather, the only difference in semantics was an optional argument that was only used in the test suite

19:47 (don't look at me; I didn't write it) =)

19:47 stuarthalloway: is the a leiningen way to say "give me the snapshot as of date d" so people can back off the edge?

19:48 s/the/there

19:48 technomancy: yeah, you just replace SNAPSHOT with the timestamp of the build

19:48 it should probably be better-documented though

19:49 slyphon: technomancy: do you know if it's possible, or if someone has written, something like repl-ln that works over swank?

19:49 so you can spawn a sub-repl in a certain context

19:49 stuarthalloway: we need to encourage people to track to a timestamp, or at least make sure they know how

19:50 technomancy: slyphon: the swank.core/break debug repl is basically that; you can ask hugod how that works

19:50 stuarthalloway: a doc fix plus an email or blog post on "paddling back from the edge" would be most welcom

19:50 slyphon: technomancy: w00t!

19:50 technomancy: stuarthalloway: will definitely include that in the readme for the next lein release

19:51 liebke: technomancy: what would be an example using the timestamp for the previous snapshot of Clojure?

19:52 technomancy: liebke: at work we're using version "1.2.0-master-20100426.160114-46"

19:52 liebke: I just emailed the group about the swank problem, I definitely need to go back a snapshot

19:52 thanks!

19:52 technomancy: it's a little more complicated than timestamps I guess; it includes the hudson build number

19:53 liebke: what about clojure-contrib?

19:53 is it the same?

19:53 * dnolen is just now in the past couple of days is realizing what hudson is, and is happy that it exists

19:54 technomancy: liebke: for contrib: "1.2.0-20100427.200505-82"

19:54 liebke: excellent, thanks

19:55 technomancy: posted to the mailing list with the magic numbers

19:56 slyphon: technomancy: for the record: C

19:57 C

19:57 J

19:57 GAH

19:57 http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml

19:57 sexpbot: "Hugo Duncan : Swank Clojure gets a Break with the Local Environment"

19:57 slyphon: stupid paste

19:58 technomancy: oh, I thought you wanted details on how it's implemented

19:59 slyphon: technomancy: hah, no, i just want the feature :)

19:59 technomancy: oh yeah, it's the best

19:59 slyphon: :D

19:59 i've been *wanting* that for a while

20:00 esp. since i have a whole ton of (with-blah-context* ) methods

20:28 unlink: Has anyone released a reader for Clojure that implements sweet expressions?

20:52 cemerick: unlink: oh, I'd hope not

20:53 somnium: it looks like even the PLT mailing list was slightly hostile to them :p, not sure how you'd implement { ~infix } in clojure either

20:53 {{ x + y + z }} is kinda salty

20:55 cemerick: it seems like a complete waste to me *shrug*

20:56 _ato: I think there was one a long time ago, sweetjure or something like that, but it didn't get much interest and now seems to have disppeared

20:56 cemerick: I think the influx of people willing to use clojure from java-land is at least encroaching on voiding their premise

20:56 somnium: it feels like a half-measure to me, if you really want syntax, why not write a preprocessor and feed it to the reader

20:58 I like the syntax of haskell and ocaml, but template haskell and camlp4 are terrifying

20:59 unlink: somnium: the infix part is of dubious utility

21:00 somnium: http://github.com/apatil/pleajure

21:03 _ato: ah yep, that's the one I was thinking of

21:04 currivan: Question about type hints: I can use #^Lbyte in a defn binding but I can't get it to work in let (error) or binding (still have reflection warning). Anyone know why?

21:18 slyphon: anyone use swank.core/break ?

21:18 * slyphon can't get access to the locals

21:30 tomoj: is a quick recovery from what happened to 1.2 impossible in general?

21:32 * currivan

21:58 _brian2_: noob question, why the first item returned from lazy seq by (first.. ) is not the same as I see when I use doseq? : http://clojure.pastebin.com/SasLCeBF

22:00 slyphon: doseq doesn't keep the head of the seq?

22:01 hrm

22:01 _brian2_: don't know , thats what I get

22:01 slyphon: depends on what (hn-body) is

22:02 _brian2_: all lazy seq's aren't equal?

22:02 slyphon: nope

22:02 a lazy-seq could be bytes coming out of a socket

22:03 _brian2_: ok

22:03 so what (first .. considers to be first is not what doseq does

22:05 slyphon: well

22:05 actually, i'm gonna stop talking, because i'm kinda new to this

22:05 ;)

22:05 _brian2_: ok, lol

22:06 tomoj: _brian2_: I think what you want is (doseq [v (hn-body)] ...)

22:06 _brian2_: ok

22:07 thnks

22:07 tomoj: the issue you're seeing is interesting

22:07 want to know why you see that output?

22:07 _brian2_: yes

22:07 tomoj: do you know about destructuring yet?

22:07 _brian2_: a bit

22:08 tomoj: ,(let [[a b c] (iterate inc 1)] [a b c])

22:08 clojurebot: [1 2 3]

22:08 tomoj: if you have a vector in a binding form, this means that you expect a seq to be bound to it, and the symbols you put into the vector will be bound to elements in that seq

22:09 _brian2_: i'm gonna copy this and think about it

22:09 tomoj: ,(let [[x] "foo"] x)

22:09 clojurebot: \f

22:09 tomoj: ,(let [[x y z] "foo"] [x y z])

22:09 clojurebot: [\f \o \o]

22:09 tomoj: the repeated newlines you're seeing is because each time through the doseq, v is bound to the first character of each string

22:10 _brian2_: hmm

22:10 tomoj: and they all start with newlines

22:10 _brian2_: ok, and then [space]

22:10 tomoj: ,(doseq [x ["foo" "bar" "baz"]] (println x))

22:10 clojurebot: foo bar baz

22:11 slyphon: hrm

22:12 tomoj: ,(doseq [[x y z] ["foo" "bar" "baz"]] (println [x y z]))

22:12 clojurebot: [f o o] [b a r] [b a z]

22:12 tomoj: ,(for [[x] ["foo" "bar" "baz"]] x)

22:12 clojurebot: (\f \b \b)

22:12 _brian2_: actually I would have thought one variable "v", then it would not destructure, but obviousl I am wrong

22:13 tomoj: with just the symbol v, it doesn't destructure

22:13 but when you have a vector or map, you get destructuring

22:13 _brian2_: but what about my output

22:13 tomoj: you have a vector

22:13 you've got (doseq [[v] (hn-body)] (prn v))

22:13 what you want is (doseq [v (hn-body)] (prn v)), no vector in the binding form

22:14 _brian2_: ahh

22:14 tomoj: when the vector has fewer elements in it than the number of elements in the thing bound to it, the rest are just ignored

22:14 so v is bound to the first element of each string

22:14 and the seq for a string is a seq of characters

22:14 _brian2_: hmm, ok

22:15 tomoj: ,(seq "\n blah")

22:15 clojurebot: (\newline \space \b \l \a \h)

22:15 _brian2_: yes ok, that clarifys it much for me

22:15 clarify

22:16 thanks!

22:18 actually I think I was confused because these [] is also used as arguments for functions.

22:18 tomoj: right

22:18 _brian2_: but not when calling

22:19 tomoj: I guess this is somewhat like learning the syntax of clojure :(

22:19 ,(doc doseq)

22:19 clojurebot: "([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."

22:19 _brian2_: yes

22:19 tomoj: at least the syntax is consistent

22:20 let, for, doseq, and others all use the same syntax here

22:20 _brian2_: what do they mean b "head of sequence" ?

22:20 the first element

22:20 ?

22:20 tomoj: yeah, the head is the first element

22:20 what that means is that doseq will allow that element to be garbage collected

22:21 _brian2_: hmm

22:21 tomoj: if you write code which keeps a reference to the first element of a lazy seq, it "holds the head", and this means that the entire seq will be stored in memory

22:21 _brian2_: ok

22:21 tomoj: if you don't hold the head, you can traverse an infinite seq as long as you like without running out of memory

22:21 _brian2_: yes, hmm important point

22:21 tomoj: so for instance a clojure program could (doseq [i (iterate inc 0)] (println i))

22:22 and it would just sit there printing out the natural numbers practically forever

22:22 _brian2_: yes, this is very important to my application

22:24 it seems only particular cases you would not want to use it

22:33 chouser: aaargh!

22:33 slyphon: chouser: sup?

22:33 chouser: remember: *don't* fry bacon naked

22:33 chouser: I've been getting bit 3 evenings in a row now by (I think) the same problem, and it's something I *knew* but was somehow overlooking

22:34 slyphon: doh

22:34 chouser: the comparator you give to sorted-set-by controls not just order, but the set's concept of uniqueness.

22:34 slyphon: ah

22:34 interesting

22:35 chouser: ,(sorted-set-by #(compare (:a %1) (:a %2)) {:a 2 :b 1} {:a 1 :b 2} {:a 2 :c 3})

22:35 clojurebot: #{{:a 1, :b 2} {:a 2, :b 1}}

22:35 chouser: I mean, it has to. It's the only thing that makes sense from the set's perspective.

22:36 I probably made fun of the person who last complained about it to me.

22:36 slyphon: :)

22:36 chouser: ,(sorted-set-by #(compare [(:a %1) %1] [(:a %2) %2]) {:a 2 :b 1} {:a 1 :b 2} {:a 2 :c 3})

22:36 clojurebot: java.lang.RuntimeException: java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Comparable

22:37 slyphon: that's different than ruby & python

22:37 chouser: hm, interesting.

22:38 slyphon: heh, that's like today, i was going *nuts* trying to figure out some weird JMS behavior, turns out you have to explicitly call "start" on your connectoin

22:38 connection

22:38 (which i *knew*, dammit)

22:38 rhudson: ,(sorted-set-by #(first [0 %1 %2]) :a :b :c :d :e)

22:38 clojurebot: #{:a}

22:39 chouser: ,(sorted-set-by #(compare [(:a %1) 0] [(:a %2) 1]) {:a 2 :b 1} {:a 1 :b 2} {:a 2 :c 3})

22:39 clojurebot: #{{:a 1, :b 2} {:a 2, :c 3} {:a 2, :b 1}}

22:39 chouser: hm...

22:39 ,(sorted-set-by #(compare [(:a %1) 0] [(:a %2) 1]) {:a 2 :b 1} {:a 1 :b 2} {:a 2 :c 3} {:a 2 :c 3})

22:39 clojurebot: #{{:a 1, :b 2} {:a 2, :c 3} {:a 2, :c 3} {:a 2, :b 1}}

22:40 chouser: fascinating. this might work just fine in my case.

22:40 I don't need the set for removing duplicates

22:40 slyphon: is a lazy-seq kind of like a monad if you're wrapping something like a socket?

22:41 i.e. representing a stream of IO as a seq of values

22:42 i hear people discuss "monadic IO" but i haven't had the time to learn haskell yet

22:44 tomoj: I don't see the lazy-seq <=> monad connection there

22:44 I'd think in haskell you'd have an IO [a] to represent the stream of values coming out of a socket

22:44 slyphon: how is that different from a seq?

22:45 tomoj: a seq is just an [a]

22:45 slyphon: IO is the class, no?

22:46 tomoj: if you have an IO [a], you can get from it an [a]

22:46 then you just process the [a] like you would a lazy-seq

22:47 the lazy seq actually has the mechanisms for doing more IO contained inside it

22:47 I am still confused by haskell so don't trust me

22:47 slyphon: hahahaha

22:48 chouser: ha! ok, don't do my always-unique thing above

22:48 if your comparator never returns 0, you can never find or remove anything in your set.

22:48 duh

22:50 rhudson: So the comparator for a sorted set has to define a total ordering, sounds like

23:01 chouser: are you trying to define a priority queue?

23:05 chouser: yessir

23:05 it was working fine until I moved from vectors to records

23:15 I'm going crazy

23:15 ((.comparator wd) (first wd) (first wd)) ;=> 0

23:16 (wd (first wd)) ;=> nil

23:16 I don't see how a set can do that.

23:16 unlink: What is the idiomatic way to write to stderr?

23:17 slyphon: (binding [*out* *err*] ...)

23:17 i think

23:17 unlink: (binding [*out* *err*] (println blah)) ?

23:17 oh, :(

23:17 slyphon: someone will correct me, though

23:17 well

23:17 you can wrap that in a macro

23:17 unlink: I mean I understand

23:17 slyphon: yeah, i also though that was kind of "meh"

23:18 rhickey: chouser: what is wd?

23:18 rhudson: chouser: what's wd?

23:18 chouser: sorted-set-by

23:18 I just spotted it

23:19 my sort-by fn is (defn work-order [a b] (cond (= a b) 0 (< (:cost-est a) (:cost-est b)) -1 :else 1))

23:19 the problem is that if a bunch of items have the same :cost-est, the two equal ones might not end up next to each other

23:20 so simply guaranteeing that it returns 0 for equal items isn't sufficient. it must *always* put things in the same order.

23:22 rhudson: sounds right

23:23 chouser: so to get the behaviour I want I have to take into account every field of the record

23:24 I mean, I have to actually *order* on every field, not just check equality.

23:24 hiredman: or order on :cost-est then hashcode

23:24 chouser: perhaps I'd be better off implementing Comparable in the record itself

23:24 rhudson: If you had a serial # / index on each record, you could sort by [(:cost x) (:serial x)]

23:25 chouser: hiredman: I thought of that, but I could get incorrect 0's if the hashcodes happend to be different

23:25 and items would mysteriously disappear

23:25 hiredman: chouser: uh, for immutable objects?

23:26 oh

23:26 right

23:26 sorted-sets

23:26 what a pain

23:27 chouser: ugh. Actually, I'd be better off just using a vector

23:27 hiredman: :)

23:27 rhudson: Unless one of the elments in the vector was a map, then you'd have the same incomparability problem

23:28 hiredman: huh?

23:29 rhudson: Maps aren't Comparable

23:29 chouser: right. it's not. I have a number and a 2-element vector of numbers.

23:30 unlink: Is there any datetime convenience code for clojure

23:30 my use case is printing out a string of the form "2010-04-29 03:30:44.950063"

23:31 hiredman: clojurebot: javadoc java.text.DateFormater

23:31 nuts

23:31 what is that thing called

23:31 unlink: SimpleDateFormatter?

23:32 * SimpleDateFormat

23:32 hiredman: sure

23:32 that'll do

23:32 rhudson: That's what I always use

23:32 unlink: OK. I'm just asking because that is a horrible class O:-)

23:32 hiredman: right

23:32 well

23:32 right

23:33 rhudson: format's something like "yyyy-MM-dd hh:mm:ss.SSS"

23:35 replaca: unlink: my advice is skip java dates and pick up jodatime. It's still pretty nasty but at least it makes sense

23:37 unlink: this is inspiring

23:37 * slyphon seconds

23:38 unlink: in a bad way, I mean

23:38 slyphon: unlink: it's java, it's not supposed to be inspiring

23:38 it's supposed to be hackable by your replacement who you will undoubtedly train

23:38 unlink: as in, inspiring me to write something for clojure

23:38 slyphon: hah

23:40 chouser: I think there's a clojure wrapper around jodatime somewhere.

23:40 slyphon: you know, come to think, i think the problem with most date/time libs is that time is a *terrible* abstraction

23:42 unlink: well it's a nasty concept

23:42 and calendars are inherently tricky

23:42 slyphon: eyah

23:43 rhudson: At least there's options beyond "Wed Apr 28 23:42:28 EDT 2010" these days -- that's gotta be the worst format in the world

23:43 slyphon: "Time is of an affliction" - Frank Zappa

23:44 rhudson: "Without time, everything would happen at once. Without space, everything would happen to me"

23:44 * slyphon laughs

23:44 replaca: chouser: brad cross and technomancy did something for incanter, but even they don't like it. Someone's working on something new over there. I have high hopes

Logging service provided by n01se.net