#clojure logs

2008-09-18

03:13scook0is there a good way to define a global mutable ref, such that if I reload the file that defines it the old value won't be clobbered?
04:07scgilardiscooko: one way to keep track of a ref is to bind it to a var using def. (def myref (ref {})) You can prevent myref from being clobbered by using "defonce" rather than "def".
04:09scgilardiyou can see an example of that in boot.clj where *loaded-libs* is protected against reloads of boot.clj.
05:59leafwanybody know how to turn on the clj_paren_rainbow option for syntax highlighting?
05:59leafwin Vim ?
05:59leafwit's not obvious at all for me
06:08leafwok done ... it was :let g:clj_paren_rainbow=1
08:57achim_phi! i've encountered an exception handling odditiy here. there seem to be some exceptions (ClassCast, in my case) you're not able to catch in the repl, while you can just fine running c.l.Script
08:57achim_p(try (tree-seq 1 2 3) (catch Exception e))
08:57achim_p(try (keys '(1)) (catch Exception e))
08:57achim_pany ideas why that might be?
09:37Chouserhm, odd.
09:40Chouserah, lazy seqs?
09:41Chouserthe exception is being thrown when the repl tries to print the values, not inside the try when the seq is being created.
09:43Chouser(def x (keys '(1))) ; "keys" is evaluated and successfully creates a seq which is stored at x
09:43Chouser(first x) ; oops
10:29Chouserthatnks for giving me the opportunity to learn. :-)
10:57ozzileeI have a function that gets called 1000 times a second with value. I want to take the average of every 100 values and call another function. My question is, where do I keep the sum and count while calculating the average. In a Ref? Is the STM going to give me performance headaches? Am I better off writing that bit in plain Java?
11:00Chouser_I dunno if STM would cause you much trouble. I think if there's no contention it's prety lightweight.
11:01ChouserYou could also mutate a value in a Java array or something if you want to escape Clojure's safety net without having to actually write Java code.
11:01ozzileeChouser: There should be any contention, so no worries there.
11:02Chouseroh, is this a single thread? you could use a var, binding, and set!
11:02ozzileeChouser: Hmm good idea. I'll keep that in mind if I do run into issues.
11:03ozzileeI haven't managed to wrap my head completely around Var bindings yet.
11:04ozzileeI was trying to close over the state of the Vars with a function, which I guess fails because the function doesn't know what thread it's going to be called from?
11:05Chouserif foo is calling bar 1000 times a second, you could say: (def sum) (defn bar [i] (set! sum (+ sum i))) (defn foo [] ... (binding [sum 0] (loop ... (bar i))))
11:05ChouserHm, I left out the recur.
11:06ChouserAnyway, the point is to use a dynamic binding of var, you have to do all your calls to (set!) within a (binding ...)
11:07ChouserI think I'd have to see your code to understand what you were trying to close over.
11:08ozzileeLet me pastie something up.
11:18lisppaste8ozzilee pasted "averages" at http://paste.lisp.org/display/67077
11:19ozzileeThe idea is to have make-averager take a count and a proc, then return a function that calls the proc once every count times with the average.
11:20abrooksI must be missing something simple. I'm trying to use clojure.parallel but neither the API documentation nor the stuff I've found in the Clojure group are clueing me in how to use library functions. Neither import nor load-file seems to work. I used to use load-file to load libraries like this but it no longer seems to work in the same manner. I could dig in and figure this out, of course, but I figure if I'm having ...
11:20abrooks... trouble, others may be as well. I think some documented examples would go a long way.
11:21Chouserabrooks: (ns user (:use clojure.parallel))
11:22abrooksAh, I found a way to use (load ) with a leading / on the path as well.
11:23abrooksChouser: Would it be reasonable to use this to be namespace agnostic? (ns *ns* (:use clojure.parallel))
11:25abrooksI realize that the (ns ..(:use ..)) mechanism is preferred but here's the load approach that also worked: (load "/clojure/parallel/parallel.clj")
11:25Chouserabrooks: no, to leave the current *ns* alone, say "use" or "require"
11:26Chouser(use 'clojure.parallel) ; imports *all* names, so I don't personally recommend it
11:26abrooksHm. (ns *ns* ) uses the quoted symbols as the namespace...
11:26Chouser(require '[clojure.parallel :as par])
11:26abrooksChouser: Is there some overview of how to use this that I've missed?
11:27abrooksThis seems incomplete: http://clojure.org/namespaces
11:28abrooksThis only talks about what's in (only two) of the libraries, not how to use them: http://clojure.org/other_libraries
11:29Chouserabrooks: http://groups.google.com/group/clojure/msg/1ad3690fb84abdc1
11:30Chouserozzilee: it looks like that code works. what's the problem?
11:32abrooksChouser: So, really the second link in there since the message you link to has no real documentation: http://groups.google.com/group/clojure/browse_frm/thread/bf552753ea0b6e20/f053d73f83e5b3d4
11:32ozzileeChouser: Yeah, it works, but is it sane? Is using Refs like that a decent way to do it? I always feel like I'm hacking around Clojure's immutability when I use Refs, rather than working with it.
11:34Chouserabrooks: I posted the link I did because it's directly off the release announcement thread, and because it helps explain why there aren't other docs yet.
11:35abrooksChouser: The above is still pretty thin on explanation and general usage. It also does give a picture of how load* relates to ns and import, etc.
11:36abrooksChouser: Ah. I missed that.
11:37Chouserozzilee: well, it probably can be improved, but you've got nice thread-safe code there. It's not immutable, but that's implied in your requirements.
11:38ozzileeChouser: All righty, thanks for the help, I appreciate it.
11:39Chouser(alter count inc)
11:40ozzileeChouser: Heh, I was just thinking I should use a separate dosync to reset them so I could (commute count + 1).
11:41ozzileeI didn't know about alter though, that's nice.
11:41ozzilee(realizing that alter doesn't have commute's relaxed ordering enforcement)
11:41Chousercommute's better, when you can use it. Which you can here.
11:41ozzileeYeah, I have to split out the reset bit though, otherwise it tells me I can't ref-set after commute.
11:42Chouseroh! cool.
11:43Chouserof course then it wouldn't really be thread-safe anymore -- you'd have a race after the inc and before the max test
11:43Chouserso maybe alter's best, since you won't have any contention anyway.
11:43ozzileeChouser: Ah, you're right.
11:43Chouser@sum is synonymous with (deref sum)
11:43ozzileeBah. undo undo undo :-)
11:44ozzilee@? Nice!
11:44Chouserfewer parens :-)
11:45ozzileeHmm. Shorter way to write (ref-set sum (+ @sum 1)) ?
11:45ozzileeEr.
11:45ozzilee(+ @sum n)
11:45ozzileeRather
11:45rhickey(alter sum inc)
11:46Chouser(dosync (alter sum #(+ % n)))
11:47rhickey(alter sum + n)
11:48ozzileeHeh nice.
11:51lisppaste8ozzilee annotated #67077 with "updated" at http://paste.lisp.org/display/67077#1
11:52Chouseryou've still got a deref in there.
11:52Chouserwhich is of course fine if you really want it. :-)
11:52ozzileeChouser: Yeah, I thought it was better for the feng shui...
11:53ChouserDunno if you care, but there's a rand-int function you might like too.
11:54ozzileeHmm, nice to know.
13:14ChouserIf I build a Clojure-collection-compatible data structure on top of a literal JS object, I can be sure I have the only reference to the JS obj and so until some change is made I can simply wrap the existing object.
13:14Chouserclj: [1 2 3] --> js: clojure.JS.lit_vector([1,2,3])
13:15rhickeyClojure does this, see LazilyPersistentVector
13:15Chouserall the data structures in ClojureScript will be mutable if you're malicious and poke around inside them.
13:16rhickeyChouser: you don't have the language constructs to prevent that
13:16rhickeye.g. final
13:16Chouserso my question is, should I use the same construct (like LazilyPersistenVector) when I *can't* be sure it's a literal underneath.
13:17rhickeywhere did it come from?
13:17Chouserfor example, should (vec x) make sure to copy x?
13:18rhickeyyou can build copying on non-copying but not vice-versa
13:18ChouserI guess I'm thinking of the collection constructors that can take a JS collection object.
13:18rhickeyI would say presume they will be used immutably and provide copy helpers
13:18rhickeysee vice-versa above
13:19rhickeyI hate it when there is no handoff option, since then you can't build one. Lots of Java is like that
13:23ChouserLike a method of LazilyPersistentVector that would return a clone or the internal array?
13:23rhickeysee create/createOwning
13:23rhickeyowning one is a handoff
13:24rhickeybut you can presume people will do (vec (clone x)) if they are unsure about the sharing involved
13:24rhickeyif you can write clone in JS
13:25rhickeypresume FP from people using Clojure Script
13:25ChouserI can write a clone. Fast (builtin) for arrays. Slow for hash/objects.
14:20jgracinrhickey: would you be willing to accept patches that add examples of usage to doc-strings of various functions? I miss that kind of info.
14:21jgracinI often know what the function does, just can't remember how to call it.
14:22rhickeyjgracin: I think examples would be great, but am not sure putting them in the source is best. There's the wiki, and there's also been some talk about tests. Perhaps they could be combined?
14:22abrooksjgracin: I wonder if that could be a separate module.. when loaded it updates the doc strings of the clojure API.
14:23ChouserI'd like examples to be runnable en-mass, to allow for confirmation that they're still accurate.
14:23abrooksThat way it wouldn't gunk up the main source file. The risk of course would be some level of inaccuracy as the API changes, there's more chance for a drift.
14:23Chouser...which makes them sound like unit tests.
14:23rhickeyChouser: exactly, they're just liek tests
14:23rhickeylike
14:24abrooksChouser: That would be reasonable as a separate module which could be loaded to update the doc strings and run as tests ala py-doctest.
14:24Chouserthere's already support for :test in meta-data, right?
14:24jgracinI don't mean elaborate examples of all possible usages, just one line how some thing is most often used, so that when I write (doc ns) I see the form.
14:24rhickeyyes, there's :test, and could be :example, but I'm feeling like some indirection might be good here
14:25jgracine.g. at the end of all text
14:26rhickeyChouser: I'm liking more and more your page-per-function idea. If the information had semantic structure, it could include docs, tests, examples and be both readable and subject to automated use
14:26jgracinI agree. that would be great
14:39Chouserit could probably be run off of just about any wiki system
14:41ozzileeThe chicken scheme people tried to do something like this... I don't think it ever really worked.
14:41ChouserI think I like -> plus .foo better than ..
14:41Chouserozzilee: oh, really? do you know why not?
14:42ozzileeChouser: I think it was a mix of things, I'm trying to think back to when we were talking about it.
14:43ozzileeThere was a lot of legacy stuff in place for docs. They were also putting all the documentation for user libraries in the same system, which complicated things.
14:44ozzileeDoing documentation that was meant to be viewed online as well as in the repl was restricting, as well. Tables and illustrations didn't work out very well.
14:45ozzileehttp://chicken.wiki.br/Eggs%20Unlimited%203
14:46ozzileeThat's the wiki, with sematic tags for examples and such.
14:47ozzileeIt's very possible their scope was just too large to handle. Of course, I haven't messed with Chicken in a while, so it all might work just great now, idk.
14:48Chouserozzilee: hm, thanks.
14:49ozzileeI still think it's a great idea, though.
14:50ChouserI think we'd want the primary description to flow from the boot.clj meta-data that only rhickey can edit. That keeps the args pegged to the real world, and the main prose under tight control.
14:51ChouserMaybe the first test or two could serve as the simplest examples, and somehow be made available at the repl.
14:52Chousersince they'd be code, there wouldn't be any html vs. repl formatting issues.
14:52Chousersince they'd be tests, it'd be easy to make sure they still worked as advertised.
14:53ChouserBesides hosting those examples, the wiki could also allow nearly anyone to add more tests, more verbose HTML prose, and "see also" links.
14:54abrooksChouser: I like your idea.
14:54arohnerCan you currently add more than one test to a function?
14:55Chousersure, if they're all wrapped in an enclosing fn. :-)
14:55Chouserbut I don't think boot.clj nor the functions metadata is the right place to put all tests
14:56abrooksboot.clj should remain sparse and maintainable, IMO.
14:58abrooksI do like the idea of being able to load a module and have richer metadata in the REPL. I don't see any reason why the wiki documentation couldn't be transformed into an enhancement library which would update the Clojure API functions with the extended help and examples.
14:58abrooksIt could be loaded on demand.
14:58abrooksarohner: Chouser and I have been discussing the concept grouping quite a bit recently.
14:58abrookser... achim_p --^
14:58abrooks(sorry arohner ...)
14:59abrooksachim_p: I like the idea presented in the screenshot too.
14:59abrooksachim_p: Oh, it was off by ourselves not in #clojure or the group. Sorry.
15:00abrooksachim_p: A lot of it was flailing around trying to figure out what the concepts / programming patterns may be.
15:01abrooksActually, I think the high level concepts were more obvious. The ideas of related functions and programming patterns (functions which take a collection and a seq containing subset of that collection, functions that reduce a collection to a single value, etc.) were harder to define crisply.
15:02Chouserabrooks: reasons the wiki docs may not work well in the repl: verbosity, illustration
15:02abrooksChouser: I was figuring that illustration would not work but Python docs are all available at the REPL.
15:03abrooksI can't see why we couldn't aim for a similar standard. Python docs are highly useful.
15:06rhickeyI don't see why we have to limit ourselves to repl text. I'd be just as happy if doc popped a browser or swing thing
15:07rhickeywho's using Clojure over terminals?
15:08rhickeyyikes
15:08rhickeysorry about that
15:08rhickey:)
15:08abrooksHeh. Don't appologize. It's a better world, IMO. :)
15:08arohnerI'm using clojure inside of an emacs inferior lisp
15:08abrooksI suspect that Chouser is as well.
15:09rhickeybut are the Clojure JVMs on other machines?
15:09abrooksI'm using Clojure inside of GNU screen linked with Vim.
15:09abrooksrhickey: Sure. I even use Clojure from a terminal when the JVM is local.
15:10abrooksrhickey: I suspect my usage is different that what you're imagining.
15:10rhickeyIf you enter this do you see it: (. javax.swing.JOptionPane (showMessageDialog nil "Hello World"))
15:10abrooksIf I run it locally or I forward X over the SSH session.
15:11arohnerI wouldn't like to be forced to have X at all times
15:11rhickeydo you have a browser?
15:11abrooksrhickey: Yeah... :)
15:12arohnerI wouldn't ask that you hold back functionality for terminal users, just leave a decent fallback
15:12abrooksrhickey: I'm sure about now you have rather warped view of my work environment. It's as arcane as you might imagine.
15:13arohnerabrooks: mine used to be similar
15:13arohnerssh + screen + emacs over a terminal
15:14abrooksrhickey: For me transparency and single context are the most important thing. I use GNU screen (instead of the much heavier, and less powerful VNC) so I can have a single context from wherever I am.
15:14drewrabrooks: You're not alone in that. I usually development Clojure in my Carbon-compiled Emacs, but I don't want to be limited.
15:14rhickeyI guess all I am saying is, it's 2008, Clojure is a new language, we should be able to leverage all of the internet/web tech to do something interesting rather than spew text, both from a presentation and information service, access and sharing standpoint
15:15abrooksWhether I'm at my workstation at work, or at home or connecting from my notebook, I have _exactly_ the same state/view.
15:16abrooksarohner, drewr: Right. ssh + screen + Vim in my case.
15:17arohnerrhickey: I like the browser idea. I like the fancy features, I just want the fallback to not start with "now install X..."
15:17abrooksrhickey: Python has nice GUI documentation (which I like and use) and that same documentation is available in texual form at the REPL. It's 2008, I think we can do both. :)
15:18abrooksChouser: Where do you run and edit Clojure? In an xterm? GNU screen?
15:20rhickeyI'm proud to be one of the presenters at Lisp50@OOPSLA: http://p-cos.blogspot.com/2008/09/lisp50oopsla.html
15:20abrooksrhickey: Cool. Congratulations!
15:21abrooksYou and Alan Kay. ;-)
15:21abrooksAnd John McCarthy
15:21rhickeyand John McCarthy, and Guy Steele and ...
15:21abrooksAnd Guy Steele.
15:21abrooksRight.
15:21rhickeyit's awesome
15:21Chouserabrooks: my repls are almost always in an xterm, occasionly in screen over ssh. I almost always edit .clj in gvim.
15:22abrooksChouser: Your JVM isn't always local either?
15:23abrooksrhickey: That's an impressively short list to be a member of. ;-D
15:23rhickeyYeah, quite an honor.
15:23abrooksOf course we consider this to be the future of Lisp so naturally you should be there. :)
15:23Chouserabrooks: the irc log -> html thing runs on a server that I get to via ssh.
15:24rhickeyyes, they asked me to represent this decade
15:24Chouserheh. seriously?
15:25drewrAwesome!
15:25arohnercongrats. That is an impressive list to be on
15:25rhickeyChouser: yes
15:26abrooksdrewr: Ah, right, OOPSLA 2008 will be in your back yard!
15:26drewrIt's more my front yard. My house faces downtown. :-)
15:26abrooks:)
15:26rhickeyMany of those guys are my heroes
15:27abrooksOh, and Richard Gabriel.. I missed him the first time through the list.
15:29abrooksChouser: Richard Gabriel is beind the Worse is Beter, Worse is Better is Worse, etc..
15:29abrooks^Beter^Better
15:30rhickeyClojure seems to be the only modern dialect represented, everyone else worked on Scheme/CL or still do
15:33abrooksrhickey: Are there any useful / significant (i.e. non-toy) Lisps in the last decade?
15:33rhickeyabrooks: besides CLojure?
15:33abrooksRight, besides Clojure. I've only seen what I consider to be experimental / amature Lisps.
15:34abrooksI consider Clojure to be viable for writing real production programms in, if not now, in the very near future (depending on one's requirements for "production").
15:35rhickeythat's kind of subjective, being considered non-toy/non-experimental is a high bar among the Lisp community, one of the reasons this is so nice for Clojure
15:36rhickeyBut the interest and activity in Clojure is undeniable
15:36abrooksrhickey: How about for you -- what other (new, non-scheme/non-CL) Lisps out there interest/have potential to you?
15:39rhickeyabrooks: obviously I'm biased, and busy with Clojure, but I've strived to make it a distinct and substantive dialect with a reason for existing. If I could have found the same feature set I wouldn't have written Clojure
15:40rhickeyI first spent a fair amount of time trying to integrate CL with what I consider the profession dev world. (jFli, Foil)
15:41rhickeyKawa was the only other Lisp I seriously considered a couple of years ago. I think it's a nice implementation
15:48jgracinrhickey: congrats on the invited talk. I'm glad you did not settle with CL. I think Clojure is what Lisp ought to be in the 21st century. CL is lovely but it desperately needed a facelift.
15:49jgracinand what a facelift it got.. :-)
15:50drewrrhickey: Did you stick with the JVM all these years because you believe in its power or because of its ubiquity and ease of integration with most business platforms?
15:53rhickeydrewr: from my perspective, for commercial dev it's either JVM or .Net. Foil supported both, and Clojure did early on
15:54rhickeygoing solely with the JVM let me go faster and deeper, and now, being open source and having so many open source libs and infrastructure, I think it's the better place to be
15:59abrooksThe JVM is really becoming the open platform that it wanted to be (and Sun kept it from being).
16:02rhickeyabrooks: you have to give Sun credit for staying in the platform game vs Microsoft's $$ and winning, in the sense that the rest of the world adopted Java and made it viable. Also for stability, MS has changed their whole API set 3 times in the same time frame
16:02abrooksThe explosion of new JVM languages, JVM support for dynamic languages, new JVM implementations (Icedtea, etc.), JRE/JDK as a standard part of distributions have all come, IMO as a direct result of Sun's open sourcing of Java.
16:03abrooksrhickey: Yes. The made the right decision. I think the Java platform suffered for a long time because they were unable/unwilling to do so.
16:03rhickeyI think the open sourcing is great, but don't neglect that the JVM is really good tech
16:03abrooksOh, HotSpot is fantastic are Sun's debug and profiling tools.
16:04abrooksThe tech was good but Java and the JVM were an isolated world until recently.
16:04rhickeyand compatibility, platform support etc. The only real negative was the pace, but that led to stability too
16:06rhickeyYeah, not being open source kept them out of Linux apps. I can't believe people still write apps in C/C++
16:06abrooksPlatform support was only good for dominant platforms. Java on odd architectures (custom MIPS comes to mind) sucks. The other side of platform support, OS interfaces, sucks as well because they completely punted on that.
16:08abrooksrhickey: There are some good reasons to write in C. There's a lot of things that Java can't touch. It's not at all useful for accessing OS features unless you pretend that the JVM is the OS.
16:09rhickeyC/C++ for parts, sure. For all of it, yikes.
16:09abrooksNo UNIX domain sockets effectively means no non AWT/Swing X11 access or high performance DB access without specific support libraries.
16:09abrooksrhickey: I'm still not convinced I want a JVM in my kernel, Clojure or no. :)
16:10rhickeyIt's about the right tool for the job. There are plenty of Linux apps needlessly written in C++, that's just goofy
16:11abrooksrhickey: I completely agree.
16:11rhickeyBut I agree, Java wasn't a viable choice then due to its closed-ness and poor Linux support
16:15abrooksThe without specific library support one has general, portable access to (A) files and (B) TCP/UDP sockets. That's fine for webish stuff but useless for whole application domains. I can't write a CD ripper without IOCTL support. I can't write a Mac OS Spotlight replacement (ala Beagle) without access to the kernel inotify syscall. I can't write an X11 window manager without UNIX domain socket support. etc., etc.
16:15abrooksI've been spending some time recently working on getting Jtux resurrected and maintained.
16:22ozzileeabrooks: Jtux looks neat.
16:23abrooksozzilee: Yes. And dormant.
16:23ozzileeI can imagine it being a hellish bunch of headaches.
16:23abrooksIt doesn't compile on an x86_64 system though I think Chouser got it compiled (and working?) on x86.
16:23ozzileeTo write, I mean.
16:28albinoJNA though?
16:28albinoBut I guess that is too far in the future to count as a solution now?
16:29abrooksozzilee: Just tedious, I expect.
16:29Chouserhttps://jna.dev.java.net/
16:29abrooksalbino: I forget why I rejected JNA before.
16:29abrooksPython's ctypes is insufficient for lots of stuff.
16:30ozzileeabrooks: Perhaps. I would think things like incompatibilities between bsd and linux would get annoying. Not to mention between versions of the same.
16:30abrooksAny calls which want to interact with physical buffers get tricky.
16:30abrooksI guess I should look at JNA again.
16:31abrooksozzilee: That's what GNU autotools is for. JTux was done without any GNU autotoolification.
16:31abrooksGNU autotools: The worst portability suite ever, except for all the others.
16:32ozzileeabrooks: I'm not sure what you mean by autotoolification. I'm not much for C programming.
16:33albinoabrooks: python's ctypes is supposed to be very similar to JNA for java, I thought
16:34albinowhere cyptes was a influence/inspiration for JNA
16:34abrooksalbino: Right and python's ctypes has limitations. It's a workable interface for some things though, even when it works it can be pretty gross.
16:34albinobetter than writing JNI code by hand
16:34albinoor C glue code by hand for CPython
16:35abrooksozzilee: GNU autotools includes: automake, autoconf, libtool. You've come across it if you've done the usual, ./configure; make; make install; dance.
16:35ozzileeabrooks: Right, I don't know what you mean by JTux being done without autotoolification. It doesn't account for incompatibilities?
16:37albinoI was reading about the suckiness of autotools a while back, seems like kde moved to cmake IIRC and they were saying it was totally worth it
16:37abrooksozzilee: Right. All the types are fixed with the assumption of the small set of compilers + platforms that the author used with some #defines that he figured out.
16:37albinoahh, here it is http://lwn.net/Articles/188693/
16:37ozzileeabrooks: Ah. So it needs a LOT of work :-)
16:37abrooksozzilee: Try cross compiling or targeting for some platform that the author didn't think about (x86_64, gcc 4.x, etc.) and you're SOL.
16:37abrooksozzilee: A good bit, yes.
16:39abrooksI do a lot of porting and cross-compiling at my job. CMake seems to have a lot less "stored" wisdom about cross-compile and non-x86, non-Linux/Windows platforms.
16:39abrookser.. "stored wisdom"
16:41abrooksIt seems that JNA will be a lot less work to get working. I guess I can start there until I have proven cases of it being insufficient/too slow for what I want to do.
16:42abrooksalbino: Thanks for pointing me back to JNA. :)
16:50albinoabrooks: heh, sure
16:58cemerickam I right in thinking that zippers are only suitable for binary trees?
16:59Chousercemerick: nope, any ol' tree will do
17:00cemerickhrm, I guess I'm being confused by a lot of the discussions of them focussing on binary trees
17:03Chouseryou're talking about clojure.zip right?
17:06cemerickChouser: Yeah. Pay me no heed. :-)
17:06ChouserI like clojure.zip and what it let me do with clojure.contrib.zip-filter, so I'm more than happy to help it make sense for you.
17:10cemerickChouser: Thanks for the offer, I may yet take you up on it.
20:36rhickeyadded *1/2/3 *e and tweaked error messages
21:01Chousercool