#clojure log - Mar 06 2010

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

0:09 brandonw: if you have a situation where you are using map and need to define an anonymous function, but you already have one in a higher scope, is it more idiomatic to define that first anonymous function as a private function in the same namespace, or as a function defined within the scope of the top level public function you are working on

0:09 s/but you already have one/but you already have an anonymous function

0:10 (just to be clear)

0:15 slyphon: uh, where do i get swank-clojure.jar

0:15 * slyphon is a bit of an emacs n00b

0:15 slyphon: i followed the directions here: http://github.com/technomancy/swank-clojure

0:16 rickmode: slyphon: that's the right place

0:17 slyphon: yeah, it says to copy swank-clojure.jar to the lib/ directory if you want to use the project feature

0:17 but i'm retarded tonight and can't seem to find that jar file

0:17 rickmode: slphon: this helped me too: http://www.bestinclass.dk/index.php/2009/12/clojure-101-getting-clojure-slime-installed/

0:17 slyphon: rickmode: thanks :)

0:18 rickmode: slyphon: I was referred that video by another person here in this channel within the last week ;)

0:19 slyphon: heh

0:19 oh, bastard

0:20 * slyphon finds ~/.swank-clojure

0:20 rickmode: watch the video anyway - there's lots of good bits there

0:20 slyphon: cool

0:20 rickmode: it kinda explains the "why" of it all

0:21 slyphon: ah

0:21 i've been SLIMEd before, but yeah, any info is useful

0:22 rickmode: i'm still not entirely clear on the differences between slime and swank... but I got my emacs, clojure and leiningen stuff working smoothly now

0:23 slyphon: yeah, the slime/swank difference was always a bit of a mystery, i think swank is a lisp-impl-specific server that answers requests from slime

0:23 or, something like that

0:24 rickmode: ya - that's my sense too - UI vs. server stuff

0:25 * slyphon is really happy there's vim-mode

0:25 slyphon: 10 years of muscle-memory is not easily undone

0:26 rickmode: tell me about it... but I'm coming from an IDE background (winblows and java IDEs)

0:26 slyphon: ah

0:27 rickmode: i still get baffled by the frames/buffers/windows stuff in emacs - it's got its own *way*

0:27 tomoj: slyphon: just use elpa

0:27 it's pretty simple http://tomojack.com/2010/02/emacs-for-clojure-from-scratch/

0:27 slyphon: tomoj: yeah, i did, i needed to copy the swank-clojure.jar into an existing project

0:28 tomoj: lein?

0:28 clojurebot: leiningen is a build tool designed not to set your hair on fire (http://github.com/technomancy/leiningen)

0:28 slyphon: didn't realize it put it in .swank-clojure

0:28 tomoj: if your project needs swank-clojure, I think it should be in the dependencies for the build tool

0:28 it's pretty easy to work with a lein project through emacs

0:29 slyphon: well, i'm not really using a build tool right now

0:29 tomoj: why not? too much work?

0:29 slyphon: eh, i don't come from a java background, so it was a high barrier to entry for me to start thinking about leingen or maven or w/e

0:29 tomoj: I think I will be making a screencast soon with emacs+lein

0:29 yeah

0:29 slyphon: i just put my jars in lib/

0:29 tomoj: it can be a bit intimidating

0:30 slyphon: and wrote a Rakefile to spawn nailgun w/ vim-clojure

0:30 tomoj: but I think technomancy has really got it down so that it's easy to do

0:30 slyphon: technomancy is a sharp cookie

0:30 [sic]

0:30 tomoj: oh, I kind of assumed you were using emacs :)

0:30 slyphon: yeah, i switched

0:30 well

0:31 that makes it sound really official

0:31 i used emacs for about a year back in 2005 or so

0:31 i wanted to see where it was at

0:31 tomoj: and now you're a vim dude?

0:31 slyphon: i've always been a vim dude :)

0:32 tomoj: well, there's a lein-nailgun plugin

0:32 I dunno how well it works, though

0:32 slyphon: i was working on an all-emacs team though at the time, and i got tired of everyone always giving me shit about it

0:32 tomoj: haha

0:32 I didn't know there were all-emacs teams who gave shit about it

0:32 slyphon: well

0:32 heh

0:32 it was twisted-python

0:32 tomoj: if my coworkers start trying to use vim for clojure, I'd give them shit

0:32 but not aggressively :)

0:32 slyphon: and it was my first real gig, and i kind of wanted to fit in

0:33 tomoj: yeah makes sense

0:33 well, maybe I can convert you with my screencast

0:33 slyphon: now that i'm not trying to use emacs for IRC and reading email, and all that other nonsense, i'm interested primarily because i remember SLIME being *really* impressive with sbcl

0:33 plus, messing around with elisp is kind of fun

0:34 tomoj: yes, I've done a couple fun things with elisp

0:34 I've made it so the editor can be aware of which namespace a source file defines

0:34 slyphon: ah, that's handy

0:35 tomoj: so you can get a skeleton ns decl from the path, or cause the repl to switch to the namespace in the current buffer, for example

0:35 but I feel like there is much more you could do

0:35 (and a lot I love already works with slime)

0:35 slyphon: context-awareness is a really powerful thing

0:35 tomoj: e.g. M-. will jump to the function definition, even if the clj source file is buried in a jar

0:35 slyphon: see, *that* stuff is really nifty

0:35 tomoj: slime macroexpansion stuff works, some documentation stuff

0:36 plus, ...paredit

0:36 slyphon: yeah, srsly

0:36 tomoj: this is what my screencast will cover

0:36 slyphon: oh, excellent

0:36 i look forward to watching it

0:36 tomoj: but I can't stop the pain of learning (or using) emacs

0:36 :(

0:36 slyphon: hahaha

0:36 well, i've got the basics down

0:37 and having vim-mode (which is light-years better than Viper) definately helps

0:37 i just need hjkl

0:37 tomoj: I suppose you don't need much more than the basics

0:37 slyphon: and :e :w

0:37 tomoj: unless you want to live in emacs

0:37 slyphon: the 'C-w j' bindings are good too

0:38 that's one thing that always drove me insane about emacs, i didn't think the split-handling was nearly as straightforward

0:38 "Why did that open up down there?

0:38 "

0:38 tomoj: hmm

0:38 with paredit?

0:39 slyphon: nah, just with standard emacs buffer stuff

0:39 tomoj: I don't notice anything that sounds like that with my setup

0:39 but I don't really understand what you mean

0:39 slyphon: it could just be some insane combination of plugins i was using back in the day

0:39 it seems much more intuitive now

0:39 with this setup i have

0:40 tomoj: I think there was some plugin that made it so while you're editing, the parens are exploded c-style, but when you are done they are redone to be lisp-style (e.g. '))))))' at the end of a line)

0:40 but I don't find the need for that

0:40 * slyphon nods

0:41 slyphon: argh, one thing i wish i could figure out is how to globally define the friggin font i want EVERYWHERE

0:41 * slyphon is using Aquamacs

0:55 tomoj: aquamacs is :/

0:55 I'm not really sure what to do about emacs on osx

0:55 almost want to just run it in Terminal.app, but I hate Terminal.app

0:56 danlarkin: I live inside console emacs in iTerm

0:57 slyphon: i usually run everything in mrxvt

0:57 well, anything that has to do with "work", but the meta key in X11 on OS-X is totally hosed, iirc

1:00 offby1: newbie question -- just built my program with leiningen. When I try to run it with 'clj anagrams.jar "Your Mother Wears Army Boots"', I get 'Exception in thread "main" java.lang.Exception: No such namespace: ' (followed by a bunch of binary garbage). What might be wrong?

1:01 tomoj: danlarkin: will check iTerm out, thanks

1:01 I hadn't considered trying to get rxvt to work on mac

1:02 slyphon: i require jmk-neep

1:02 * offby1 requires pizza and beer

1:02 slyphon: well, that too

1:02 usually non-concurrently though

3:03 ennui: have a public Java class 'Bar' in package 'foo'. (import 'foo.Bar) succeeds. How can I now call its (public static) main method?

3:04 derefed: (foo.Bar/main) I think

3:04 that's just a guess though

3:06 tomoj: I imagine you will need to pass a string[] in, no?

3:07 (foo.Bar/main (into-array String []))

3:11 ennui: derefed, tomoj, thanks. the last one works perfectly. i was struggling with how to properly pass the string argument.

3:11 derefed: np =)

4:13 dmiles: http://libomv.pastebin.ca/1824907 <- am i runing the pastebin line 109 every "new" ?

4:14 nteon: so if i have ((a b) (c d) (e f)), how can i get (a b c d e f)? I want to use reduce but my brain is tired

4:15 gregh: ,(flatten '((a b) (c d) (e f)))

4:15 clojurebot: (a b c d e f)

4:17 nteon: gregh: ah! cool

4:17 thanks

4:22 ,(doc flatten)

4:22 clojurebot: "([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns nil."

4:22 hiredman: ,`flatten

4:22 clojurebot: clojure.contrib.seq-utils/flatten

4:25 nteon: hiredman: yes, that was the command I was looking for, thanks :)

4:35 zab: Evening all. I'm trying to get Enlive working on App Engine. GAE docs say I can read files using Class.getResource() or ServletContext.getResource(). NFI how to do that from Clojure. Any pointers?

4:45 tomoj: zab: (.getResourceAsStream (clojure.lang.RT/baseLoader) "filename")

4:46 maybe that's what you're looking for

4:46 zab: tomoj: thanks!

5:41 tomoj: what is the point of having (:load) in the ns macro?

5:42 I mean, I understand what it does, I just don't understand why we need it

5:42 so that we can split a namespace into multiple files easily?

10:01 ned: forgive my stupidity but whats the proper way to 'clone' a lein repo?

10:01 i cant quite figure it out and i've searched relatively extensively

10:02 tcrayford: use git clone?

10:02 ned: sorry the repos hosted on clojars

10:02 just git clone http://clojars.org/repo/name ?

10:07 oh it would seem i have to create some boilerplate code, before lein deps.

10:11 tcrayford: yep

10:11 in project.clj

10:16 rsh: is there a good way to tell emacs to indent custom macros a certain way? particularly when dealing with macros that contain a parameter like (& body)?

10:18 vy: rsh: It should indent them right, that's how (with-foo ...) macros get indented also.

10:23 rsh: I see. with-foo macros seem to work fine, but any arbitrary name doesn't like (defmacro =bind [parms & body])

10:27 vy: Hrm... That feature might be implemented in recent versions of SLIME, Clojure uses an obsolete version.

10:27 But I'm pretty sure SLIME is capable of indenting by looking at function's arguments.

11:33 jkr: If I want to use clojure-mode from ELPA with my own clojure.jar in /opt/clojure (as opposed to downloading a new one), what should I set?

11:33 I used to be able to set swank-clojure-jar-path, but it seems to have changed in the months since I last used it.

12:18 joshua-choi: Performance-wise, which is better: conj!-ing many times onto a vector transient, or cons-ing many times onto a list?

12:24 rsh: what is the clojure equivalent to CL's atomp function?

12:27 boojum: joshua-choi: seems to be transient is faster

12:28 joshua-choi: Okay

12:28 Thanks

12:31 boojum: joshua-choi: http://gist.github.com/323814

12:32 joshua-choi: Great, thanks for running that.

12:35 krumholt_: rsh, probably it's (not (coll? x))

12:36 rsh: thanks

12:37 krumholt_: rsh, but thats not quite it i think a function is not an atom in CL but it is not a coll in clojure either

12:37 dnolen: krumholt_ rsh: I believe seq? is more equivalent to atomp

12:38 krumholt_: ,(seq? [1 2 3])

12:38 clojurebot: false

12:41 krumholt_: ,(seq? (list 1 2 3))

12:41 clojurebot: true

12:43 krumholt_: ,(map #(not (or (coll? %) (fn? %))) [1 "foo" 'foo (list 1 3) [1 3] (fn [x] x) {:a 1} #{1 2 3}])

12:43 clojurebot: (true true true false false false false false)

12:43 krumholt_: i think (not (or (coll? x) (fn? x))) should be atomp

12:44 rsh: is that kind of calculation not common in clojure?

12:44 krumholt_: rsh, you mean for recursion?

12:44 rsh: ye

12:44 yes*

12:45 dnolen: krumholt_: interesting when I wrote clj-cont I brought it this very topic, but I don't recall why I decided seq? was better than coll?

12:45 brought -> brought up

12:45 krumholt_: rsh, i used it a lot in commonlisp almost never in clojure. i ceased to use symbols that much

12:46 dnolen, i think seq? checks if it implement ISeq like lists. coll is almost everything

12:47 dnolen, look at this beautiful class diagram :) http://github.com/Chouser/clojure-classes/blob/master/graph-w-legend.png

12:48 dnolen, you can see very good what coll? checks for and what seq? checks for

12:49 dnolen: yeah, again I don't remember why I chose seq?. It was a for a code walker.

12:50 code is from almost a year ago

12:50 I remember intending to use coll?

12:50 but bringing it up on IRC and changing my mind.

12:52 rsh: if recursing through a list representing a tree is uncommon in clojure, what are the alternatives

12:53 technomancy: rsh: I don't think it's particularly uncommon. have you used tree-seq?

13:08 rsh: technomancy: I have not heard of tree-seq, i will look into it more. We were discussing earlier the clojure equivalent of atomp and landed on (or #(coll? %) #(fn? %)) . Does this look right to you?

13:09 CL's atomp

13:10 offby1: newbie question -- just built my program with leiningen. When I try to run it with 'clj anagrams.jar "Your Mother Wears Army Boots"', I get 'Exception in thread "main" java.lang.Exception: No such namespace: ' (followed by a bunch of binary garbage). What might be wrong?

13:10 * offby1 clears throat and gestures subtly towards technomancy

13:10 technomancy: rsh: isn't atomp just "is this not a compound data type?" it's been a while since my last CL usage.

13:10 rsh: technomancy: yes

13:11 technomancy: offby1: does your project.clj specify the :main namespace?

13:11 rsh: technomany: clojure not having a this included seems odd to me, like it is implying you should not be doing this much

13:11 technomancy: offby1: the JVM has some odd rules wrt translating between dashed-namespaces and files_on_disk.clj

13:11 rsh: technomany: not having this*

13:11 technomancy: rsh: if you want to know if something is not a collection, you can just call (not (coll? x))

13:12 offby1: technomancy: lemme check

13:12 rsh: technomany: yeah, but a fn would return true there even though it shouldn't

13:13 offby1: technomancy: it says nothing about :main

13:13 I let leiningen create it, and didn't edit it further

13:15 technomancy: offby1: oh, I see. yeah, your clj script is probably expecting to be pointed at a .clj file instead of a jar

13:16 offby1: oh?

13:16 technomancy: you'd want to run jar files using the "java" command-line launcher, but the rules about that are quirky too

13:17 you need to either build it as a standalone jar, or include all the deps on the classpath

13:17 offby1: technomancy: aha, you are correct, sir

13:17 clj ./src/anagrams/core.clj yo ho ho => happiness

13:17 technomancy: and you'd also need to specify a :main namespace containing a -main function

13:17 right... command-line launching is definitely a weak point of clojure

13:19 offby1: you can also try the leiningen-run plugin

13:19 offby1: oh hell -- next problem is my program runs out of heap space. Is there a way I can increase it with clj, or do I just need to cruft up a shell script that directly invokes java on the .jar?

13:19 .oO("plugin"?)

13:19 technomancy: where'd you get your clj script? there's not really a standard one yet.

13:20 offby1: ClojurX

13:20 technomancy: offby1: looks like the one in contrib takes a CLOJURE_OPTS env var

13:20 CLOJURE_OPTS="-Xmx1g" clj [...]

13:21 if yours is based on that you could try that

13:21 JAVA_OPTS is also a common one

13:21 (bbiab)

13:23 offby1: tx

13:27 LauJensen: Evening team

13:39 joshua-choi: I think I asked this before, but I don't remember the answer. Is there a high-level function mystery so that (mystery f g) is equivalent to (fn [& args] (and (apply f args) (apply g args)))?

13:41 slyphon: joshua-choi: you could write that macro pretty easily

13:42 joshua-choi: Yeah. Just wondering if there was a standard one.

13:46 texodus: Anyone bored who wants to give me some feedback on a Clojure library I wrote to wrap Netty? http://github.com/texodus/saturnine

16:25 greybeard: Is there One True Swank/Slime Configuration document? Particularly in the use of swank-clojure-extra-classpaths?

16:29 My code runs fine from the command line - but not in slime. It doesn't seem to find the jars as I get the "No suitable driver found for jdbc:mysql://..."

16:43 dnolen: greybeard: install via ELPA and you'll probably find it easier to get working estup

16:43 estup -> setup

16:45 greybeard: I did use ELPA. But I prefer to have less magic and more understanding.

16:48 In .emacs I have something like: (setq swank-clojure-extra-classpaths (list "/Users/edglas/jars/" "/opt/jars/"))

17:16 bsteuber: why is there a difference between concat and lazy-cat, though concat states the seq is lazy?

17:18 hiredman: one of them is a macro so it can make things lazier

17:19 bsteuber: hmm

17:19 hiredman: ,(first (lazy-cat [1] (println :x)))

17:19 clojurebot: 1

17:19 hiredman: ,(first (lconcat [1] (println :x)))

17:19 clojurebot: java.lang.Exception: Unable to resolve symbol: lconcat in this context

17:19 hiredman: ,(first (concat [1] (println :x)))

17:19 clojurebot: 1

17:19 :x

17:20 bsteuber: ,(take 4 (concat (repeat 1) [2]))

17:20 clojurebot: (1 1 1 1)

17:21 bsteuber: i see

17:21 the there is only a difference when side effects are involved?

17:21 or is there a pure example where they differ?

17:22 hiredman: if the things you are concating are all lazy it makes no difference

17:22 well

17:23 lazy-cat wraps things in an additional layer of laziness

17:23 bsteuber: so if I have a 5000000 element array as first argument, will concat traverse it eagerly?

17:23 hiredman: no

17:23 bsteuber: good

17:23 hiredman: concat doesn't traverse

17:24 bsteuber: ok, so it is usually "lazy enough"

17:24 hiredman: but if you have a function that generats a 50000 element list, and (concat (f) [1]) because concat is a function f will be evaluated

17:24 er

17:24 (f)

17:25 the arguments to functions are evaluated and the result is passed

17:25 bsteuber: ok, that makes sense

17:25 hiredman: lazy-cat essential generates a thunk of each argument and that thunk is not called until it is needed

17:26 bsteuber: so I will just remember that not even function calls are evaluated

17:26 thank you :)

17:28 chouser: disconnecting to rearrange my network at home. please refrain from saying anything interesting until the logger is back online.

17:28 :-)

17:36 bsteuber: I'm wondering why replicate is there as well as repeat

17:36 chouser: bsteuber: historical reasons. I would expect replicate to go away

17:38 bsteuber: chouser: ic - so maybe it should be marked depricated?

17:38 chouser: sounds good to me

17:40 rhickey: ticket/patch welcome

17:46 bsteuber: oh, didn't know it is spelled deprecated

17:47 rhickey: ok, sounds like fun and a good reason to start learing about your assembla stuff

17:47 though it's just a patch of one line saying "DEPRECATED" :)

17:54 hiredman: ,(doc *asert*)

17:54 clojurebot: Gabh mo leithscéal?

17:54 hiredman: ,(doc *assert*)

17:54 clojurebot: "; "

17:54 tomoj: what's that for?

17:55 hiredman: good question

17:55 bsteuber: ,*assert*

17:55 clojurebot: true

17:55 hiredman: ,(doc assert)

17:55 clojurebot: "([x]); Evaluates expr and throws an exception if it does not evaluate to logical true."

17:56 tomoj: aha

17:57 so bind *assert* to false to skip assertions

17:58 hiredman: (when *assert* (binding [*out* *err*] (println "X is depricated, use Y")))

17:58 pre

18:00 bsteuber: .(assert false)

18:00 ,(binding [*assert* false] (assert false))

18:00 clojurebot: java.lang.Exception: Assert failed: false

18:01 bsteuber: hmm

18:04 hiredman: ,(binding [*assert* false] *assert*)

18:04 clojurebot: false

18:07 hiredman: ,(binding [*assert* false] (macroexpand '(assert false)))

18:07 clojurebot: nil

18:08 hiredman: it must be some kind of quirk of clojurebot's sandbox

18:08 or not

18:22 bsteuber: hiredman: I think the binding is done at run-time while the macroexpand already expands at compile-time

18:23 so *assert* is still true at this point

18:23 hiredman: mm

18:25 bsteuber: so how can we rebind *assert* at compile-time?

18:25 hiredman: write or find a binding macro

18:26 bsteuber: not sure if it's that easy

18:26 hiredman: why not?

18:28 bsteuber: ,(defmacro with-production-mode [& body] (binding [*assert* false] `(do ~@body)))

18:28 clojurebot: DENIED

18:31 bsteuber: (with-production-mode (assert false))

18:31 this fails

18:32 because the binding is only there when the `(do) is returned, but not when it's macroexpanded

18:34 we had to do sth like that

18:34 (defmacro with-production-mode [form] (binding [*assert* false] (macroexpand form)))

18:34 but explicit macroexpand is ugly

18:34 hiredman: ,(X [*assert* false] (assert false))

18:34 clojurebot: nil

18:35 hiredman: but that is rather horrible

18:35 bsteuber: ,(doc X)

18:35 clojurebot: "([[name value] & code]); "

18:40 * hiredman is cheating and using eval

18:40 bsteuber: yeah, why not

18:41 in CL you would do this kind of thing with (eval-when (compile) ...)

18:42 but the CL stuff is doing side effects, so you can't transfer this to clojure easily

18:42 hiredman: (defmacro X’ [x & code] `(binding ~x (eval '~@code)))

18:43 there really should be a do in there somewhere

18:45 bsteuber: how about eval and the environment?

18:45 it won't work in a let, right?

18:45 hiredman: right

18:46 it's hardly perfect

18:46 if you really want to you can always alter-var-root

18:47 bsteuber: somehow it stays true

18:48 maybe we're not supposed to alter the vars from core

18:48 hiredman: oh

18:49 direct binding maybe

18:49 bsteuber: ,`macroexpand-all

18:49 clojurebot: clojure.walk/macroexpand-all

18:50 hiredman: and the repl must bind it

18:50 ,(set! *assert* false)

18:50 clojurebot: java.lang.IllegalStateException: Can't change/establish root binding of: *assert* with set

18:50 hiredman: but clojurebot doesn't

18:50 bsteuber: (defmacro in-prod [& code] (binding [*assert* false] `(do ~@(macroexpand-all code))))

18:50 ,(defmacro in-prod [& code] (binding [*assert* false] `(do ~@(macroexpand-all code))))

18:50 clojurebot: DENIED

18:51 bsteuber: that does the job

18:52 though I don't know whether it is okay to macroexpand-all on arbitrary code

18:52 but I guess it's better that eval :)

18:54 why did clojurebot deny my in-prod macro?

18:55 hiredman: clojurebot doesn't allow defs

18:56 bsteuber: hm okay :)

20:05 ichernetsky: Hi. Is there possibility to gen-class some class that has some java annotation?

20:20 danlarkin: ichernetsky: I don't think clojure can do annotations yet

20:20 ichernetsky: danlarkin: Is it going to be added in the near future?

20:21 danlarkin: not to my knowledge

22:48 mikem: hi, if I have a function with arguments such as [first & rest], in the body of the function rest is a list. how can I pass that list to another function which accepts arguments the same way (ie: [firt & rest])?

22:52 nteon: ,(doc apply)

22:52 clojurebot: "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."

22:52 nteon: mikem: so (apply some-fn rest)

22:56 mikem: nteon: I'm actually trying to reply to this email on the mailing list: http://groups.google.com/group/clojure/browse_thread/thread/ea67c317dafb47df

22:56 in the last posting, the author wraps (struct-map) in his own function, passing in & init, but when inits is passed to struct-map it's a single list, not a variable number of arguments.

23:00 nteon: mikem: I would guess its because he's returning the struct 'sm', not the modified one returned from assoc

23:02 mikem: actually, it's the call to (struct-map ) which fails. the correct way to call struct-map is: (struct-map st :a 1 :b 2) ... inside his my-struct-map, it ends up being called (struct-map st (:a 1 :b 2))

23:02 so I'd like to "expand" that sequence (:a 1 :b 2) before passit it to the real struct-map

23:02 s/passit/passing/

23:06 nteon: mikem: (apply struct-map s inits)

23:06 is the particular change

23:07 ah, I misread that if statement

23:07 mikem: nteon: ok, that works

23:07 thanks

23:08 yeah, the if statement is correct

23:08 nteon: mikem: glad I could help

23:31 hiredman: http://gist.github.com/324145 my first chunked seq

Logging service provided by n01se.net