2010-04-28
| 00:32 | MadWombat | Hello |
| 00:33 | Raynes | Hello. |
| 00: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)))) |
| 00:35 | MadWombat | this somehow seems ugly and non-idiomatic |
| 00:35 | MadWombat | especially ((eval f)) part |
| 00:36 | MadWombat | is this "The Clojure Way" or am I not sufficiently enlightened? |
| 00:37 | technomancy | MadWombat: what about (def fns [f1 f2 f3]) (doseq [f fns] (store-data (f))) ? |
| 00:38 | technomancy | assuming the f1, f2, f3, etc have been def'd when the function calling store-data is compiled |
| 00:46 | MadWombat | technomancy: interesting :) wonder why I started quoting them right away anyway |
| 01:10 | vIkSiT | mmarczyk, you mean "back" into a separate duck-streams ns? |
| 01:10 | cemerick | vIkSiT: right, (:require [clojure.contrib.io :as io]), and then use io/slurp* and io/spit, etc |
| 01:10 | mmarczyk | yes |
| 01:10 | mmarczyk | but you can just use stuff from io, yes |
| 01:10 | cemerick | It's been suggested that it be restored, but deprecated |
| 01:10 | mmarczyk | be wary of changes in behaviour though |
| 01:10 | vIkSiT | ah I see |
| 01:10 | vIkSiT | hmm. |
| 01:11 | mmarczyk | some of the functions act somewhat differently in addition to having been moved to a different ns |
| 01:11 | vIkSiT | i c |
| 01:12 | vIkSiT | well, it looks like Clojure is to languages what Linux has been to OSs :) Its changing so fast! |
| 01:12 | cemerick | the perils of following the bleeding edge :-) |
| 01:12 | vIkSiT | (Not to mention that half the books haven't been written yet :P) |
| 01:12 | cemerick | vIkSiT: you can see the current state of the API here: http://richhickey.github.com/clojure-contrib/index.html |
| 01:13 | cemerick | That shows where the master branch is, and there's a link at the left to get to the 1.1.x release docs. |
| 01: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 |
| 01:14 | mmarczyk | spoiled with the new toys :-) |
| 01:16 | vIkSiT | hehe totally |
| 01:18 | vIkSiT | cemerick, wow, that list is comprehensive! How does one explore all that :) |
| 01:19 | cemerick | slowly, and only as needed :-) |
| 01:25 | vIkSiT | the graph library looks interesting |
| 01:43 | vIkSiT | hmm is line-seq recommended to open files? |
| 01:44 | cemerick | vIkSiT: it takes a reader, but sure |
| 01:44 | vIkSiT | (line-seq (reader "filepath")) for instance. |
| 01:44 | vIkSiT | ah, I was just guessing that since line-seq is lazy - it probably doesn't put everything in memory.. |
| 01:44 | vIkSiT | vs say, slurp |
| 01:45 | cemerick | vIkSiT: io/read-lines is probably better |
| 01:45 | vIkSiT | ah |
| 01:45 | cemerick | note the docs though |
| 01:46 | vIkSiT | cemerick, anything specific there btw? |
| 01: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 |
| 01:46 | defn | stu h's new screencast is awesome |
| 01:46 | cemerick | vIkSiT: regarding? |
| 01:48 | vIkSiT | cemerick, oh, nothing - I thought you were talking about soemething specific in the docs. |
| 01:48 | mmarczyk | (doc clojure.contrib.duck-streams/read-lines) |
| 01:48 | clojurebot | "([f]); Like clojure.core/line-seq but opens f with reader. Automatically closes the reader AFTER YOU CONSUME THE ENTIRE SEQUENCE." |
| 01: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 |
| 01:48 | mmarczyk | see the bit in capital letters |
| 01:48 | mmarczyk | yup |
| 01:49 | mmarczyk | defn: it is, isn't it? :-) |
| 01:49 | vIkSiT | aah, I get mmarczyk's statement now as well, thanks! |
| 02:04 | vIkSiT | oh I always forget to ask - on an emacs slime REPL - whats the best way to break the currently executing program/statement? |
| 02:06 | _ato | vIkSiT: C-c C-b |
| 02:06 | vIkSiT | ah thanks _ato |
| 02:07 | vIkSiT | also, is there a way to "log" a particular REPL session into a file somewhere? |
| 02:07 | _ato | maybe C-x C-w (write-file) and enter a filename |
| 02:08 | _ato | that's a one off saving though, dunno about logging continuously |
| 02:08 | _ato | you can keep hitting save after you've named it I guess :p |
| 02:08 | vIkSiT | hehe |
| 02:09 | vIkSiT | ah that works just fine.. |
| 02:09 | vIkSiT | I just need a log of some stuff |
| 02:37 | vIkSiT | is there a way to create an index for an in memory clojure data structure? |
| 02:37 | vIkSiT | (assuming you have a huge map for instance..) |
| 03:54 | carkh | vIkSiT: a map is already indexed by it's key isn't it ? |
| 03:54 | carkh | its* |
| 04:07 | LauJensen | Morning all |
| 04:07 | esj | and a good morning to you, sir. |
| 04:07 | ordnungswidrig | moin |
| 04:09 | spariev | morning |
| 04:11 | mmarczyk | good morning |
| 04:12 | spariev | isn't memfn deprecated ? |
| 04:13 | Raynes | mmarczyk: I was trying to modify a ref inside a macro inside a macro. |
| 04:14 | spariev | just received a ClojureInAction MEAP update, and found example with memfn in chapter on Java interop |
| 04:15 | Raynes | spariev: memfn existed before #(). |
| 04:15 | Raynes | I don't know why he would use it. |
| 04:17 | mmarczyk | hi Raynes |
| 04:17 | Raynes | Yo. |
| 04: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? |
| 04:18 | mmarczyk | just occurred to me you might be |
| 04: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. |
| 04:19 | Raynes | My macrofoo is quite weak. |
| 04: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 :-) |
| 04:19 | mmarczyk | makes me feel a bit silly now |
| 04: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. :\ |
| 04:19 | clojurebot | multimethods is what separates the boys from the men. |
| 04:20 | Raynes | Indeed. |
| 04:20 | mmarczyk | oh, well, I was thinking of posting an answer to your Q with some thoughts re: this kind of scenario |
| 04:21 | mmarczyk | :-) |
| 04:21 | Raynes | mmarczyk: http://gist.github.com/381865 Is the actual example. |
| 04:21 | mmarczyk | incidentally, I find this surprising: |
| 04:22 | mmarczyk | ,(let [g (gensym)] (= g (symbol (name g)))) |
| 04:22 | clojurebot | true |
| 04:22 | Raynes | That fails. Hard. Since you wanted a more realistic example. :> |
| 04:22 | mmarczyk | not in hindsight, that is |
| 04:22 | mmarczyk | but haven't expected it |
| 04:22 | mmarczyk | Raynes: looking now |
| 04:23 | Raynes | Aye, that (do in defplugin is unnecessary, by the way. |
| 04:23 | Raynes | Just haven't removed it. |
| 04:24 | mmarczyk | you might want to add a comment to your Q to point to that, it makes the idea come across |
| 04:24 | mmarczyk | quite clearly |
| 04:24 | Raynes | I will once I get it less ugly and more of what I expected. |
| 04:25 | Raynes | I also forgot to remove the quote from ~@body in defplugin. |
| 04:25 | Raynes | That was a typo. |
| 04:25 | Raynes | :p |
| 04:25 | Raynes | This would totally work if not for ~@body forcing evaluating of the damned argument list. |
| 04:26 | mmarczyk | hm |
| 04:26 | mmarczyk | ~@ has nothing to do with whether sth is evaluated or not |
| 04:26 | clojurebot | Ik begrijp |
| 04:26 | Raynes | http://gist.github.com/381870 |
| 04:26 | mmarczyk | ouch, sorry, clojurebot |
| 04:27 | Raynes | mmarczyk: I guess that isn't quite what I meant. |
| 04:27 | Raynes | Anyway, the arg list that is being passed to the multimethod from defcommand is being evaluated by something. |
| 04:27 | Raynes | Because it gives me "whatever is not defined" |
| 04:28 | Raynes | I've never really done anything significant with macros before. |
| 04:29 | mmarczyk | I'm trying to fix that atm |
| 04:29 | Raynes | Macros are fun until you realize that you're too dumb to write them. :> |
| 04:30 | Licenser_ | Raynes: my experience: often a function works too |
| 04:30 | Raynes | For context, if anybody is wondering what I'm doing, I'm writing a DSL for plugins in sexpbot. |
| 04:31 | cgrand | Raynes: defplugin's body can only contain defcommand forms? |
| 04:32 | Raynes | cgrand: I've not decided on that yet. |
| 04:32 | Raynes | It depends on whether or not it can contain other things without causing problems. :p |
| 04:32 | Raynes | All that is really necessary in there is defcommand forms. |
| 04:32 | Raynes | Technically, anyway. |
| 04:33 | Raynes | You could put functions and such outside and just drop the defcommands in defplugin. |
| 04:33 | cgrand | then why bother with two separate macros? |
| 04:33 | Raynes | It doesn't really matter either way. |
| 04:33 | Raynes | Because I was trying to go for the put-everything-in-defplugin scheme. |
| 04:34 | Raynes | Because it would look better. |
| 04:34 | Raynes | If that's too much trouble, I'll have to go that route. |
| 04:38 | mmarczyk | have you considered using clojure.contrib.macro-utils/macrolet ? |
| 04:39 | cgrand | put-everything-including-defs-and-defns? |
| 04:39 | mmarczyk | I've almost reimplemented a chunk of that just now, then realised I'd seen it in contrib :-) |
| 04:39 | mmarczyk | (please disregard the nonsensical `almost' in the above) |
| 04:40 | Raynes | cgrand: Indeed. |
| 04:41 | Raynes | Was that moved in contrib master? |
| 04:42 | Raynes | Ah |
| 04:42 | Raynes | macros |
| 04:42 | mmarczyk | http://gist.github.com/381879 |
| 04:42 | mmarczyk | I'm using latest contrib now |
| 04:42 | mmarczyk | so yeah, maybe it was called something different before |
| 04:42 | mmarczyk | the ns, that is |
| 04: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 |
| 04:43 | mmarczyk | the gist is just a rough sketch, btw |
| 04:44 | mmarczyk | http://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/macro_utils.clj |
| 04:44 | Raynes | D'oh. |
| 04:44 | mmarczyk | :-) |
| 04:45 | Raynes | mmarczyk: Oh, that's cool. |
| 04:45 | cgrand | Raynes: alternative DSL designs which don't need two separate macros, https://gist.github.com/19367943286f495c96df |
| 04:45 | Raynes | mmarczyk: I can work with this. |
| 04:46 | Raynes | Thanks, both of you. I like the macrolet option. |
| 04:47 | mmarczyk | cgrand's ideas look good, though -- especially the first one, looks a lot like defprotocol |
| 04:48 | Raynes | I don't think I really understand macros enough to implement either of those idea.s |
| 04:48 | Raynes | ideas* |
| 04:49 | mmarczyk | that could be construed as a reason to try :-) |
| 04:49 | Raynes | Or a construed reason to kill myself. |
| 04:49 | Raynes | I was pretty fond of my original idea. :\ |
| 04:50 | Raynes | I've already been frustrated for about 2 hours. Not sure I can handle another 10. |
| 04:50 | mmarczyk | nothing like a 10-hour-long bug hunting session, I find |
| 04:51 | mmarczyk | 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? ;-) |
| 04:52 | Chousuke | hmhm |
| 04:52 | Chousuke | I think you should try implementing both of cgrand's ideas |
| 04:53 | Raynes | Is the other idea really that bad? |
| 04:54 | mmarczyk | well actually the first defplugin with (cmdkey [args] body...) sections should be the most straightforward too |
| 04:54 | Chousuke | well the worst of it is that it captures the name cmd-list |
| 04:54 | mmarczyk | you could make that (defplugin plugin-name (cmdkey [args] body...)*) |
| 04:54 | Raynes | Capturing cmd-list should never cause any problems. |
| 04:55 | Chousuke | that would be pretty easy. you'd just get the name and a seq of cmdkey specs as parameters |
| 04:55 | mmarczyk | Chousuke: not with the macrolet approach |
| 04:55 | Raynes | And the macrolet approach uses a gynsym. |
| 04:55 | Raynes | gensym* |
| 04:55 | mmarczyk | not to say I don't agree with the general sentiment, which I do |
| 04:56 | Raynes | I need an extra keyboard. |
| 04:56 | Raynes | One I can beat my head against. :> |
| 04:57 | mmarczyk | hm, I seem to have forgotten to include the (let [g (ref [])] ...) bit in the gist, will fix in a sec |
| 04:57 | Chousuke | maybe you're trying too hard :P |
| 04:57 | Chousuke | create a simpler macro first, then expand |
| 04:57 | Raynes | I kind of just wanted this done. Immediately. |
| 04:57 | Raynes | Which is more the problem than anything. |
| 04:58 | mmarczyk | ...fixed (hopefully) |
| 04:58 | Chousuke | Raynes: make a function that takes one of those (cmdkey [args] ...) things and then returns some clojure code |
| 04:59 | Chousuke | then do your macro like `(do whateverstuff ~@(map helper-fn cmdspecs)) |
| 05:00 | cgrand | https://gist.github.com/19367943286f495c96df#L11 |
| 05:00 | Chousuke | that would be a simple way to implement cgrand's first idea. |
| 05:01 | Chousuke | ... or that :) |
| 05:01 | Raynes | Close. |
| 05:02 | Raynes | 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. |
| 05:02 | Raynes | I'm not sure how that would be possible like this. |
| 05:04 | Raynes | Or wait. |
| 05:04 | Raynes | Sorry, had a brainfart there. |
| 05:04 | Raynes | It's all coming back to me. |
| 05:04 | Raynes | :p |
| 05:04 | Chousuke | keep in mind that in principle you're just working with data structures |
| 05:05 | Raynes | Chousuke: I was thinking about it too much. |
| 05:05 | Raynes | It makes sense now. |
| 05:05 | Chousuke | if you design your DSL so that the data structures are easy to modify it'll be easy to implement |
| 05:06 | Raynes | cgrand: I appreciate the head start there. |
| 05:06 | Raynes | cgrand: You might have just taught me macros. :p |
| 05:07 | cgrand | Raynes: great! |
| 05:08 | mmarczyk | :-) |
| 05:12 | cgrand | Raynes: don't look at this solution now then http://gist.github.com/381898 :-) |
| 05:13 | mmarczyk | and a working example of macrolet usage... though for a different purpose (which is ridiculous): http://gist.github.com/381904 |
| 05:26 | Raynes | cgrand: Out outcomes ended up being quite similar. I just stole your clever trick to get rid of the ref. |
| 05:26 | Raynes | cgrand: It's still tossing me that "whatever is not defined" stuff though. |
| 05:27 | cgrand | Raynes: can you paste your test? |
| 05:27 | Raynes | cgrand: Also, why is that `(do ..) before the ~@(for ..) important? |
| 05:28 | Raynes | cgrand: http://gist.github.com/381923 |
| 05:28 | Raynes | "irc is not defined" |
| 05:28 | Raynes | I assume it's trying to evaluate the stuff in the argument vector. |
| 05:28 | cgrand | because a macro returns only one form, so you have to group the defmethods and the dosync into a do |
| 05:29 | Raynes | cgrand: Oh, alright. |
| 05:29 | stilkov_ | Is there a page somewhere that lists the performance guarantees for the various different collections? |
| 05:29 | stilkov_ | http://clojure.org/data_structures only mentions them for some functions |
| 05:31 | Chousuke | hmm |
| 05:31 | Chousuke | a table would be easy to make |
| 05:31 | Chousuke | too bad I don't have a blog or anything to publish one :P |
| 05:35 | cgrand | Raynes: I can't reproduce your bug |
| 05:35 | Raynes | http://gist.github.com/381936 Is there anything wrong with my version? |
| 05:35 | stilkov_ | Chousuke: I can offer a a blog that would be happy to host this :-) |
| 05:40 | Raynes | cgrand: I think I had some screwed up parens. |
| 05:41 | cgrand | Raynes: I guess beacuse your own version works as well as mine |
| 05:41 | jwr7 | deftrace does not support functions with docstrings (as I've just discovered) |
| 05: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. ;) |
| 05:43 | Raynes | mmarczyk, Chousuke: Thanks to you guys as well. <3 |
| 05:48 | Raynes | Now the fun part. |
| 05:48 | Raynes | Converting some 30 plugins to use the new DSL. |
| 05:49 | lancepantz | can i use read-properties to read a properties file from the classpath instead of a specific file? |
| 05:50 | Chousuke | I wonder if conj to a vector is log32 or constant time |
| 05:57 | Chousuke | Anyone spot mistakes in this? It's all from memory and docstrings. www.gensoukyou.net/datas.html |
| 05:57 | sexpbot | "datas" |
| 06:03 | wooby | 'morning all |
| 06:07 | Chousuke | I wonder about the queue performance guarantees though :/ |
| 06:08 | Chousuke | too bad rhickey isn't here :P |
| 06:10 | Chousuke | (don't tweet that url or anything, I make no guarantees of persisting stuff on my home server) |
| 06:11 | LauJensen | Chousuke: So accept stilkov's offer? |
| 06:12 | Chousuke | only after I get someone to agree with me on the veracity of that data |
| 06:16 | cgrand | Chousuke: conj on Queue is O(log32 n) (the tail of a queue is a vector) |
| 06:16 | cgrand | pop is O(1) for vectors |
| 06:17 | cgrand | err no |
| 06:17 | spariev | according to Chapter 5 of JoC, count on vectors is "essentially constant time", which means O(log32 n) |
| 06:18 | Chousuke | hmm, so they don't store a count value? |
| 06:18 | cgrand | pop is O(log32 n) |
| 06:19 | spariev | oh, sorry, my bad, it's o(1) |
| 06:19 | spariev | misreading on my part |
| 06:19 | Chousuke | yeah, I just checked the source |
| 06:31 | Chousuke | I guess the table is okay now. |
| 06:41 | Raynes | rhickey: Morning. |
| 06:41 | rhickey | hey |
| 06: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? |
| 06:58 | sexpbot | "datas" |
| 07: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 |
| 07:03 | rhickey | conj and pop on vectors are O(1) |
| 07:04 | Chousuke | I suppose assoc doesn't work for sets either. I should probably note that somehow |
| 07:06 | rhickey | conj on queue is also O(1) |
| 07:08 | AWizzArd | rhickey: subvec also O(1) yes? |
| 07:10 | Chousuke | I suppose I'll just change the time guarantees constant, near-constant and logarithmic with explanations |
| 07:11 | Chousuke | and linear |
| 07:13 | rhickey | AWizzArd: yes |
| 07:14 | AWizzArd | gooood |
| 07:20 | patrkris | would protocols make it possible to transparently make partition fast on vectors by using subvec? |
| 07:21 | Chousuke | partition is fast |
| 07:21 | Chousuke | it returns a lazy sequence |
| 07:21 | Chousuke | so it's in effect constant tim |
| 07:21 | Chousuke | time* |
| 07:22 | LauJensen | Chousuke: I dont follow your logic |
| 07:22 | patrkris | the call to partition itself is fast, yes |
| 07:23 | LauJensen | patrkris: But yes, protocols would let you use specific functions for chopping up specific datatypes |
| 07:23 | patrkris | LauJensen: yes - but I guess multimethods could be used also |
| 07:25 | LauJensen | I guess. |
| 07:27 | Chousuke | I need to learn to use org-mode better :P |
| 07:27 | Chousuke | oh well, I guess the table is okay now. |
| 08:16 | wlangstroth | technomancy: were there really that many *jure projects? I only know of scriptjure. |
| 08:17 | Raynes | wlangstroth: Compojure, conjure, enclojure, etc. |
| 08:18 | LauJensen | technomancy: that last commit was a joke right? |
| 08:18 | wlangstroth | Raynes: I completely forgot about those - LauJensen: Pretty sure that was a joke - doesn't Compojure use lein? |
| 08:19 | Raynes | Surely it's a joke. |
| 08:20 | LauJensen | Raynes: If it was anybody other than phil who made it, I wouldnt even have asked :) |
| 08:20 | Raynes | :p |
| 08:20 | wlangstroth | He *has* kept it up there for a while, though |
| 08: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. |
| 08:21 | Raynes | Huge commit, that was. |
| 08:21 | Raynes | 26 files changed, 575 insertions(+), 455 deletions(-) |
| 08: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 :) |
| 08:22 | Raynes | Hey! :< |
| 08:22 | wlangstroth | LauJensen: It's so true. We Canadians admitted to our socialism long ago. |
| 08: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 |
| 08:24 | mmarczyk | "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..." |
| 08:24 | Raynes | $help ( |
| 08:24 | sexpbot | Raynes: Evalutate Clojure code. Sandboxed, so you're welcome to try to break it. |
| 08:24 | Raynes | It's beautiful. |
| 08:24 | Raynes | mmarczyk, cgrand: I love you guys. <3 |
| 08:25 | mmarczyk | :-) |
| 08:25 | LauJensen | mmarczyk: You must restrain yourself! We dont know for sure yet! |
| 08:26 | mmarczyk | pleased to make your acquaintance, Mr. Sexpbot |
| 08:26 | LauJensen | $(dorun (pmap count (partition 2 (range 10e9)))) |
| 08:26 | Raynes | The core code is a mess right now because of a lack of sophisticated hooking. |
| 08:26 | sexpbot | Execution Timed Out! |
| 08:27 | LauJensen | Nice work Raynes |
| 08:27 | Raynes | LauJensen: Thank you. <3 |
| 08:27 | Raynes | It uses clj-sandbox for that. Courtesy of Licenser_. |
| 08:28 | mmarczyk | LauJensen: there's this strange feeling deep down in my gut, of truly the most dire portent, I fear |
| 08:28 | wlangstroth | That's the most sophisticated "Execution Timed Out!" I've ever seen. |
| 08:29 | mmarczyk | $(.hash "asdf") |
| 08:29 | sexpbot | No matching method found: hash for class java.lang.String |
| 08:29 | mmarczyk | (ouch) |
| 08:29 | mmarczyk | $(.hashCode "asdf") |
| 08:29 | sexpbot | 3003444 |
| 08:29 | fogus | $(#(% %) #(% %)) |
| 08:30 | mmarczyk | $(.getDeclaredMethod Integer "parseInt" (into-array Class [String])) |
| 08:30 | sexpbot | DENIED! |
| 08:30 | rfg | $(def x 5) |
| 08:30 | sexpbot | DENIED! |
| 08:30 | Raynes | Oh yeah, that reminds me of a big. |
| 08:30 | Raynes | bug* |
| 08:30 | LauJensen | $(future (+ 2 2)) |
| 08:30 | sexpbot | DENIED! |
| 08:30 | Raynes | If it returns nil, it doesn't print anything. |
| 08:30 | Raynes | That's something I forgot to fix from ages ago, because it isn't on my TODO list. :> |
| 08:30 | mmarczyk | $(eval :foo) |
| 08:30 | sexpbot | DENIED! |
| 08:30 | mmarczyk | $:foo |
| 08:30 | sexpbot | Command not found. No entiendo lo que estás diciendo. |
| 08:31 | rfg | $*clojure-version* |
| 08:31 | sexpbot | Command not found. No entiendo lo que estás diciendo. |
| 08:31 | mmarczyk | $(do *clojure-version*) |
| 08:31 | sexpbot | DENIED! |
| 08:31 | mmarczyk | $(identity *clojure-version*) |
| 08:31 | sexpbot | DENIED! |
| 08:31 | Raynes | It's 1.2. |
| 08:31 | Raynes | But that var isn't whitelisted. |
| 08:31 | mmarczyk | the secretive Mr. Sexpbot :-) |
| 08:31 | mmarczyk | $(clojure.contrib.find-namespaces/find-namespaces-on-classpath) |
| 08:31 | sexpbot | clojure.contrib.find-namespaces |
| 08:32 | rfg | $(System/getProperty "java.class.path") |
| 08:32 | sexpbot | DENIED! |
| 08: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). |
| 08:33 | mmarczyk | why'd he return 'clojure.contrib.find-namespaces for $(clojure.contrib.find-namespaces/find-namespaces-on-classpath) ? |
| 08:33 | mmarczyk | #clojure-casual ? is there such a channel? :-) |
| 08:33 | Raynes | I don't know. |
| 08:33 | fogus | $(let [$ identity] (#(% $) #(% $))) |
| 08:33 | sexpbot | clojure.core$identity__3929@e62a39 |
| 08:33 | Raynes | mmarczyk: Indeed. |
| 08:35 | mmarczyk | $(ns-resolve *ns* '*clojure-version*) |
| 08:35 | sexpbot | DENIED! |
| 08:35 | Licenser_ | mmarczyk: if you break the sandbox you get a cookie :P |
| 08:36 | mmarczyk | oh! oh! |
| 08:36 | mmarczyk | lemme get the code then |
| 08:37 | Licenser_ | mmarczyk: changing the code to break it does not cound :P |
| 08:37 | mmarczyk | that much is understood :-) |
| 08:37 | Licenser_ | elsewhre http://github.com/Licenser/clj-sandbox |
| 08:37 | sexpbot | Page has no title. |
| 08:37 | Raynes | Uh oh. |
| 08:37 | Raynes | That isn't good. |
| 08:37 | Licenser_ | I broke sexpbot |
| 08:38 | Licenser_ | heh |
| 08:38 | Raynes | He's supposed to ignore github titles. |
| 08: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 |
| 08:38 | Licenser_ | mmarczyk: appriciated |
| 08:39 | Licenser_ | I claim it to be more secure then clojurebot :P |
| 08:39 | Raynes | Oh, I see. |
| 08:42 | Raynes | <Licenser_> elsewhre http://github.com/Licenser/clj-sandbox |
| 08:42 | Raynes | There we go. |
| 08:42 | Raynes | Good bot. |
| 08:43 | mmarczyk | $(meta #'+) |
| 08: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."} |
| 08:44 | mmarczyk | $(.alterMeta #'+ assoc :name '-) |
| 08:44 | sexpbot | Tried to call: alterMeta on #'clojure.core/+ which is not allowed. |
| 08:44 | mmarczyk | :-) |
| 08:44 | Licenser_ | :) |
| 08:44 | Licenser_ | good aproach but no cookie yet |
| 08:45 | mmarczyk | this only serves to strengthen our resolve (and hopefully the awaiting cookie grows larger in time) |
| 08:45 | Licenser_ | just more |
| 08:46 | Licenser_ | you know there is a limit of cookie size to create but the ammount of cookies - while certenly limited - is way more extenedable |
| 08:46 | mmarczyk | "You silly wabbit..." :-D |
| 08:46 | Raynes | Well, _ato` just broke sexpbot. |
| 08:47 | Raynes | You guys are on a roll today. :p |
| 08:47 | Licenser_ | _ato`: is good at breaking things |
| 08:47 | mmarczyk | Licenser: oh, I should have realised you'd have a lazy sequence of cookies |
| 08:47 | Licenser_ | of cause |
| 08:48 | Licenser_ | 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 |
| 08:49 | mmarczyk | $(symbol "asdf") |
| 08:50 | mmarczyk | oh the bothersome legacy stoves |
| 08:51 | Licenser_ | $(symbol "asdf") |
| 08:51 | sexpbot | result: asdf |
| 08:51 | Raynes | Not as fixed as I thought. |
| 08:52 | mmarczyk | hm |
| 08:53 | mmarczyk | $(throw (RuntimeException. "asdf")) |
| 08:54 | Raynes | mmarczyk: You might want to wait until the bot is online. :p |
| 08:54 | Raynes | Works better that way. |
| 08:55 | mmarczyk | the very same idea has occurred to me ;-) |
| 08:58 | mmarczyk | right, um, so I was going to retry that; here goes: |
| 08:58 | mmarczyk | $(throw (RuntimeException. "asdf")) |
| 08:58 | sexpbot | asdf |
| 08:59 | spariev | $(str "b" (reduce (fn [x y] (str x "i")) "i" (take 30 (repeat :cookie))) "g cookie") |
| 08:59 | sexpbot | result: biiiiiiiiiiiiiiiiiiiiiiiiiiiiiiig cookie |
| 08:59 | spariev | just experimenting with lazy seq of cookies |
| 08:59 | Licenser_ | good work spariev |
| 08:59 | Raynes | Cookies taste good. |
| 09:00 | mmarczyk | $(str #=(println "Regrettably, one must work harder than this for one's cookie.")) |
| 09:00 | sexpbot | EvalReader not allowed when *read-eval* is false. |
| 09:08 | fogus | Clojure API needed. http://www.flyobjectspace.com/ |
| 09:08 | sexpbot | "Fly Object Space" |
| 09:09 | mmarczyk | $(() ()) |
| 09:09 | sexpbot | clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn |
| 09:10 | mmarczyk | $(the-ns 'user) |
| 09:10 | sexpbot | result: user |
| 09:11 | mmarczyk | $(.getMapping (the-ns 'user) 'resolve) |
| 09:11 | sexpbot | DENIED! |
| 09:11 | mmarczyk | :-( |
| 09:12 | mmarczyk | obviously not gonna work, but hey... I've just thought of at least a dozen convoluted ways of calling Clojure functions by name :-) |
| 09:17 | Chousuke | ,(resolve 'foo) |
| 09:17 | clojurebot | nil |
| 09:18 | Chousuke | ,((resolve (symbol (apply str '[e v a l]))) '(+ 1 1)) |
| 09:18 | clojurebot | 2 |
| 09:18 | Chousuke | :P |
| 09:18 | mmarczyk | oh my :-) |
| 09: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. |
| 09:19 | mmarczyk | you're talking to the wrong bot, though :-) |
| 09:19 | mmarczyk | $(resolve 'foo) |
| 09:19 | sexpbot | DENIED! |
| 09:19 | mmarczyk | ,(resolve 'foo) |
| 09:19 | clojurebot | nil |
| 09:20 | anars | ,(doc resolve) |
| 09:20 | clojurebot | "([sym]); same as (ns-resolve *ns* symbol)" |
| 09:20 | Chousuke | $(var resolve) |
| 09:20 | sexpbot | DENIED! |
| 09:20 | Chousuke | $(ns-resolve *ns* 'foo) |
| 09:20 | sexpbot | DENIED! |
| 09:20 | Chousuke | hmm, they've been more thorough :P |
| 09:20 | Chousuke | $'resolve |
| 09:20 | sexpbot | Command not found. No entiendo lo que estás diciendo. |
| 09:21 | Chousuke | $(do 'resolve) |
| 09:21 | sexpbot | DENIED! |
| 09:21 | Chousuke | ... very thorough :P |
| 09:21 | Chousuke | $(ns-mappings *ns*) |
| 09:21 | sexpbot | DENIED! |
| 09:21 | Chousuke | hmmh |
| 09:24 | LauJensen | Chousuke: I wonder if you ask Raynes nicely, if he won't give you your own special channel wherein you can practice :) |
| 09:24 | Raynes | I already did. :\ |
| 09:24 | Raynes | They just haven't listened. :p |
| 09:24 | kzar | #clojure-casual I think |
| 09:25 | Raynes | LauJensen: Every time people play with the bot, I note that it's in #clojure-casual as well for extended playtime. |
| 09:30 | Raynes | At least chouser didn't have to see me make a fool of myself. |
| 09:31 | Chousuke | heh |
| 09:31 | LauJensen | mmarczyk: you're switching to mouse ? |
| 09:31 | LauJensen | cemerick: You got me there :) |
| 09:32 | Chousuke | http://github.com/technomancy/leiningen/commit/39732d5b649dedb70b14e88fe561dfc9ddb31611 \o/ |
| 09:33 | wlangstroth | LauJensen: I'm guessing the concern for American roots had more to do with being sued than incurring a tax. |
| 09: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 |
| 09:35 | cemerick | ah, the blunt cludgel of tax policy :-) |
| 09:36 | wlangstroth | LauJensen: I didn't realize you were the one responsible for so much CO2. |
| 09:36 | LauJensen | Yea thats my bad Im afraid |
| 09:38 | wlangstroth | I mean, I knew you were responsible for a lot of hot CO2, but ... |
| 09:39 | LauJensen | wow, cheap shot |
| 09:40 | wlangstroth | it was *right there* - how could I not take it? Besides, there's no technical discussion that I would interrupt. |
| 09:40 | LauJensen | yea I completely understand, now get going, I believe there are trees that need hugging - right ABOOT now :) |
| 09:42 | Raynes | Oh. I accidentally did :reload-all instead of :reload. |
| 09:42 | Raynes | Good stuff. |
| 09:43 | wlangstroth | I believe you mean "A-BOAT", which is how we really say it. Hold on - there's an unhugged tree outside. |
| 09:45 | wlangstroth | LauJensen: where *are* you, anyway - I want to at least know what part of Scandahoovia I'm insulting |
| 09:46 | Raynes | Now the bot has reload functionality. No more shutting him down just to fix a bug. |
| 09:49 | powr-toc | Is there a variant of catch that allows you to catch nested |
| 09:49 | powr-toc | exceptions? I'm using c.c.sql and it throws RuntimeExceptions, yet |
| 09:49 | powr-toc | the errors we need to catch are causally 2 deep |
| 09:50 | LauJensen | wlangstroth: Im in the middle of everything, aka Denmark |
| 09:50 | clojurebot | what time is it? |
| 09:50 | underdev | Time to get ill! |
| 09:50 | Raynes | powr-toc: clojure.stacktrace. |
| 09:50 | rfg | Denmark FTW |
| 09:50 | Raynes | powr-toc: (catch Exception e (.getMessage (clojure.stacktrace/root-cause e))) |
| 09: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) \?))) |
| 09:52 | AWizzArd | ,(format "INSERT INTO %s (%s)" "table" (str/join \, (repeat 5 \?))) |
| 09:52 | clojurebot | java.lang.Exception: No such var: str/join |
| 09:52 | AWizzArd | where str/join ==> clojure.contrib.string/join |
| 09:52 | AWizzArd | ,clojure.contrib.string/join |
| 09:52 | clojurebot | java.lang.ClassNotFoundException: clojure.contrib.string |
| 09:53 | zmila | AWizzArd - preferably you create sqls with different known tablenames, and then on run-time dispatch and select one of it |
| 09:57 | AWizzArd | zmila: clean and bureaucratic (: |
| 09:57 | AWizzArd | Hallo bendlas |
| 09:57 | bendlas | hi AWizzArd |
| 09: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 | mattcodes | 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 | slyphon | chouser: oh, sorry, i meant VBScript |
| 10:04 | chouser | Clojure benefit #1: doesn't poke you in the eye |
| 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 | mattcodes | 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 | mattcodes | 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 | Chousuke | 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 | chouser | I want to write chapter intros like that. :-) |
| 10:17 | chouser | 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 | bfwin | [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 | fogus | I would have never thought of that in a million years |
| 10:25 | Raynes | It's fixed now. |
| 10:25 | Raynes | 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 | Raynes | 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 | Chousuke | 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 | Chousuke | ,(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 | technomancy | - |
| 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 | Raynes | 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 | wlangstroth | fogus: that's terrible |
| 10:32 | wlangstroth | 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: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 | Chousuke | 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 | technomancy | 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 | arkahn | 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 | technomancy | 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 | wlangstroth | 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 | spariev | 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 | chouser | 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 | Chousuke | 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 | rhickey | 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 | rhickey | 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 | AWizzArd | 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 | rhickey | I think it leads to bad perf code |
| 11:51 | rhickey | I instead have map-indexed, where the mapping fn will get passed the index and the item |
| 11:52 | rhickey | indexed == (comp map-index vector) |
| 11:52 | rhickey | er, map-indexed |
| 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 | rhickey | 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 | stilkov_ | 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 | rhickey | oops sorry, s.b. 3 hops to 4 hops above |
| 12:05 | stilkov_ | 3.9 something |
| 12:05 | stilkov_ | 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 | rhickey | (let [v1k (into [] (range 10)) |
| 12:12 | rhickey | v1m (into [] (range 1000000))] |
| 12:12 | rhickey | (time (dotimes [_ 1000000] (rand-nth v1k))) |
| 12:12 | rhickey | (time (dotimes [_ 1000000] (rand-nth v1m)))) |
| 12:12 | rhickey | "Elapsed time: 257.341 msecs" |
| 12:12 | rhickey | "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 | eyeris | As a lisp-noob I thought & inits meant "and the rest of the arguments are converted to a list" |
| 12:15 | eyeris | 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 | eyeris | http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/struct |
| 12:16 | hiredman | right, but the api docs cover EVERYTHING |
| 12:16 | hiredman | 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 | Chousuke | 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 | slyphon | 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 | slyphon | stylistically speaking |
| 13:28 | slyphon | 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 | slyphon | 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 | digash | throws an exception Unable to resolve classname: clojure.core$bytes__4916@27443628 |
| 13:30 | digash | |
| 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 | chessguy | str.split('/').reject(&:blank?).reverse.join(', ') |
| 13:31 | chessguy | pretty darn expressive |
| 13:31 | slyphon | that's "rails" |
| 13:32 | slyphon | so some of the expressiveness has been handed to you |
| 13:32 | chessguy | well, sure you can use libraries |
| 13:33 | chessguy | 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 | slyphon | doesn't barf on nil |
| 13:34 | chouser | (->> "abc/def/ghi" (.split #"/") (remove empty?) reverse (str/join ", ")) |
| 13:34 | slyphon | wuuuuu! |
| 13:35 | slyphon | (.split #"/") really? |
| 13:35 | slyphon | nice |
| 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 | slyphon | 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 | dnolen | if you're using clojure-contrib 1.2.0 |
| 13:40 | chessguy | that's nice |
| 13:40 | chessguy | though i'd rather have a function i could pass the string into |
| 13:40 | slyphon | uh |
| 13:40 | slyphon | you just wrap the above in (fn blah [s] ...) |
| 13:40 | chessguy | yeah, i know |
| 13:41 | chessguy | 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 | licoresse | Trying to figure out the C-c t command in clojure-test-mode |
| 13:47 | licoresse | (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 | licoresse | That means, I should'nt worry too much about where to put the tests... |
| 13:49 | licoresse | as long as they are under test/ |
| 13:49 | licoresse | 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 | stuartsierra | 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 | Borkdude | 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 | kotarak | (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 | Borkdude | repeat already refers to: #'clojure.core/repeat in namespace: user2 |
| 13:58 | stuartsierra | oh yeah |
| 13:59 | stuartsierra | c.c.string contains names that clash with core |
| 13:59 | stuartsierra | You can't "use" it without ":only". |
| 13:59 | stuartsierra | 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 | Borkdude | 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 | stuartsierra | 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 | lambdatronic | But still...just nils. |
| 14:16 | lambdatronic | I'm using Clojure 1.1.0 |
| 14:16 | lambdatronic | master |
| 14:17 | lambdatronic | 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 | lambdatronic | 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 | Borkdude | gtg |
| 14:22 | chouser | is there a better way to write #(compare (first %1) (first %2)) ? |
| 14:23 | chouser | 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 | opqdonut | :) |
| 14:23 | chouser | yeah |
| 14:23 | chouser | '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:24 | chouser | #(apply compare (map f %&)) meh |
| 14:25 | slyphon | ooh |
| 14:25 | slyphon | 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 | slyphon | ? |
| 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:30 | slyphon | anyone? |
| 14:31 | chouser | (take-while identity (repeatedly #(.receive consumer))) |
| 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 | that much i get |
| 14:33 | slyphon | 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 | slyphon | nah, anything that gets through should be a Message |
| 14:34 | slyphon | 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 | lambdatronic | so I created a minimal test case and pasted it here: http://paste.lisp.org/display/98512 |
| 14:48 | lambdatronic | Just load it into a repl and run (clj-span.test/test-me) |
| 14:49 | lambdatronic | You should be able to see that the problem is in whatever is coming out of find-viewpath. |
| 14:49 | lambdatronic | Those vectors won't work as keys in the evil-map, although literal vectors do. |
| 14:49 | lambdatronic | Any help I can get here would be deeply appreciated. This bug has been biting me for a few days now. |
| 14:51 | lambdatronic | 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 | tcrayford | explain #_ comments |
| 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 | slyphon | :) |
| 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 | slyphon | 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 | stuartsierra | tcrayford: no |
| 15:04 | tcrayford | I'm mostly concerned about how results look |
| 15:05 | tcrayford | 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 | stuartsierra | 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 | stuartsierra | But even those are not API-stable right now. |
| 15:07 | tcrayford | aye |
| 15:07 | tcrayford | once those are, I'll have a crack |
| 15:07 | tcrayford | 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 | tcrayford | 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 | tcrayford | that's pretty cool |
| 15:10 | tcrayford | 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 | tcrayford | 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 | tcrayford | 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 | somnium | 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 | tcrayford | in favour of lazy-test |
| 15:18 | stuartsierra | mabes: lazytest is intended to subsume circumspec |
| 15:18 | stuartsierra | 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 | stuartsierra | Basically, we came at it from opposite directions. |
| 15:20 | stuartsierra | S. Halloway wrote circumspec by adding features he wanted in clojure.test. |
| 15:20 | stuartsierra | 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 | stuartsierra | I'm not there yet. |
| 15:21 | slyphon | :) |
| 15:21 | slyphon | stuartsierra: what are you doing talking in here then? go! |
| 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 | slyphon | clojars? |
| 15:22 | tcrayford | http://github.com/stuartsierra/lazytest |
| 15:23 | tcrayford | I'm not sure about the `is` macro's syntax |
| 15:23 | tcrayford | 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 | stuartsierra | 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 | stuartsierra | 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 | tcrayford | 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 | tcrayford | and how powerful |
| 15:34 | somnium | tcrayford: the core of its here, (I found c.c.monads to be slightly too magical) |
| 15:34 | somnium | 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 | slyphon | 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 | tcrayford | I was more interested in the code that used the state monad, as opposed to the implementation of it :P |
| 15:35 | tcrayford | 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 | tcrayford | 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 | stuartsierra | But nobody uses it. |
| 15:39 | stuartsierra | 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 | 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 | tcrayford | 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 | lambdatronic | just that one function. |
| 15:48 | lambdatronic | 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 | lambdatronic | it creates this sequence of vectors, which won't work as lookup keys in the evil-map. |
| 15:49 | lambdatronic | the evil-map is really just any boring map with vector pairs of integers as its keys. |
| 15:49 | lambdatronic | 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 | lambdatronic | If I have a map (in this case, evil-map) which has vectors of integers as its keys. |
| 15:50 | lambdatronic | and I try to do a lookup in it using a literal vector, it works. |
| 15:51 | lambdatronic | if I try to do the lookup like so (map evil-map list-of-vecs), that also works. |
| 15:51 | lambdatronic | provided a generate the list-of-vecs like so: for [i (range 3) j (range 3)] [i j]) |
| 15:51 | lambdatronic | however... |
| 15:52 | lambdatronic | 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 | lambdatronic | 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 | lambdatronic | j (range 3)] [i j]) ??? |
| 15:55 | stuartsierra | huh |
| 15:55 | stuartsierra | I don't know. |
| 15:56 | stuartsierra | they look the same |
| 15:56 | lambdatronic | i know. I'm trying to make a smaller test-case. |
| 15:56 | lambdatronic | just a moment |
| 16:00 | hoeck | lambdatronic: maybe it boils down to: |
| 16:00 | hoeck | ,(.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 | stuartsierra | 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 | lambdatronic | and they check out as = |
| 16:01 | lambdatronic | 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: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 | lambdatronic | @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 | stuartsierra | oh well |
| 16:19 | stuartsierra | 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 | stuarthalloway | kotarak: hopefully Rich is on it |
| 16:21 | stuarthalloway | 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 | stuartsierra | 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 | cemerick | 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 | stuarthalloway | 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 | 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 | stuarthalloway | 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 | 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 | technomancy | 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 | stuarthalloway | nothing called lib |
| 16:32 | stuarthalloway | 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 | rhickey | 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 | stuartsierra | 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 | chouser | 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 | chouser | 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 | rhickey | technomancy: yes, exactly |
| 16:49 | chouser | oh, sorry -- it was take-while I was using today that had no complement. |
| 16:50 | chouser | 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 | slyphon | (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 | stuartsierra | slyphon: multimethods have no "super" |
| 16:55 | slyphon | yes, i know |
| 16:55 | slyphon | 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 | slyphon | hrm, that wouldn't work either |
| 16:56 | slyphon | blah! |
| 16:56 | technomancy | I'm just not used to ever thinking about the difference between false and nil. |
| 16:57 | technomancy | 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 | slyphon | 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: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 | slyphon | 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 | slyphon | ooh |
| 17:03 | slyphon | 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 | 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 | technomancy | wlangstroth: I prefer "reserved for legacy JVM interop" |
| 17:09 | stuartsierra | slyphon: sure, just def a reference to it |
| 17:09 | stuartsierra | like (def old-report clojure.test/report) |
| 17:09 | slyphon | mm'kay |
| 17:09 | slyphon | 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 | rhickey | or just prepping for the push? |
| 17:12 | stuartsierra | slyphon: yes |
| 17:12 | slyphon | ok, cool :) |
| 17:12 | slyphon | 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 | chouser | no. |
| 17:16 | chouser | 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 | AWizzArd | 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"} |
| 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 | slyphon | er |
| 18:11 | slyphon | yeah, but with the correct syntax and stuff |
| 18:11 | slyphon | ;) |
| 18:12 | slyphon | oooh |
| 18:12 | slyphon | 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 | replaca | sometime folks complain about regular expression strings, other times they complain about CL format strings. But how about a mixture: |
| 18:18 | replaca | (GET (re-pattern (cl-format nil "/~@[~a/?~]" prefix)) (home-page prefix)) |
| 18:19 | slyphon | and on *that* note |
| 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: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 | technomancy | 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 | The-Kenny | My current project.clj fails with java.lang.IllegalStateException: Var swank.swank/start-server is unbound (using M-x swank-clojure-project) |
| 18:31 | The-Kenny | 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 | The-Kenny | 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 | technomancy | could try lein swank tho |
| 18:45 | The-Kenny | Fails too :( "group-by already refers to bla" |
| 18:45 | The-Kenny | 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: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: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 | stuarthalloway | 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 | technomancy | or rather, the only difference in semantics was an optional argument that was only used in the test suite |
| 19:47 | technomancy | (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 | stuarthalloway | s/the/there |
| 19:48 | technomancy | yeah, you just replace SNAPSHOT with the timestamp of the build |
| 19:48 | technomancy | 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 | slyphon | 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 | liebke | 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 | liebke | is it the same? |
| 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 | slyphon | C |
| 19:57 | slyphon | J |
| 19:57 | slyphon | GAH |
| 19:57 | slyphon | 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 | slyphon | i've been *wanting* that for a while |
| 20:00 | slyphon | 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 | somnium | {{ 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 | somnium | 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:30 | tomoj | is a quick recovery from what happened to 1.2 impossible in general? |
| 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 | slyphon | 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 | slyphon | a lazy-seq could be bytes coming out of a socket |
| 22:03 | _brian2_ | ok |
| 22:03 | _brian2_ | so what (first .. considers to be first is not what doseq does |
| 22:05 | slyphon | well |
| 22:05 | slyphon | actually, i'm gonna stop talking, because i'm kinda new to this |
| 22:05 | slyphon | ;) |
| 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 | _brian2_ | thnks |
| 22:07 | tomoj | the issue you're seeing is interesting |
| 22:07 | tomoj | 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 | tomoj | 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 | tomoj | you've got (doseq [[v] (hn-body)] (prn v)) |
| 22:13 | tomoj | 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 | tomoj | so v is bound to the first element of each string |
| 22:14 | tomoj | 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 | _brian2_ | clarify |
| 22:16 | _brian2_ | thanks! |
| 22:18 | _brian2_ | 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 | tomoj | ,(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 | tomoj | let, for, doseq, and others all use the same syntax here |
| 22:20 | _brian2_ | what do they mean b "head of sequence" ? |
| 22:20 | _brian2_ | the first element |
| 22:20 | _brian2_ | ? |
| 22:20 | tomoj | yeah, the head is the first element |
| 22:20 | tomoj | 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 | tomoj | 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 | _brian2_ | it seems only particular cases you would not want to use it |
| 22:33 | chouser | aaargh! |
| 22:33 | slyphon | chouser: sup? |
| 22:33 | slyphon | 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 | slyphon | 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 | chouser | 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 | slyphon | connection |
| 22:38 | slyphon | (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 | chouser | ,(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 | chouser | 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 | slyphon | i.e. representing a stream of IO as a seq of values |
| 22:42 | slyphon | 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 | tomoj | 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 | tomoj | then you just process the [a] like you would a lazy-seq |
| 22:47 | tomoj | the lazy seq actually has the mechanisms for doing more IO contained inside it |
| 22:47 | tomoj | 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 | chouser | if your comparator never returns 0, you can never find or remove anything in your set. |
| 22:48 | chouser | duh |
| 22:50 | rhudson | So the comparator for a sorted set has to define a total ordering, sounds like |
| 23:01 | rhudson | chouser: are you trying to define a priority queue? |
| 23:05 | chouser | yessir |
| 23:05 | chouser | it was working fine until I moved from vectors to records |
| 23:15 | chouser | I'm going crazy |
| 23:15 | chouser | ((.comparator wd) (first wd) (first wd)) ;=> 0 |
| 23:16 | chouser | (wd (first wd)) ;=> nil |
| 23:16 | chouser | 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 | slyphon | i think |
| 23:17 | unlink | (binding [*out* *err*] (println blah)) ? |
| 23:17 | unlink | oh, :( |
| 23:17 | slyphon | someone will correct me, though |
| 23:17 | slyphon | well |
| 23:17 | slyphon | 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 | chouser | I just spotted it |
| 23:19 | chouser | 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 | chouser | 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 | chouser | 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 | chouser | 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 | chouser | and items would mysteriously disappear |
| 23:25 | hiredman | chouser: uh, for immutable objects? |
| 23:26 | hiredman | oh |
| 23:26 | hiredman | right |
| 23:26 | hiredman | sorted-sets |
| 23:26 | hiredman | 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 | unlink | 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 | hiredman | nuts |
| 23:31 | hiredman | what is that thing called |
| 23:31 | unlink | SimpleDateFormatter? |
| 23:32 | unlink | * SimpleDateFormat |
| 23:32 | hiredman | sure |
| 23:32 | hiredman | 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 | hiredman | well |
| 23:32 | hiredman | 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:38 | unlink | in a bad way, I mean |
| 23:38 | slyphon | unlink: it's java, it's not supposed to be inspiring |
| 23:38 | slyphon | 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 | unlink | 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 | 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 |