#clojure logs

2009-10-15

00:00cataskajust a thought: does clojure has "advise" like emacs elisp ?
00:13wavisjgrant: in a word, interfaces. that is a problem osgi is intended to solve
00:13hiredmanjgrant: there are tricks you can use to stop clojur code from referencing java classes
00:14hiredman(when (not *compiling-files*) (Class/forName "some.java.class"))
00:14hiredmanI forget if it's compiling files, whatever that var is
00:14hiredman,(doc *compiling-files*)
00:14clojurebotI don't understand.
00:14hiredmanbah
00:14hiredman,(doc *compile-files*)
00:14clojurebot"; Set to true when compiling files, false otherwise."
00:15hiredmanit does make interop less nice
00:16hiredmanyou can try and break the clojure code up into two parts, part one that the java depends on, and part two that depends on the java
01:32wavis,(new [java.awt.event.ActionListener] (actionPerformed [e] nil))
01:32clojurebotjava.lang.IllegalArgumentException: Unable to resolve classname: [java.awt.event.ActionListener]
01:33wavisthis is my first shot at the new new. not sure how else to use an api that requires action listeners. clues?
01:34wavis,(resolve 'java.awt.event.ActionListener)
01:34clojurebotjava.awt.event.ActionListener
01:35hiredmanwavis: clojurebot is not on the new new branch
01:36hiredmanand you don't need new new for that, proxy will work fine
01:36wavisoh. ... i thought i was, but maybe I'm not
01:36hiredmanI would just proxy unless you know you need new new (which you don't)
01:38wavisno, i just hadn't used proxy before.
01:49sfuenteshello
02:07wavishi sfuentes
02:14sfuenteshello there
02:39sfuentesLau: I have been waiting for thee
02:40sfuentesI am here to slay you, dragon
02:44tomojLauJensen: http://gist.github.com/210737
02:44tomojpatch for multiple not-nulls with postgres
02:45tomojguess I should post it to lighthouse, huh?
02:54sfuentes:)
03:18LauJensensfuentes, morning :)
03:46sfuentes_morning Lau
03:46LauJensenWhats up ?
03:46sfuentes_first thing ....
03:47sfuentes_i'm a Pythonista :)
03:47LauJensenhehe - I can almost guess the second thing :)
03:48sfuentes_second, I hope you keep writing those great posts ... did you guess right?
03:49LauJensenNo I got it wrong, but I might be affected by the night of tidal waves hitting my mailbox :) Thanks
03:49sfuentes_I know you get plentyful criticism, but I think the comparisons are great (even if a bit strong/controvertial)
03:50AWizzArdsfuentes_: what's up? Is Lau again comparing?
03:50AWizzArdHi Lau :)
03:50sfuentes_and I hope that criticism won't stop you from completing your Haskell vs Clojure post :)
03:51LauJensenHey AWizzArd
03:51sfuentes_cause you know the Haskell ppl are going to try to eat you alive
03:51jdz~max
03:51clojurebotmax people is 184
03:52LauJensensfuentes_, I think Haskell will be a while, it's DEEP language and I just got tarballed by one of them: http://blog.willdonnelly.net/2009/10/14/brians-purely-functional-brain/
03:52LauJensen49 lines :)
03:52jdztake that, AWizzArd
03:52LauJensen(still cant get it to compile)
03:52sfuentes_AWizzArd: he's doing a great job
03:52AWizzArdjdz: thanks man *thumbs up*
03:52AWizzArd*g*
03:53AWizzArd,(.wait "abc" 2000)
03:53clojurebotjava.lang.IllegalMonitorStateException
03:53AWizzArdWhy IMSE?
03:53LauJensensfuentes_, anyway, I knew that the Python post would send the sparks flying, but I felt it was important because normally the opposition gets drowned out. So this was my 2 cents
03:54LauJensenAWizzArd, that only fires when you're not the owner doesn't it ?
03:54ChousukeI'm not a fan of "vs." comparisons though /:
03:54LauJensenChousuke, truth be told, I'm not either. I had enough of those after the Scala rumble, which was good though
03:56sfuentes_I imagine comparisons are great for a task/problem at hand
03:57sfuentes_some tools are better suited and purposely designed for certain tasks after all
03:57LauJensenI think it depends. If you think that at Vs post can layout all truth in regards to both languages and give a 'fair' treatment you'll be disappointed, but it can serve to show some interesting differences, which is important
03:58LauJensenI did a lot of work in C++ some years ago when I met a guy from Microsoft who got me into C#, and because of it's ease of use and speed of development, I wasted so much time there. I think i would have enjoyed a Clojure vs C# type post at that time :)
03:58sfuentes_Lau: What if the post was a wiki? :)
04:00LauJensensfuentes_, when Clojure was first mentioned in the mainstream here, it was on newz.dk and it gots lots of attention. That attention can be summed up into these words "& as arbitary arguments is so lame, use php's foreach instead, thats much more concise" - So sometimes, it's good to hear an active users oppinion :)
04:00octeAWizzArd: in java you'd need to synchronize on "abc" first, afaik
04:00octeso i don't really know how you'd do that in clojure?
04:00sfuentes_Lau: Specifically, why would you say it was a waste of time?
04:01LauJensensfuentes_, because I wasn't expanding my horizon, I was just mutating objects in new ways, it was robotic programming so to speak
04:02sfuentes_Lau: makes sense .... but C# is still big business
04:02hiredmanAWizzArd: use a blocking queue, or promise/deliver, or etc...
04:02LauJensenNo doubt - And Python still has it's place :)
04:03octe(let [o (new Object)] (locking o (.wait o 200))),(locking [o new Object] (. wait
04:03octeoops
04:03octe,(let [o (new Object)] (locking o (.wait o 200)))
04:03clojurebotnil
04:03sfuentes_i think the cobol ppl (however few) still get paid pretty well .... at least i imagine
04:05sfuentes_but they are maintenance works :)
04:07AWizzArdI see.
04:08AWizzArdSo, locking will sync under the hood.
04:08AWizzArd,(doc locking)
04:08clojurebot"([x & body]); Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in all circumstances."
04:19octeAWizzArd: yup, just like in java you need to hold the monitor of the object
04:21AWizzArdAnd holding monitor means to synchronize?
04:21octeyes, pretty much on the jvm
05:22snowwhiteping
05:23snowwhite(contains? '(1 2 3) 2) ==> false so, seems in clojure list is not a collection?
05:23Chousukeno.
05:23Chousukecontains? checks for an index
05:23Chousukenot for values
05:23Chousukeuse .contains
05:23Chousukeclojurebot: contains
05:23clojurebotGabh mo leithscéal?
05:25G0SUBI am curious why (contains? '(1 2 3) 2) returns false.
05:25Chousukelists aren't indexed .)
05:25hiredman
05:25Chousukeso there is no value for the key 2
05:25hiredman,(doc contains?)
05:25clojurebot"([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."
05:25G0SUBisn't a list a collection too? (count) works on a list, for example.
05:25hiredman*key*
05:25hiredman*key*
05:25tomojhmm.. key is the key
05:26hiredmanlists don't have keys/indexs
05:26Chousukeclojurebot: contains? is for checking whether a collection has a value for a given key. If you want to find out whether a value exists in a Collection (in linear time!), use the java method .contains
05:26clojurebotIk begrijp
05:26Chousukeclojurebot: the-question is <alias> contains?
05:26clojurebotexcusez-moi
05:26Chousukehm
05:26Chousukehow does that work?
05:26hiredmanit doesn't
05:26arbscht_or c.c.seq-utils/includes?
05:26Chousukecan't have aliases? :(
05:26hiredmannope
05:27Chousukedamn
05:27ChousukeI guess contains? should be renamed
05:27Chousukeit has the most frequently asked question here.
05:27hiredmanI spent about two and a hald hours working replumbing clojurebot for derby
05:27hiredmanhalf
05:28Chousukeoh, it's db-backed now?
05:28hiredmanhaven't switch the live clojurebot over though
05:28Chousukedo you use clojureql?
05:28hiredmanyeah
05:28G0SUBChousuke: I agree. else the doc should be changed.
05:28hiredmanstorage branch on github
05:29hiredmanG0SUB: the doc cleary states *key*
05:29hiredmanif they *key* is present
05:29hiredmanand it says "will not perform linear search for a value"
05:30G0SUBhiredman: yeah, but it's not too clear.
05:30Chousukehas-key? would be a better name for contains ;(
05:34tomojhiredman: what/where is the "storage" branch?
05:34tomojoh, you mean for clojurebot?
05:34hiredmanyessir
05:35tomojthought it was a branch of clojureql I hadn't seen
07:03AWizzArd,(Integer/bitCount 1000000)
07:03clojurebot7
07:03AWizzArd,(Integer/bitCount 9999999)
07:03clojurebot14
07:04AWizzArd,(Integer/bitCount 2999999)
07:04clojurebot15
07:20AWizzArdThere is a reader macro for producing BigDecimal objects:
07:20AWizzArd,(class 123M)
07:20clojurebotjava.math.BigDecimal
07:21AWizzArdIs there something similar for BigIntegers?
08:31amatosI am trying to import clojure.contrib.sql in the REPL and it is not working. If I do "(use 'clojure.contrib.sql)" I get the following: java.lang.NoSuchMethodError: clojure.lang.Namespace.importClass(Ljava/lang/Class;)Ljava/lang/Class; (NO_SOURCE_FILE:0). I am using clojure 1.0 from maven central and the latest snapshop of clojure-contrib 1.0 from formos. Any ideas?
09:12chouser(package-alias 'java.util.concurrent 'conc) (conc.LinkedBlockingQueue.) ; wouldn't this be nice?
09:13cgrand+1
09:14chouserthough what I actually want is nested class aliasing, which is probably more controversial
09:14chousers/actually want/want at the moment/
09:15AWizzArdchouser: would it be possible to have re-seq taking an optional fn which defaults to re-groups?
09:16chouserAWizzArd: of course it would be *possible*
09:18AWizzArdand btw, is it possible to let with-open know what type its resource has which it will close? That way one could remove the reflection warnings in duck-streams
09:20chouserAWizzArd: type hints should flow through with-open bindings
09:20AWizzArdgood
09:21amatosI am trying to import clojure.contrib.sql in the REPL and it is not working. If I do "(use 'clojure.contrib.sql)" I get the following: java.lang.NoSuchMethodError: clojure.lang.Namespace.importClass(Ljava/lang/Class;)Ljava/lang/Class; (NO_SOURCE_FILE:0). I am using clojure 1.0 from maven central and the latest snapshop of clojure-contrib 1.0 from formos. Any ideas?
09:25amatosShould I be using a more recent version of clojure?
09:27AWizzArdamatos: I am using a recent checkout of Clojure (from github) and using c.c.sql produces no problems on my system. You could really try a newer clojure.jar.
09:30amatosHow stable is clojure straight from github? Is that what most people use? I am a bit concerned with stability...
09:33chouseramatos: there are very rarely new bugs in master compared to 1.0, so if you pull from master and contrib and then just stick with whatever version you get, you'll probably be just fine.
09:34chouseramatos: if you upgrade every time either changes, you're a bit more likely to stumble over a new contrib bug or some non-backward-compatible change, but even that is rarely much trouble.
09:35amatoschouser: thanks a lot. I'll give that a shot
09:36chouserif you do, please let me know if your experience is any worse than I described so I can avoid giving it to anyone else in the future. :-)
09:36amatossure :)
09:37amatoswell, at least now it seems to be working! Thanks a lot :)
09:40AWizzArdamatos: every few weeks I get a fresh checkout of Clojure, let my unit tests run and play a bit around. If that all works well (so far 100%) I keep the newest version.
09:41amatosok, thanks. I'll give that a try
10:42Chousuke*sigh*
10:42Chousukewhy is syntax-quote symbol qualifying so damn complicated ;(
10:43rhickeyChousuke: how so?
10:48Chousukerhickey: Well, that's what it seems to me. I'm trying to figure out everything it does in order to implement it in my macro, and just when I thought I was done I noticed I don't handle the Foo/bar static method case :P
10:49rhickeyoh, complicated to implement vs complicated to use?
10:49Chousukeyeah
10:49Chousukemy current attempt is already rather messy
10:55chouserthe longer I use Clojure, the more I tend to forget how much worse the alternatives are
10:55chouserI need to find a forum where I can teach it to people and watch them "get it"
10:56raekspeaking of teaching
10:57cemerickI still trip over the class vs. class-symbol thing more regularly than I should admit.
10:58chousercemerick: in type hints?
10:58raekclojure and its data structures will probably be mentioned in the course "data and program structures" I will attend next spring
10:58raekI might even be the person speaking about it
10:59cemerickchouser: in the context of macro-writing, yes.
10:59raekAnders Haraldsson seems to be interested in clojure
11:01raekhas there been held any courses in clojure at universities?
11:14Chousukehttp://gist.github.com/211019 hm, this looks okay
11:16somniumis there a recommended way to convert a java.util.HashMap to a persistent clojure map?
11:17Chousuke(into {} themap)
11:17somniumawesome
11:18somniumthe mongodb java api fits clojure like a glove
11:18Chousukeoh bugger
11:18Chousukenow my clojure doesn't build anymore.
11:19chouserrunning core.clj through your reader?
11:19Chousukenah, just trying to fix up syntax-quote
11:19ChousukeI love this informative error message
11:20Chousuke/build.xml:89: java.lang.ExceptionInInitializerError
11:25Chousukehm, the caveats of repl-driven development...
11:29Chousukethe unavailability of even the most basic macros hurts :P
11:35somniumwould it be worthwhile to subclass the associative clojure data structures and implement the db persistence interface for direct persistence?
11:35somniumit would make for a seamless wrapper, but I'm wondering if the default mutable java classes are better for db persistence
11:37cemericksomnium: that's something I'm planning on doing for a jdbm wrapper I wrote last month
11:38somniumI don't really have a good handle on how they're stored in memory, but if you have 20 maps sharing one base structure, and make 20 complete copies to the db, what happens?
11:39raekwouldn't it be very clojure-ish to have db persistance in a ref rather than a map?
11:39somniumraek: the ref has to contain some sort of datastructure right?
11:40raekthe implementation of the ref, or the value contained in the ref?
11:40cemerickdepends on what you want to do. Transparent persistence (I think there's a better term for that -- orthogonal persistence?) makes for some very straightforward app implementations. If you can forget that there's a DB there, things get a lot simpler.
11:43raeki was thinking about something like this:
11:43raek(def pref (persistent-ref "file.db"))
11:44raekand then @pref would give the value last set to it
11:45tomojbut transactions can be retried
11:45tomojis there a way to say, if this transaction fails, do this before retrying?
11:46tomoj(so you could use a database transaction in your STM transaction?)
11:46raekcouldn't one just make a watcher that watches the state change of a ref and store that to a file?
11:47tomojI suppose, but it's not ACID
11:47raektomoj: hmm, i suppose not
11:48tomojan STM transaction which wraps a DB transaction will be ACID, right?
11:48chouserrhickey's been talking about tweaking the STM to allow tying external transactions to it.
11:48chouserI don't know if that would be enough to get ACID, but you'd be closer.
11:49tomojis what's needed some way to say "do this to rollback my DB transaction if this STM transaction fails"?
11:50tomojand, "fail this STM transaction if such and such happens because the DB transaction failed"
11:51chouseruntil then a watcher would be pretty easy
11:51chousera watcher on a ref won't fire until the transaction is committing.
11:52tomojSTM already gives you ACI, right? so if you can guarantee that whenever an STM transaction commits, so does a DB transaction, you've got ACID, I think?
11:54chouserhm, an exception in a watcher doesn't prevent the transaction from committing. I guess that's not shocking.
11:55chouser,(let [r (ref 0)] (add-watch r nil #(throw (Exception. (str %4)))) (try (dosync (alter r inc)) (catch Exception _)) @r)
11:55clojurebotchouser: excusez-moi
11:55tomojor unplugging the computer while the watcher is doing its thing
11:55chouseroh, no try/catch, eh?
11:57chouser,(let [r (ref 0) a (agent nil)] (add-watch r nil #(throw (Exception. (str %4)))) (send a #(dosync % (alter r inc))) (await a) @r)
11:57clojurebot1
12:05AndiXnghi. can anybody help me creating a double[][] array?
12:05AndiXngi need it for initializing a TableLayout
12:07kotarakI think make-array can multidim: (make-array Double/TYPE 10 10) or so.
12:07kotarak(doc make-array)
12:07clojurebot"([type len] [type dim & more-dims]); Creates and returns an array of instances of the specified class of the specified dimension(s). Note that a class object is required. Class objects can be obtained by using their imported or fully-qualified name. Class objects for the primitive types can be obtained using, e.g., Integer/TYPE."
12:08AndiXngthanks :)
12:09AndiXngand is there a method where I can fill it quicky (e.g. by giving a clojure vector) or do i have to use aset for each field?
12:15somnium,(seq (let [ary (make-array Integer/TYPE 10 10)] (doseq [x (range 10)] (doseq [y (range 10)] (aset ary x y (* x y)))) ary ))
12:15clojurebot(#<int[] [I@e352d9> #<int[] [I@543360> #<int[] [I@1f8ec00> #<int[] [I@14df816> #<int[] [I@1daa156> #<int[] [I@962da5> #<int[] [I@18ec9af> #<int[] [I@15b2e18> #<int[] [I@12f40eb> #<int[] [I@14f23ae>)
12:16AndiXngok, i have custom values, thanks anyway
12:17cgrand,(into-array (map (partial into-array Double/TYPE) (repeat 4 (range 6))))
12:17clojurebot#<double[][] [[D@1eae719>
12:19cgrand,(into-array (map (partial into-array Double/TYPE) [[1 2] [3 4]]))
12:19clojurebot#<double[][] [[D@6f6266>
12:20cgrandAndiXng: ^^
12:20AndiXng,(seq (into-array (map (partial into-array Double/TYPE) [[1 2 3 4 5] [3 4]])))
12:20clojurebot(#<double[] [D@17fc253> #<double[] [D@aee53f>)
12:20AndiXngthis TableLayout has really a poor design ;)
12:21cgrand,(map seq (into-array (map (partial into-array Double/TYPE) [[1 2 3 4 5] [3 4]]))))
12:21clojurebot((1.0 2.0 3.0 4.0 5.0) (3.0 4.0))
12:23AndiXngcgrand: works like a charm, thanks
12:24cgrandyw
12:43AWizzArdDamn, where is my problem in understanding? I have a (def index (ref {})) - a ref on a hasmap. I fill it with lots of values. Now (count @index) ==> 513945. BUT, and this kills me: (count (keys @index)) ==> 513972
12:44AWizzArdAnd also: (count (rest @index)) ==> 513971
12:45AWizzArdHow is that possible? How can (= (dec (count @index)) (count (rest @index))) be false?
12:46Chousukeare you sure it didn't change in the middle?
12:46AWizzArd100% sure
12:46AWizzArdI can eval this now in the repl.
12:46AWizzArdI always get these numbers.
12:47Chousukedo you have test code to replicate this?
12:47AWizzArdI can see if I can get code.
12:49ChousukeI think at some point there was a bug with hash-map counting... are you running an older version?
12:50Chousukeor maybe this is just another bug :P
12:51AWizzArdIt's not open source, but used in my company. I can see if I get something for replicating it, and I will try the newest Clojure version.
12:51AWizzArdgot to go now, tomorrow maybe more about it
12:55cgrandAWizzArd: is your clojure up to date?
12:56cgrandthere was several "count" bugs in the new PersistentHashMap (mea culpa)
12:56cgrandwere even
13:46kefka,(binding [*print-dup* true] (pr-str 5))
13:46clojurebot"5"
13:46kefka,(binding [*print-dup* true] (pr-str {:a 4}))
13:46clojurebot"#=(clojure.lang.PersistentArrayMap/create {:a 4})"
13:46kefka,(binding [*print-dup* true] (long 5))
13:46clojurebot5
13:46kefka,(binding [*print-dup* true] (pr-str (long 5)))
13:46clojurebot"#=(java.lang.Long. \"5\")"
13:48kefka,(binding [*print-dup* true] (pr-str (symbol "nil")))
13:48clojurebot"nil"
13:49kefka,(binding [*print-dup* true] (pr-str nil))
13:49clojurebot"nil"
13:49kefka,(= nil (symbol "nil"))
13:49clojurebotfalse
13:49kefkaShouldn't the print-dups be different?
13:50Chousukeyou don't want a symbol called nil
13:50Chousukethat'll break things
13:50kefkaok.
13:51kefkaI'd never use a symbol called nil
13:51kefkabut I thought print-dup was designed so as to be completely unambiguous
13:51chouserChousuke: I don't think that's right, actually.
13:51chouseroh
13:51chouserhm
13:52chousersorry, I'm wrong. Chousuke's right.
13:52chouser'symbol' currently is far too permissive, allowing you to create all kinds of symbols that cause problems later
13:53chouserI guess "nil" should be one that it refuses to do.
13:53technomancychouser: I have a patch for that!
13:53technomancywell, for unreadable symbols
13:53technomancynot for nil and such
13:53chousernil is an unreadable symbol though, actually.
13:53kefkaOn a related note:
13:53chouserthe text "nil" reads as the value nil not as the symbol nil
13:53technomancyoh, sure; that's handy
13:54kefka,(binding [*print-readably* true] (pr-str Double/POSITIVE_INFINITY))
13:54clojurebot"Infinity"
13:54technomancy~ticket 17
13:54clojurebotI don't understand.
13:54kefkawhich the reader converts to the symbol 'Infinity
13:54technomancy~#17
13:54clojurebotHuh?
13:54somnium,(symbol "#^%foo")
13:54clojurebot#^%foo
13:54technomancy~ticket #17
13:55clojurebot{:url http://tinyurl.com/nq6ef7, :summary "GC Issue 13: validate in (keyword s) and (symbol s)", :status :test, :priority :low, :created-on "2009-06-17T18:56:26+00:00"}
13:55chouserkefka: bleh. yep, that's no good.
13:58ambientimplementing a modular synth with clojure infinite seqs as streams is about 200x as slow as with C :/
13:59chouserambient: yeah, I was worried about your seq performance
14:00ambientwith C i can render in real time using 0.5% of CPU, with clojure it takes 3x times longer to render than play the audio
14:00chouserambient: the problem is that unless you're using chunked seqs the JVM has to create an object or two for *each* item of a seq.
14:00ambient:(
14:01ambientstreams just would be so elegant in this situation
14:01chouserthere's probably also a box/unbox performance hit
14:02Chousukeseqs don't make very good streams I guess :/
14:02chouserI know collections of primitives are planned -- I don't know if that will include seqs or not.
14:02chouserchunked seqs of primitives might get you a lot closer to C's speed, but I'm not sure.
14:03chouserambient: you're only using one processor core, right?
14:03technomancyooh, my fixtures patch got approved; sweet.
14:03ambientyes, i tried utilising 2 cores but it took 3 times longer
14:04chouserheh. oh.
14:04ChousukeI think rich was working on streams at some point.
14:04Chousukewhat became of that, I wonder.
14:04ambientchouser good tip about chunked seqs, is there any documentation other than i found from google?
14:04slashus2I think chunked seqs took priority.
14:05chouserChousuke: dead end. I think chunked seqs address some of the same problems streams were meant to.
14:05chouserambient: probably not. it may be that you're using them already.
14:06jedediahIs it possible to send a vector to a java function that expects a list? (Specifically, I'm looking at java.util.Collections
14:06ChousukeI think it would be beneficial to have some kind of a stream model of "this goes from A to B through a series of transformations, but never escapes" kind of situation
14:07ambientidk perhaps i could hack some sliding window thingie, using unboxed float vector, together that could emulate streams
14:08technomancyjedediah: try calling seq on it
14:08rstehwien1chouser: by chunked sequences do you mean something like (doseq [chunk (su/partition-all 256 bytes)] (.update crc (into-array Byte/TYPE chunk)))
14:08rstehwien1where bytes is a lazy-seq of bytes
14:09jedediahtechnomancy: thanks
14:09Chousukerstehwien1: no, chunked seqs just take advantage of the inherent chunkiness of some clojure data structures
14:10chouseralso some seq generators produce chunked seqs, such as range
14:10Chousukeeg. vectors are really internally made of chunks of 32, so processing each item lazily adds ~32 times more overhead than you need :P
14:10chouser,(class (seq (range 100)))
14:10clojurebotclojure.lang.ChunkedCons
14:11rstehwien1chousuke: I thought you might mean having a bunch of bytes read from a buffered stream and only needing to do the boxing into binary for larger chunks than one bye
14:11rstehwien1byte
14:11chouserno, currently each item in a chunked seq is still boxed. I don't know if there are plans for chunks of primitives.
14:12ChousukeI wonder if the JVM escape analysis is capable of detecting situations where there's a seq transformation pipeline, and do away with some of the excess allocations :/
14:13ChousukeI don't think Clojure's going to be as fast as C or plain java for sound processing any time soon, though.
14:14rstehwien1chouser: Ah, I'll have to do some reading on chunks. But the "(.update crc" call above only be operating on 256 bytes at a time saving me computational and boxing time than doing 1 byte at a time correct?
14:14chouserI think sound processing is one of rhickey's target application spaces. I think that's what all the array support is for.
14:18ambientif you want to hear some sound processing, here's a piece http://paste.pocoo.org/raw/145131/
14:18ambientrecognize the song? ;)
14:26somniumis there a way to check for interfaces on objects like for classes?
14:26technomancy(doc isa?)
14:26clojurebot"([child parent] [h child parent]); Returns true if (= child parent), or child is directly or indirectly derived from parent, either via a Java type inheritance relationship or a relationship established via derive. h must be a hierarchy obtained from make-hierarchy, if not supplied defaults to the global hierarchy"
14:27kotarak,(instance? clojure.lang.ISeq (list 1))
14:27clojurebottrue
14:28kotarak,(instance? (type (list 1)) clojure.lang.ISeq)
14:28clojurebotfalse
14:28kotarak,(isa? (type (list 1)) clojure.lang.ISeq)
14:28clojurebottrue
14:30somniumty
14:30namorjust how do you append two sequences?
14:30ambientlazy-cat
14:31ambient(lazy-cat (take 10 first-seq) (take 10 second-seq)) that's how i dun it
14:31kotarakor concat
14:31ambientor you could just concat.. ye :p
14:31namorAh, that's it! I was searching for something like "append".
14:32namorThanks!
14:32kotarak,(let [x (concat (do (println 1) [1]) (do (println 2) [2]))] (first x))
14:32clojurebot1
14:32clojurebot1 2
14:33kotarak,(let [x (concat (do (println 1) [1]) (do (println 2) [2]) (do (println 3) [3]))] (first x))
14:33clojurebot1
14:33clojurebot1 2 3
14:33kotarak,(let [x (lazy-cat (do (println 1) [1]) (do (println 2) [2]) (do (println 3) [3]))] (first x))
14:33clojurebot1
14:33clojurebot1
14:33kotarakThat's the difference.
14:34kotaraklazy-cat defers evaluation of its arguments. concat does not.
14:36somnium... best javadoc I've ever seen: com.mongodb.util.WeakBag : "if it's not obvious what a weak bag should do, then, well..."
14:38rstehwien1ambient: I almost recognize the song. Going to read it a bit tonight I hope
14:39The-KennyHello? Can someone help me with a small destructuring-issue? I want to get rid of :rows and :value in the result of a clojure-couchdb-call: http://paste.lisp.org/+1WFI
14:42arbscht_(map :value (:rows {:rows [))
14:42arbscht_(map :value (:rows {:rows [ {:value {:age 42}}))
14:43arbscht_if pasting would ever work...
14:43arbscht_,(map :value (:rows {:rows [{value {:age 42}} {:value {:age 23}}]}))
14:44clojurebotjava.lang.Exception: Unable to resolve symbol: value in this context
14:44arbscht_,(map :value (:rows {:rows [{:value {:age 42}} {:value {:age 23}}]}))
14:44clojurebot({:age 42} {:age 23})
14:44arbscht_at last!
14:44The-Kennyarbscht_: Yeah, I'm aware of that. I tried to do this with bindings of let. Just to make some functions cleaner.
14:44arbscht_oh right
14:45rstehwien1Curious what I'm doing wrong with this function reader macro:
14:45rstehwien1user> (map (fn [x] {x "hello"}) [1 2 3])
14:45rstehwien1({1 "hello"} {2 "hello"} {3 "hello"})
14:45rstehwien1user> (map #({% "hello"}) [1 2 3])
14:45rstehwien1; Evaluation aborted.
14:45rstehwien1user> "java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentArrayMap"
14:46kotarak,(macroexpand-1 '#({:x :y}))
14:46clojurebot(fn* [] ({:x :y}))
14:46kotarakrstehwien1: do you see it now?
14:46kotarak,(map #(hash-map % "hello") [1 2 3])
14:46clojurebot({1 "hello"} {2 "hello"} {3 "hello"})
14:46rstehwien1kotarak: Yes, nothing passed
14:47kotarakrstehwien1: ??
14:47rstehwien1kotorak: Thanks for the tip... must remember macroexpand-1
14:47kotarakyou try to call a map, whithout arguments this gives an exception.
14:47ChousukeThe-Kenny: I don't think what you want is possible with destructuring
14:47rstehwien1kotorak: Macro expanded to have no parameters.
14:48The-KennyChousuke: Okay, thank you.
14:49kotarakrstehwien1: no, #(foo) expands to (fn [] (foo)), your problem are the parens around foo.
14:49kotarak,(macroexpand-1 '#({% "hello"}))
14:49clojurebot(fn* [p1__5665] ({p1__5665 "hello"}))
14:49ChousukeI don't think macroexpand is actually necessary in that.
14:50Chousuke,'#(foo)
14:50clojurebot(fn* [] (foo))
14:50kotarak,String.
14:50clojurebotjava.lang.ClassNotFoundException: String.
14:50kotarak,'String.
14:50clojurebotString.
14:50ChousukeThat's not actually reader magic
14:50kotarak,'(String.)
14:50clojurebot(String.)
14:50kotarakYeah.
14:51Chousukewhich I am grateful of. it would complicate writing the reader a lot ;P
14:51rstehwien1,'#({% "hello"})
14:51clojurebot(fn* [p1__5678] ({p1__5678 "hello"}))
14:51kotarakWell there is magic of that in the syntax-quote stuff.
14:51kotarak,`(String.)
14:51clojurebot(java.lang.String.)
14:51Chousukeoh, I know.
14:51Chousukewanna see my syntax-quote implementation?
14:52kotarak,`(.length (String.))
14:52clojurebot(.length (java.lang.String.))
14:53kotarakChousuke: I dare to ask: you have a syntax-quote implementation?
14:53Chousukeyes
14:54Chousukehttp://github.com/Chousuke/clojure/blob/sq-macro/src/clj/clojure/core.clj#L535 <-
14:54Chousukeit needs some cleanup though, but it works
14:54Chousukeat least, as far as I can tell D:
14:56kotarakLooks good. Is it part of cinc?
14:56Chousukewell, it could be, but there's no real cinc project going on yet :)
14:56kotarakmainly preparations, no?
14:57Chousukeyeah.
14:57ChousukeI think I could clean up the code a lot with some use of cons or conj ;P
14:59Chousukeor rather, I just wonder why I used (list* 'do (rest form)) instead of cons :/
15:00ChousukeI'll also need to fix it to transfer metadata I guess
15:00somnium,(let [a {:b [:c :d]}] (doseq [[x [y z]] a] (println x y z)))
15:00clojurebot:b :c :d
15:01somnium,(let [a {:b [:c :d]}] (let [[x [y z]] a] (println x y z)))
15:01clojurebotjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap
15:01qedwhaaa
15:01somniumare the destructuring semantics different for different binding forms?
15:02Chousukeno,
15:02Chousukein doseq, you're destructuring each item of a
15:02Chousukewith let, you're trying to destructure a
15:03somnium,(let [[_ a] {:foo :bar}] a)
15:03clojurebotjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap
15:05Chousuke,(let [{a :a} {:a 1}] a)
15:05clojurebot1
15:05somniumaha
15:06Chousuke,(let [[a & x] {:a 1 b 1}] [a x])
15:06clojurebotjava.lang.Exception: Unable to resolve symbol: b in this context
15:06Chousuke,(let [[a & x] {:a 1 :b 1}] [a x])
15:06clojurebotjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap
15:06Chousuke,(let [[a & x] (seq {:a 1 :b 1})] [a x])
15:06clojurebot[[:a 1] ([:b 1])]
15:08Chousuke,(let [{{a :b} :a} {:a {:b 'c}}] a)
15:08clojurebotc
15:08somnium(let [a {:b [:c :d]}] (let [[x [y z]] (first (seq a))] (println x y z)))
15:08somnium,(let [a {:b [:c :d]}] (let [[x [y z]] (first (seq a))] (println x y z)))
15:08clojurebot:b :c :d
15:09Chousukemap destructuring is a bit weird
15:09Chousukethe binding map is "inverted"
15:10somniumI wonder if it would be more intuitive if it was automatically seqed... or if that would lead to strange behavior elsewhere
15:24cemerickugh, losing metadata because of an overly-casual into can be painful
15:26chouserhm. keeps the left-hand metadata, not the right-hand?
15:27cemerickeh, not even that. Had a map and did (into {...some new map...} map-with-metadata). Definitely not the smartest thing, but took about an hour to track down where my metadata had gone.
15:30chouser,(meta (into '#^{:some :meta} {e f} '{a b c d}))
15:30clojurebotnil
15:32cemerickno, it was more like (meta (into '{e f} '#^{:some :meta}{a b c d}))
15:32cemerickbut the metadata had been attached 5 layers deep
15:33kefkaHere's a question: why is there no function that, given a var, returns its name as a symbol?
15:33cemerickdefinitely my fault, but it's a pothole (i.e. I'm a long way from thinking about metadata when thinking about the contracts of fns as a matter of course)
15:33cemerickkefka: I think we've all written one :-)
15:34cemerickYou can get at it via java method calls.
15:34kefkacemerick: what method calls?
15:34kefkaObviously, there's (symbol (substring (str v) 2)) but that seems hackish
15:34kefkaI see the fields ns and name in clojure.lang.Var but no getNamespace or getName
15:34kefkathose exist for symbol, though.
15:35cemericklisppaste8: url?
15:35lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
15:35lisppaste8cemerick pasted "kefka: var-sym fn" at http://paste.lisp.org/display/88694
15:36cemerickheh, I wrote that before I got to know -> :-D
15:40LauJensenThose JVM Summit vids up yet ?
15:41ambientnot that i know of, at least not on infoq
15:41LauJensenok, next up. I see myself doing (dorun (map, (doall (map quite frequently - wouldn't it be helpful with a non-lazy map or a map which takes a keyword or something similar ?
15:44ambientbtw, seems that intellij idea will be FREE (at least the basic version)
15:44ambientthey're making a community edition
15:45lpetitambient: Intellij's in trouble ,
15:45lpetit?
15:45somniumthey'll need excellent clojure support to get me out of emacs
15:46LauJensensomnium, same here, and money
15:46tomojLauJensen: what do you need those for so often? your mapped function has side-effects?
15:48LauJensentomoj, like benchmarking forinstance, to get consitant results you need them forced.
15:48LauJensenBut year, printing, rendering, something like that also demands it
15:49chouserI almost never use doall. I would use doseq instead of dorun+map
15:49jevgenisomnium: is the current clojure support in IDEA so bad?
15:50ambienti dont know. afaik rich uses IDEA
15:50LauJensenambient, rich is on Emacs I think, no SLIME though
15:50tomojchouser: agreed
15:51ambienti just watched his talk from july where he said he uses IDEA, might've switched after
15:51LauJensenHmm... I don't remember him asking Stallman for permission... but I might have missed it
15:51chouserI think Rich uses intellij for Java
15:51somniumjevgeni: no idea. I've never actually used it. I downloaded ruby mine once but never actually used it :-p
15:52Raynes-The last time I used IDEA for Clojure, it was pretty good. I'm not sure if it's still being maintained.
15:52somniumenclojure is still a ways from emacs/vim
15:52jevgenisomnium: okay, I see:) I'm just newbie in clojure, wonder if I should learn emacs for it until it's not late)
15:52ambienti learned emacs for clojure...
15:53ambientit's really painful at the beginning but i got used to it
15:53Raynes-I didn't have to learn Emacs. I learned about 6 commands, and here I am today.
15:53ambientwhen i got emacs configured and memorized about 20 keyboard shortcuts i was ok
15:54somniumlearning clojure helps to learn to read elisp too
15:54jevgeniRaynes: don't you use sophisticated things like refactorings/etc? Or this is not the case with the clojure?
15:54RaynesNo, I don't really use anything like that with any language.
15:54ambientsomnium although i wish there was emacs-light written in clojure ;)
15:54RaynesAnd if I need to do something with Emacs that I don't know how to do, I simply google it.
15:54LauJensenanyway, about (doall (map ...)) I recommend a Common Lisp style naming: map-which-is-not-lazily-evaluated-because-it-is-being-forced-instead
15:55RaynesI typically have to look at a reference just to remember how to search and replace.
15:55somniumjevgeni: most dynamically typed languages don't need a lot of refactoring tools
15:55jevgeniokay, I see. probably this is not so scary as seems :)
15:55RaynesFunctional programming isn't scary, and anyone who tells you otherwise has never used functional programming.
15:56RaynesAnd Lisp in general just /looks/ scary.
15:56jevgeniI was rather talking about the emacs as ide
15:56RaynesOh.
15:56RaynesEmacs isn't scary at all.
15:56tomojjevgeni: +1 for emacs
15:56tomojtakes a bit of getting used to
15:56RaynesEspecially with Google on your side.
15:57somniumI think all the google hits involving monads make functional programming scarier than it is
15:57tomojI think it's quite scary at first
15:57tomojbut I got used to it and now I can't live without it
15:57technomancysomnium: doesn't help that everyone who first learns Haskell somehow feels compelled to write a monad tutorial once they get it.
15:57ambienti got my most used Emacs stuff in google docs, i'll see if i can publish it
15:57chouserthe emacs learning curve is roughly proportional to your depth of knowledge about your current editor.
15:58Raynestechnomancy: I think I might be the only person who has ever /got/ it and not been able to see what the big deal is. :\
15:58technomancyRaynes: how do you know you _really_ got it then?
15:58ambientjevgeni here: http://tommih.blogspot.com/2009/10/emacs-shortcuts.html
15:58RaynesI asked people.
15:58technomancyif you got it you would be all like "Monads are so cool! they're ... they're monads! See?"
15:59somniumquestion: since clojure explicitly makes room for side effects, is there any pragmatic reason to really grok monads (when using clojure)?
15:59jevgeniambient: thanks
15:59RaynesIt took about 3 days of focusing on Monads for me to see the purpose. Maybe I just missed the part that make them a big deal.
15:59tomojI still don't get it
15:59namorme neither
16:00tomojin the process of learning haskell though, maybe I'll have a tutorial of my own soon :P
16:00jevgeniactually I use the emacs for org mode, but I shall give it another try for clojure
16:00technomancyexcept for the "poor languages" part
16:07LauJensenSpeaking of Haskell. Those of you who read my Brians Brain post, please see an excellent translation to Haskell here http://blog.willdonnelly.net/
16:08mwoelkerIs there a good intro/video tutorial on using emacs/slime? I googled but only found listings of keyboard shortcuts
16:08ambienti might have to do that with python in one line
16:09mwoelkerI guess what I would like is an "over the shoulder view" to see the actual workflow
16:09mwoelkerIs code written in the REPL and then pasted to a clj when it works?
16:09ambientit can be
16:09mwoelkerIs it written in then clj and then execute from there?
16:09LauJensenambient, I've learned so much about Python from my commentators so I've actually wrote a little script which can turn a Python program into an 'idiomatic oneliner', let me know if you need it
16:09ambientor written in editor and pasted to repl
16:09dnolenmwoekler: you can just start writing code in a .clj file then send it to the repl.
16:10ambientLauJensen you really, really should look at numpy
16:10technomancymwoelker: you generally send whole files or defns to the repl at a time
16:11mwoelkerHow about managing multiple and/or larger projects? I really like having some sort of structure, and quick navigation to symbol definitions.
16:12mwoelkerI suspect emacs offers all that but coming from a good IDE background I expect context menus everywhere, which then allow me to discover and learn the keyboard shortcut step by step
16:12technomancyyeah, you can jump to the definition of any var easily
16:13technomancyyou just have to learn the build-in help commands, they will show you all the available features
16:13ambientmwoelker as for larger projects, clojure namespaces are enough for me
16:13somniummwoelker: for common lisp, but over-the-shoulder-slime nonetheless -> http://www.guba.com/watch/3000054867
16:13technomancyit's just not as immediately visible as pulling down a menu-bar
16:13technomancyyeah, it's very similar to the way you use slime with CL; so that video would be useful
16:14ol3````does slime-symbol completion work with clojure?
16:14mwoelkerokay thanks I'll check that out
16:14technomancyol3````: yeah, it should
17:02mwoelkersomnium: thanks for the link that was exactly what I was looking for
17:02somniummwoelker: cool
17:14somniumtrying to picture the recursions in clojure.walk is making my head spin, but they work like a charm.
17:35chousermutable state is killing me
17:35chouserbuild() has already been called on this Builder.
17:37chouseroh, found it. grrrr.
17:47lpetitchouser: he ?
17:47chousergoogle protobufs have a java api that's "mostly" immutable
17:48chousereach kind of message has an immutable class and a mutable "builder"
17:48lpetitchouser: ok, now I shouldn't have asked :)
17:48chousercalling (.build builder) gives you an immutable message, but apparently breaks the builder so you can't use it anymore. :-P
17:49technomancysounds like tranisents. =)
17:49chouseryeah, except I somehow doubt .build is constant-time ;-)
17:49lpetitok, interesting
17:49hiredmanthat would be a neat trick
17:50chouserbut now I figured out where my extra .build call is, I just need to copy the Java string into a C++ std::string ...
17:50chousercopy this
17:58somnium.. (def a (com.mongodb.BasicDBObject.))
17:58somnium(type a)
17:58somniumcom.mongodb.BasicDBObject
17:58somnium(isa? a com.mongodb.BasicDBObject) => false
17:59chousertry 'instance?'
17:59chouser'isa?' is for comparing two classes
17:59chouseroh, and reverse the args.
17:59chouser(instance? com.mongodb.BasicDBObject a)
18:00somniumthat worked
18:00somniumis there a rationale why isa? needs to be false though?
18:00chouser'isa?' is for comparing two classes
18:01chouser,(isa? Integer Number)
18:01somnium,(doc isa?)
18:01clojurebot"([child parent] [h child parent]); Returns true if (= child parent), or child is directly or indirectly derived from parent, either via a Java type inheritance relationship or a relationship established via derive. h must be a hierarchy obtained from make-hierarchy, if not supplied defaults to the global hierarchy"
18:01clojurebottrue
18:01chouser,(isa? Integer Class)
18:01clojurebotfalse
18:01chouser,(isa? Integer Object)
18:01clojurebottrue
18:01chouser,(instance? Integer Class)
18:01clojurebotfalse
18:02chouser,(instance? Class Integer)
18:02clojurebottrue
18:02chouserthere. now you should be sufficiently confused that I can go have dinner before you come up with a follow-up question. :-)
18:02somniumI was sufficiently confused before :)
18:02somniumnow I get it, but no still no idea why its that way...
18:03somniumso it goes
18:03chouserwell, my point is that you can't have one function that does both jobs (instance? and isa?) consistently.
18:04chouser(instance? Class Integer) ==> true (isa? Integer Class) ==> false
18:04mwoelkeris it clojure's birthday already?
18:05somniumright, damn classes. too bad java wasn't prototype based
18:05chousermwoelker: 17th I think
18:06hiredmanwow
18:06hiredmantime flies
18:12RaynesWill be 3 years wont it?
18:17chouser2
18:23technomancysince in English, "foo" is a String
18:24somniumI think it would be helpful if the doc string for isa? at least mentioned something about classes vs. instances
19:08djpowellhmm - trying to use clojure.main/repl to do a socket repl, but it doesn't seem to die when the client disconnects
19:10hiredmanwhy would it?
19:10djpowelli was hoping it would throw an exception or something
19:10djpowellor eof
19:11technomancydjpowell: there's a socket repl in contrib; have you seen that?
19:12djpowellill take a look
20:00qedgod clojure is interesting
20:00qedi cant get enough of rich's talks/demos
20:23ambienti just realised that if one pronounces closure like clojure, one is lisping :p
20:24ambient*mind blown* ;)
20:56chouserambient: heh
20:57Raynesqed: I'm contemplating building a shrine to Rich Hickey. Maybe we can exchange designs one day.
21:02qedRaynes: heh
21:02qedRaynes: mine is just a picture of rich's hair
21:02RaynesYeah. He has awesome hair.
21:02qedlike a jewish afro
21:03Raynes<3
21:03qedbut more anglo
21:04qedRaynes: do you know how old he is
21:04qedi feel like a jack ass because he's in the room
21:04qedbut im curious
21:11RaynesNo idea.
21:11RaynesOlder than me.
21:19chouserOld enough to know better.
22:04RaynesChouser: Touche.
22:55hiredman 19:59 hiredman : cljbot: how much do you know?
22:55hiredman 19:59 cljbot : I know 444 things
22:55hiredman:D
22:59durka42let's teach him 222 more
23:01hiredmanclojurebot's response is about 100 less
23:02hiredmancljbot is the derby backed clojurebot of the future
23:03sebaHi, I have a simple question: how do you get current file's absolute path
23:03seba*file* is relative .... getAbsolutPath uses the cwd .... so, won't work
23:03durka42simplicity can be deceptive :)
23:05durka42seba: this is interesting http://blog.taragana.com/index.php/archive/core-java-how-to-get-java-source-code-line-number-file-name-in-code/
23:06hiredmangetCanonicalPath
23:06hiredmanbut I would really recomend you keep things classpath relative
23:06sebaI get the same result using getCanonicalPath ... it also works from the cwd
23:06sebalet me explain my problem ... maybe I'm missing a simpler solution
23:07sebaI'm unit testing a function that gets resources from a directory
23:07sebaI created a sample directory of resources inside my test directory
23:08sebaI want to point my class to that sample directory in order to test it's output
23:08hiredmanclass?
23:08sebajeje sorry .... Ruby guy
23:09sebathe functions recibes a File as argument, and I would want to pass that sample directory to test the function
23:09hiredmanso, uh, what is stoppping you?
23:09seba(this is my first clojure project: http://github.com/paraseba/clj-deps
23:10sebathe problem is .... I don't know how to get a File ... pointing to a directory without using absolute paths in the code
23:10sebaif I do (File. *file*) I end with a relative file ... so tests would depend on your current working directory
23:11sebalet me clarify with some more code
23:11hiredmanbut, uh, so does the non-absolute path to the directory
23:12sebasorry ... I didn't follow
23:14hiredmanok, so aslong as you aren't constantly change the relative directory structure of test/ to file.clj
23:14hiredmanbut you can also use something like http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getResource%28java.lang.String%29
23:17sebahiredman: great, thank you, I'll try that
23:37jkoppelI just got burned heavily by false java.lang.Booleans being considered true by 'if
23:38hiredmanuse Boolean/valueOf
23:38jkoppelWell
23:38hiredmanor whatever
23:38jkoppelI'm not actually creating any Booleans manually
23:38hiredmanwhere are you getting them from?
23:38jkoppelI'm writing a multiplayer app, sending actions in the form of PersistentStructMaps
23:39jkoppelThe deserialization changes boolean primitives to Booleans
23:39jkoppel*serialization
23:39hiredmaneh?
23:39jkoppelIdentical code processing the actions on both sides, and debug prints say the input is dentical, but...not
23:39jkoppelI mean, I have things like this
23:39hiredmanhow are you serializing?
23:40jkoppelObjectOutputStream
23:40hiredmanwell, there you go
23:40jkoppelIs there a better thing to use?
23:40hiredmanprn
23:41jkoppelHmm
23:41jkoppelNow that a think about it, I'm not sure my current implementation sends anything that can't be parsed back in by the Clojure reader
23:42jkoppelThough it's more than a bit limiting to constrain the online sections of my code to things that can
23:44jkoppelAlso, that will suck for bandwidth, though I'll probably write custom code to compress the output beyond what ObjectOutputStream can do anyway
23:44jkoppelThanks though!
23:44chouseryou can use custom print-method handlers and #=() to read/write just about anything you want.
23:44jkoppelThanks!
23:47jkoppelHaving a bit of trouble finding information on that. I assume you mean add methods to a general function, but which one?
23:49hiredmanclojurebot: how much do you know?
23:49clojurebotI know 444 things
23:50durka42clojurebot: are you cljbot, the derby robot from the future?
23:50clojurebotdurka42: the fn created by future (like all fns) doesn't close over dynamicly scoped stuff
23:50durka42what a delightful non sequitur
23:50chouserjkkramer: (defmethod print-method [obj writer] ...)
23:51chouseroops. just missed jkoppel.
23:51jkkramerconfused me for a second :)
23:51hiredmandurka42: yes
23:51chouserjkkramer: :-) sorry.
23:52hiredmanhmmm