#clojure log - Oct 15 2009

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

0:00 cataska: just a thought: does clojure has "advise" like emacs elisp ?

0:13 wavis: jgrant: in a word, interfaces. that is a problem osgi is intended to solve

0:13 hiredman: jgrant: there are tricks you can use to stop clojur code from referencing java classes

0:14 (when (not *compiling-files*) (Class/forName "some.java.class"))

0:14 I forget if it's compiling files, whatever that var is

0:14 ,(doc *compiling-files*)

0:14 clojurebot: I don't understand.

0:14 hiredman: bah

0:14 ,(doc *compile-files*)

0:14 clojurebot: "; Set to true when compiling files, false otherwise."

0:15 hiredman: it does make interop less nice

0:16 you 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

1:32 wavis: ,(new [java.awt.event.ActionListener] (actionPerformed [e] nil))

1:32 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: [java.awt.event.ActionListener]

1:33 wavis: this is my first shot at the new new. not sure how else to use an api that requires action listeners. clues?

1:34 ,(resolve 'java.awt.event.ActionListener)

1:34 clojurebot: java.awt.event.ActionListener

1:35 hiredman: wavis: clojurebot is not on the new new branch

1:36 and you don't need new new for that, proxy will work fine

1:36 wavis: oh. ... i thought i was, but maybe I'm not

1:36 hiredman: I would just proxy unless you know you need new new (which you don't)

1:38 wavis: no, i just hadn't used proxy before.

1:49 sfuentes: hello

2:07 wavis: hi sfuentes

2:14 sfuentes: hello there

2:39 Lau: I have been waiting for thee

2:40 I am here to slay you, dragon

2:44 tomoj: LauJensen: http://gist.github.com/210737

2:44 patch for multiple not-nulls with postgres

2:45 guess I should post it to lighthouse, huh?

2:54 sfuentes: :)

3:18 LauJensen: sfuentes, morning :)

3:46 sfuentes_: morning Lau

3:46 LauJensen: Whats up ?

3:46 sfuentes_: first thing ....

3:47 i'm a Pythonista :)

3:47 LauJensen: hehe - I can almost guess the second thing :)

3:48 sfuentes_: second, I hope you keep writing those great posts ... did you guess right?

3:49 LauJensen: No I got it wrong, but I might be affected by the night of tidal waves hitting my mailbox :) Thanks

3:49 sfuentes_: I know you get plentyful criticism, but I think the comparisons are great (even if a bit strong/controvertial)

3:50 AWizzArd: sfuentes_: what's up? Is Lau again comparing?

3:50 Hi Lau :)

3:50 sfuentes_: and I hope that criticism won't stop you from completing your Haskell vs Clojure post :)

3:51 LauJensen: Hey AWizzArd

3:51 sfuentes_: cause you know the Haskell ppl are going to try to eat you alive

3:51 jdz: ~max

3:51 clojurebot: max people is 184

3:52 LauJensen: sfuentes_, 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/

3:52 49 lines :)

3:52 jdz: take that, AWizzArd

3:52 LauJensen: (still cant get it to compile)

3:52 sfuentes_: AWizzArd: he's doing a great job

3:52 AWizzArd: jdz: thanks man *thumbs up*

3:52 *g*

3:53 ,(.wait "abc" 2000)

3:53 clojurebot: java.lang.IllegalMonitorStateException

3:53 AWizzArd: Why IMSE?

3:53 LauJensen: sfuentes_, 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

3:54 AWizzArd, that only fires when you're not the owner doesn't it ?

3:54 Chousuke: I'm not a fan of "vs." comparisons though /:

3:54 LauJensen: Chousuke, truth be told, I'm not either. I had enough of those after the Scala rumble, which was good though

3:56 sfuentes_: I imagine comparisons are great for a task/problem at hand

3:57 some tools are better suited and purposely designed for certain tasks after all

3:57 LauJensen: I 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

3:58 I 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 :)

3:58 sfuentes_: Lau: What if the post was a wiki? :)

4:00 LauJensen: sfuentes_, 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 :)

4:00 octe: AWizzArd: in java you'd need to synchronize on "abc" first, afaik

4:00 so i don't really know how you'd do that in clojure?

4:00 sfuentes_: Lau: Specifically, why would you say it was a waste of time?

4:01 LauJensen: sfuentes_, because I wasn't expanding my horizon, I was just mutating objects in new ways, it was robotic programming so to speak

4:02 sfuentes_: Lau: makes sense .... but C# is still big business

4:02 hiredman: AWizzArd: use a blocking queue, or promise/deliver, or etc...

4:02 LauJensen: No doubt - And Python still has it's place :)

4:03 octe: (let [o (new Object)] (locking o (.wait o 200))),(locking [o new Object] (. wait

4:03 oops

4:03 ,(let [o (new Object)] (locking o (.wait o 200)))

4:03 clojurebot: nil

4:03 sfuentes_: i think the cobol ppl (however few) still get paid pretty well .... at least i imagine

4:05 but they are maintenance works :)

4:07 AWizzArd: I see.

4:08 So, locking will sync under the hood.

4:08 ,(doc locking)

4:08 clojurebot: "([x & body]); Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in all circumstances."

4:19 octe: AWizzArd: yup, just like in java you need to hold the monitor of the object

4:21 AWizzArd: And holding monitor means to synchronize?

4:21 octe: yes, pretty much on the jvm

5:22 snowwhite: ping

5:23 (contains? '(1 2 3) 2) ==> false so, seems in clojure list is not a collection?

5:23 Chousuke: no.

5:23 contains? checks for an index

5:23 not for values

5:23 use .contains

5:23 clojurebot: contains

5:23 clojurebot: Gabh mo leithscéal?

5:25 G0SUB: I am curious why (contains? '(1 2 3) 2) returns false.

5:25 Chousuke: lists aren't indexed .)

5:25 hiredman:

5:25 Chousuke: so there is no value for the key 2

5:25 hiredman: ,(doc contains?)

5:25 clojurebot: "([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'."

5:25 G0SUB: isn't a list a collection too? (count) works on a list, for example.

5:25 hiredman: *key*

5:25 *key*

5:25 tomoj: hmm.. key is the key

5:26 hiredman: lists don't have keys/indexs

5:26 Chousuke: clojurebot: 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

5:26 clojurebot: Ik begrijp

5:26 Chousuke: clojurebot: the-question is <alias> contains?

5:26 clojurebot: excusez-moi

5:26 Chousuke: hm

5:26 how does that work?

5:26 hiredman: it doesn't

5:26 arbscht_: or c.c.seq-utils/includes?

5:26 Chousuke: can't have aliases? :(

5:26 hiredman: nope

5:27 Chousuke: damn

5:27 I guess contains? should be renamed

5:27 it has the most frequently asked question here.

5:27 hiredman: I spent about two and a hald hours working replumbing clojurebot for derby

5:27 half

5:28 Chousuke: oh, it's db-backed now?

5:28 hiredman: haven't switch the live clojurebot over though

5:28 Chousuke: do you use clojureql?

5:28 hiredman: yeah

5:28 G0SUB: Chousuke: I agree. else the doc should be changed.

5:28 hiredman: storage branch on github

5:29 G0SUB: the doc cleary states *key*

5:29 if they *key* is present

5:29 and it says "will not perform linear search for a value"

5:30 G0SUB: hiredman: yeah, but it's not too clear.

5:30 Chousuke: has-key? would be a better name for contains ;(

5:34 tomoj: hiredman: what/where is the "storage" branch?

5:34 oh, you mean for clojurebot?

5:34 hiredman: yessir

5:35 tomoj: thought it was a branch of clojureql I hadn't seen

7:03 AWizzArd: ,(Integer/bitCount 1000000)

7:03 clojurebot: 7

7:03 AWizzArd: ,(Integer/bitCount 9999999)

7:03 clojurebot: 14

7:04 AWizzArd: ,(Integer/bitCount 2999999)

7:04 clojurebot: 15

7:20 AWizzArd: There is a reader macro for producing BigDecimal objects:

7:20 ,(class 123M)

7:20 clojurebot: java.math.BigDecimal

7:21 AWizzArd: Is there something similar for BigIntegers?

8:31 amatos: I 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?

9:12 chouser: (package-alias 'java.util.concurrent 'conc) (conc.LinkedBlockingQueue.) ; wouldn't this be nice?

9:13 cgrand: +1

9:14 chouser: though what I actually want is nested class aliasing, which is probably more controversial

9:14 s/actually want/want at the moment/

9:15 AWizzArd: chouser: would it be possible to have re-seq taking an optional fn which defaults to re-groups?

9:16 chouser: AWizzArd: of course it would be *possible*

9:18 AWizzArd: and 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

9:20 chouser: AWizzArd: type hints should flow through with-open bindings

9:20 AWizzArd: good

9:21 amatos: I 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?

9:25 Should I be using a more recent version of clojure?

9:27 AWizzArd: amatos: 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.

9:30 amatos: How stable is clojure straight from github? Is that what most people use? I am a bit concerned with stability...

9:33 chouser: amatos: 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.

9:34 amatos: 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.

9:35 amatos: chouser: thanks a lot. I'll give that a shot

9:36 chouser: if 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. :-)

9:36 amatos: sure :)

9:37 well, at least now it seems to be working! Thanks a lot :)

9:40 AWizzArd: amatos: 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.

9:41 amatos: ok, thanks. I'll give that a try

10:42 Chousuke: *sigh*

10:42 why is syntax-quote symbol qualifying so damn complicated ;(

10:43 rhickey: Chousuke: how so?

10:48 Chousuke: rhickey: 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:49 rhickey: oh, complicated to implement vs complicated to use?

10:49 Chousuke: yeah

10:49 my current attempt is already rather messy

10:55 chouser: the longer I use Clojure, the more I tend to forget how much worse the alternatives are

10:55 I need to find a forum where I can teach it to people and watch them "get it"

10:56 raek: speaking of teaching

10:57 cemerick: I still trip over the class vs. class-symbol thing more regularly than I should admit.

10:58 chouser: cemerick: in type hints?

10:58 raek: clojure and its data structures will probably be mentioned in the course "data and program structures" I will attend next spring

10:58 I might even be the person speaking about it

10:59 cemerick: chouser: in the context of macro-writing, yes.

10:59 raek: Anders Haraldsson seems to be interested in clojure

11:01 has there been held any courses in clojure at universities?

11:14 Chousuke: http://gist.github.com/211019 hm, this looks okay

11:16 somnium: is there a recommended way to convert a java.util.HashMap to a persistent clojure map?

11:17 Chousuke: (into {} themap)

11:17 somnium: awesome

11:18 the mongodb java api fits clojure like a glove

11:18 Chousuke: oh bugger

11:18 now my clojure doesn't build anymore.

11:19 chouser: running core.clj through your reader?

11:19 Chousuke: nah, just trying to fix up syntax-quote

11:19 I love this informative error message

11:20 /build.xml:89: java.lang.ExceptionInInitializerError

11:25 hm, the caveats of repl-driven development...

11:29 the unavailability of even the most basic macros hurts :P

11:35 somnium: would it be worthwhile to subclass the associative clojure data structures and implement the db persistence interface for direct persistence?

11:35 it would make for a seamless wrapper, but I'm wondering if the default mutable java classes are better for db persistence

11:37 cemerick: somnium: that's something I'm planning on doing for a jdbm wrapper I wrote last month

11:38 somnium: I 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:39 raek: wouldn't it be very clojure-ish to have db persistance in a ref rather than a map?

11:39 somnium: raek: the ref has to contain some sort of datastructure right?

11:40 raek: the implementation of the ref, or the value contained in the ref?

11:40 cemerick: depends 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:43 raek: i was thinking about something like this:

11:43 (def pref (persistent-ref "file.db"))

11:44 and then @pref would give the value last set to it

11:45 tomoj: but transactions can be retried

11:45 is there a way to say, if this transaction fails, do this before retrying?

11:46 (so you could use a database transaction in your STM transaction?)

11:46 raek: couldn't one just make a watcher that watches the state change of a ref and store that to a file?

11:47 tomoj: I suppose, but it's not ACID

11:47 raek: tomoj: hmm, i suppose not

11:48 tomoj: an STM transaction which wraps a DB transaction will be ACID, right?

11:48 chouser: rhickey's been talking about tweaking the STM to allow tying external transactions to it.

11:48 I don't know if that would be enough to get ACID, but you'd be closer.

11:49 tomoj: is what's needed some way to say "do this to rollback my DB transaction if this STM transaction fails"?

11:50 and, "fail this STM transaction if such and such happens because the DB transaction failed"

11:51 chouser: until then a watcher would be pretty easy

11:51 a watcher on a ref won't fire until the transaction is committing.

11:52 tomoj: STM 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:54 chouser: hm, an exception in a watcher doesn't prevent the transaction from committing. I guess that's not shocking.

11:55 ,(let [r (ref 0)] (add-watch r nil #(throw (Exception. (str %4)))) (try (dosync (alter r inc)) (catch Exception _)) @r)

11:55 clojurebot: chouser: excusez-moi

11:55 tomoj: or unplugging the computer while the watcher is doing its thing

11:55 chouser: oh, no try/catch, eh?

11:57 ,(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:57 clojurebot: 1

12:05 AndiXng: hi. can anybody help me creating a double[][] array?

12:05 i need it for initializing a TableLayout

12:07 kotarak: I think make-array can multidim: (make-array Double/TYPE 10 10) or so.

12:07 (doc make-array)

12:07 clojurebot: "([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:08 AndiXng: thanks :)

12:09 and 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:15 somnium: ,(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:15 clojurebot: (#<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:16 AndiXng: ok, i have custom values, thanks anyway

12:17 cgrand: ,(into-array (map (partial into-array Double/TYPE) (repeat 4 (range 6))))

12:17 clojurebot: #<double[][] [[D@1eae719>

12:19 cgrand: ,(into-array (map (partial into-array Double/TYPE) [[1 2] [3 4]]))

12:19 clojurebot: #<double[][] [[D@6f6266>

12:20 cgrand: AndiXng: ^^

12:20 AndiXng: ,(seq (into-array (map (partial into-array Double/TYPE) [[1 2 3 4 5] [3 4]])))

12:20 clojurebot: (#<double[] [D@17fc253> #<double[] [D@aee53f>)

12:20 AndiXng: this TableLayout has really a poor design ;)

12:21 cgrand: ,(map seq (into-array (map (partial into-array Double/TYPE) [[1 2 3 4 5] [3 4]]))))

12:21 clojurebot: ((1.0 2.0 3.0 4.0 5.0) (3.0 4.0))

12:23 AndiXng: cgrand: works like a charm, thanks

12:24 cgrand: yw

12:43 AWizzArd: Damn, 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:44 And also: (count (rest @index)) ==> 513971

12:45 How is that possible? How can (= (dec (count @index)) (count (rest @index))) be false?

12:46 Chousuke: are you sure it didn't change in the middle?

12:46 AWizzArd: 100% sure

12:46 I can eval this now in the repl.

12:46 I always get these numbers.

12:47 Chousuke: do you have test code to replicate this?

12:47 AWizzArd: I can see if I can get code.

12:49 Chousuke: I think at some point there was a bug with hash-map counting... are you running an older version?

12:50 or maybe this is just another bug :P

12:51 AWizzArd: It'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:51 got to go now, tomorrow maybe more about it

12:55 cgrand: AWizzArd: is your clojure up to date?

12:56 there was several "count" bugs in the new PersistentHashMap (mea culpa)

12:56 were even

13:46 kefka: ,(binding [*print-dup* true] (pr-str 5))

13:46 clojurebot: "5"

13:46 kefka: ,(binding [*print-dup* true] (pr-str {:a 4}))

13:46 clojurebot: "#=(clojure.lang.PersistentArrayMap/create {:a 4})"

13:46 kefka: ,(binding [*print-dup* true] (long 5))

13:46 clojurebot: 5

13:46 kefka: ,(binding [*print-dup* true] (pr-str (long 5)))

13:46 clojurebot: "#=(java.lang.Long. \"5\")"

13:48 kefka: ,(binding [*print-dup* true] (pr-str (symbol "nil")))

13:48 clojurebot: "nil"

13:49 kefka: ,(binding [*print-dup* true] (pr-str nil))

13:49 clojurebot: "nil"

13:49 kefka: ,(= nil (symbol "nil"))

13:49 clojurebot: false

13:49 kefka: Shouldn't the print-dups be different?

13:50 Chousuke: you don't want a symbol called nil

13:50 that'll break things

13:50 kefka: ok.

13:51 I'd never use a symbol called nil

13:51 but I thought print-dup was designed so as to be completely unambiguous

13:51 chouser: Chousuke: I don't think that's right, actually.

13:51 oh

13:51 hm

13:52 sorry, I'm wrong. Chousuke's right.

13:52 'symbol' currently is far too permissive, allowing you to create all kinds of symbols that cause problems later

13:53 I guess "nil" should be one that it refuses to do.

13:53 technomancy: chouser: I have a patch for that!

13:53 well, for unreadable symbols

13:53 not for nil and such

13:53 chouser: nil is an unreadable symbol though, actually.

13:53 kefka: On a related note:

13:53 chouser: the text "nil" reads as the value nil not as the symbol nil

13:53 technomancy: oh, sure; that's handy

13:54 kefka: ,(binding [*print-readably* true] (pr-str Double/POSITIVE_INFINITY))

13:54 clojurebot: "Infinity"

13:54 technomancy: ~ticket 17

13:54 clojurebot: I don't understand.

13:54 kefka: which the reader converts to the symbol 'Infinity

13:54 technomancy: ~#17

13:54 clojurebot: Huh?

13:54 somnium: ,(symbol "#^%foo")

13:54 clojurebot: #^%foo

13:54 technomancy: ~ticket #17

13:55 clojurebot: {: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:55 chouser: kefka: bleh. yep, that's no good.

13:58 ambient: implementing a modular synth with clojure infinite seqs as streams is about 200x as slow as with C :/

13:59 chouser: ambient: yeah, I was worried about your seq performance

14:00 ambient: with 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:00 chouser: ambient: 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:00 ambient: :(

14:01 streams just would be so elegant in this situation

14:01 chouser: there's probably also a box/unbox performance hit

14:02 Chousuke: seqs don't make very good streams I guess :/

14:02 chouser: I know collections of primitives are planned -- I don't know if that will include seqs or not.

14:02 chunked seqs of primitives might get you a lot closer to C's speed, but I'm not sure.

14:03 ambient: you're only using one processor core, right?

14:03 technomancy: ooh, my fixtures patch got approved; sweet.

14:03 ambient: yes, i tried utilising 2 cores but it took 3 times longer

14:04 chouser: heh. oh.

14:04 Chousuke: I think rich was working on streams at some point.

14:04 what became of that, I wonder.

14:04 ambient: chouser good tip about chunked seqs, is there any documentation other than i found from google?

14:04 slashus2: I think chunked seqs took priority.

14:05 chouser: Chousuke: dead end. I think chunked seqs address some of the same problems streams were meant to.

14:05 ambient: probably not. it may be that you're using them already.

14:06 jedediah: Is it possible to send a vector to a java function that expects a list? (Specifically, I'm looking at java.util.Collections

14:06 Chousuke: I 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:07 ambient: idk perhaps i could hack some sliding window thingie, using unboxed float vector, together that could emulate streams

14:08 technomancy: jedediah: try calling seq on it

14:08 rstehwien1: chouser: by chunked sequences do you mean something like (doseq [chunk (su/partition-all 256 bytes)] (.update crc (into-array Byte/TYPE chunk)))

14:08 where bytes is a lazy-seq of bytes

14:09 jedediah: technomancy: thanks

14:09 Chousuke: rstehwien1: no, chunked seqs just take advantage of the inherent chunkiness of some clojure data structures

14:10 chouser: also some seq generators produce chunked seqs, such as range

14:10 Chousuke: eg. vectors are really internally made of chunks of 32, so processing each item lazily adds ~32 times more overhead than you need :P

14:10 chouser: ,(class (seq (range 100)))

14:10 clojurebot: clojure.lang.ChunkedCons

14:11 rstehwien1: chousuke: 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:11 byte

14:11 chouser: no, currently each item in a chunked seq is still boxed. I don't know if there are plans for chunks of primitives.

14:12 Chousuke: I 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:13 I don't think Clojure's going to be as fast as C or plain java for sound processing any time soon, though.

14:14 rstehwien1: chouser: 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:14 chouser: I think sound processing is one of rhickey's target application spaces. I think that's what all the array support is for.

14:18 ambient: if you want to hear some sound processing, here's a piece http://paste.pocoo.org/raw/145131/

14:18 recognize the song? ;)

14:26 somnium: is there a way to check for interfaces on objects like for classes?

14:26 technomancy: (doc isa?)

14:26 clojurebot: "([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:27 kotarak: ,(instance? clojure.lang.ISeq (list 1))

14:27 clojurebot: true

14:28 kotarak: ,(instance? (type (list 1)) clojure.lang.ISeq)

14:28 clojurebot: false

14:28 kotarak: ,(isa? (type (list 1)) clojure.lang.ISeq)

14:28 clojurebot: true

14:30 somnium: ty

14:30 namor: just how do you append two sequences?

14:30 ambient: lazy-cat

14:31 (lazy-cat (take 10 first-seq) (take 10 second-seq)) that's how i dun it

14:31 kotarak: or concat

14:31 ambient: or you could just concat.. ye :p

14:31 namor: Ah, that's it! I was searching for something like "append".

14:32 Thanks!

14:32 kotarak: ,(let [x (concat (do (println 1) [1]) (do (println 2) [2]))] (first x))

14:32 clojurebot: 1

14:32 1 2

14:33 kotarak: ,(let [x (concat (do (println 1) [1]) (do (println 2) [2]) (do (println 3) [3]))] (first x))

14:33 clojurebot: 1

14:33 1 2 3

14:33 kotarak: ,(let [x (lazy-cat (do (println 1) [1]) (do (println 2) [2]) (do (println 3) [3]))] (first x))

14:33 clojurebot: 1

14:33 1

14:33 kotarak: That's the difference.

14:34 lazy-cat defers evaluation of its arguments. concat does not.

14:36 somnium: ... best javadoc I've ever seen: com.mongodb.util.WeakBag : "if it's not obvious what a weak bag should do, then, well..."

14:38 rstehwien1: ambient: I almost recognize the song. Going to read it a bit tonight I hope

14:39 The-Kenny: Hello? 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:42 arbscht_: (map :value (:rows {:rows [))

14:42 (map :value (:rows {:rows [ {:value {:age 42}}))

14:43 if pasting would ever work...

14:43 ,(map :value (:rows {:rows [{value {:age 42}} {:value {:age 23}}]}))

14:44 clojurebot: java.lang.Exception: Unable to resolve symbol: value in this context

14:44 arbscht_: ,(map :value (:rows {:rows [{:value {:age 42}} {:value {:age 23}}]}))

14:44 clojurebot: ({:age 42} {:age 23})

14:44 arbscht_: at last!

14:44 The-Kenny: arbscht_: Yeah, I'm aware of that. I tried to do this with bindings of let. Just to make some functions cleaner.

14:44 arbscht_: oh right

14:45 rstehwien1: Curious what I'm doing wrong with this function reader macro:

14:45 user> (map (fn [x] {x "hello"}) [1 2 3])

14:45 ({1 "hello"} {2 "hello"} {3 "hello"})

14:45 user> (map #({% "hello"}) [1 2 3])

14:45 ; Evaluation aborted.

14:45 user> "java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentArrayMap"

14:46 kotarak: ,(macroexpand-1 '#({:x :y}))

14:46 clojurebot: (fn* [] ({:x :y}))

14:46 kotarak: rstehwien1: do you see it now?

14:46 ,(map #(hash-map % "hello") [1 2 3])

14:46 clojurebot: ({1 "hello"} {2 "hello"} {3 "hello"})

14:46 rstehwien1: kotarak: Yes, nothing passed

14:47 kotarak: rstehwien1: ??

14:47 rstehwien1: kotorak: Thanks for the tip... must remember macroexpand-1

14:47 kotarak: you try to call a map, whithout arguments this gives an exception.

14:47 Chousuke: The-Kenny: I don't think what you want is possible with destructuring

14:47 rstehwien1: kotorak: Macro expanded to have no parameters.

14:48 The-Kenny: Chousuke: Okay, thank you.

14:49 kotarak: rstehwien1: no, #(foo) expands to (fn [] (foo)), your problem are the parens around foo.

14:49 ,(macroexpand-1 '#({% "hello"}))

14:49 clojurebot: (fn* [p1__5665] ({p1__5665 "hello"}))

14:49 Chousuke: I don't think macroexpand is actually necessary in that.

14:50 ,'#(foo)

14:50 clojurebot: (fn* [] (foo))

14:50 kotarak: ,String.

14:50 clojurebot: java.lang.ClassNotFoundException: String.

14:50 kotarak: ,'String.

14:50 clojurebot: String.

14:50 Chousuke: That's not actually reader magic

14:50 kotarak: ,'(String.)

14:50 clojurebot: (String.)

14:50 kotarak: Yeah.

14:51 Chousuke: which I am grateful of. it would complicate writing the reader a lot ;P

14:51 rstehwien1: ,'#({% "hello"})

14:51 clojurebot: (fn* [p1__5678] ({p1__5678 "hello"}))

14:51 kotarak: Well there is magic of that in the syntax-quote stuff.

14:51 ,`(String.)

14:51 clojurebot: (java.lang.String.)

14:51 Chousuke: oh, I know.

14:51 wanna see my syntax-quote implementation?

14:52 kotarak: ,`(.length (String.))

14:52 clojurebot: (.length (java.lang.String.))

14:53 kotarak: Chousuke: I dare to ask: you have a syntax-quote implementation?

14:53 Chousuke: yes

14:54 http://github.com/Chousuke/clojure/blob/sq-macro/src/clj/clojure/core.clj#L535 <-

14:54 it needs some cleanup though, but it works

14:54 at least, as far as I can tell D:

14:56 kotarak: Looks good. Is it part of cinc?

14:56 Chousuke: well, it could be, but there's no real cinc project going on yet :)

14:56 kotarak: mainly preparations, no?

14:57 Chousuke: yeah.

14:57 I think I could clean up the code a lot with some use of cons or conj ;P

14:59 or rather, I just wonder why I used (list* 'do (rest form)) instead of cons :/

15:00 I'll also need to fix it to transfer metadata I guess

15:00 somnium: ,(let [a {:b [:c :d]}] (doseq [[x [y z]] a] (println x y z)))

15:00 clojurebot: :b :c :d

15:01 somnium: ,(let [a {:b [:c :d]}] (let [[x [y z]] a] (println x y z)))

15:01 clojurebot: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap

15:01 qed: whaaa

15:01 somnium: are the destructuring semantics different for different binding forms?

15:02 Chousuke: no,

15:02 in doseq, you're destructuring each item of a

15:02 with let, you're trying to destructure a

15:03 somnium: ,(let [[_ a] {:foo :bar}] a)

15:03 clojurebot: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap

15:05 Chousuke: ,(let [{a :a} {:a 1}] a)

15:05 clojurebot: 1

15:05 somnium: aha

15:06 Chousuke: ,(let [[a & x] {:a 1 b 1}] [a x])

15:06 clojurebot: java.lang.Exception: Unable to resolve symbol: b in this context

15:06 Chousuke: ,(let [[a & x] {:a 1 :b 1}] [a x])

15:06 clojurebot: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap

15:06 Chousuke: ,(let [[a & x] (seq {:a 1 :b 1})] [a x])

15:06 clojurebot: [[:a 1] ([:b 1])]

15:08 Chousuke: ,(let [{{a :b} :a} {:a {:b 'c}}] a)

15:08 clojurebot: c

15:08 somnium: (let [a {:b [:c :d]}] (let [[x [y z]] (first (seq a))] (println x y z)))

15:08 ,(let [a {:b [:c :d]}] (let [[x [y z]] (first (seq a))] (println x y z)))

15:08 clojurebot: :b :c :d

15:09 Chousuke: map destructuring is a bit weird

15:09 the binding map is "inverted"

15:10 somnium: I wonder if it would be more intuitive if it was automatically seqed... or if that would lead to strange behavior elsewhere

15:24 cemerick: ugh, losing metadata because of an overly-casual into can be painful

15:26 chouser: hm. keeps the left-hand metadata, not the right-hand?

15:27 cemerick: eh, 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:30 chouser: ,(meta (into '#^{:some :meta} {e f} '{a b c d}))

15:30 clojurebot: nil

15:32 cemerick: no, it was more like (meta (into '{e f} '#^{:some :meta}{a b c d}))

15:32 but the metadata had been attached 5 layers deep

15:33 kefka: Here's a question: why is there no function that, given a var, returns its name as a symbol?

15:33 cemerick: definitely 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:33 kefka: I think we've all written one :-)

15:34 You can get at it via java method calls.

15:34 kefka: cemerick: what method calls?

15:34 Obviously, there's (symbol (substring (str v) 2)) but that seems hackish

15:34 I see the fields ns and name in clojure.lang.Var but no getNamespace or getName

15:34 those exist for symbol, though.

15:35 cemerick: lisppaste8: url?

15:35 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

15:35 cemerick pasted "kefka: var-sym fn" at http://paste.lisp.org/display/88694

15:36 cemerick: heh, I wrote that before I got to know -> :-D

15:40 LauJensen: Those JVM Summit vids up yet ?

15:41 ambient: not that i know of, at least not on infoq

15:41 LauJensen: ok, 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:44 ambient: btw, seems that intellij idea will be FREE (at least the basic version)

15:44 they're making a community edition

15:45 lpetit: ambient: Intellij's in trouble ,

15:45 ?

15:45 somnium: they'll need excellent clojure support to get me out of emacs

15:46 LauJensen: somnium, same here, and money

15:46 tomoj: LauJensen: what do you need those for so often? your mapped function has side-effects?

15:48 LauJensen: tomoj, like benchmarking forinstance, to get consitant results you need them forced.

15:48 But year, printing, rendering, something like that also demands it

15:49 chouser: I almost never use doall. I would use doseq instead of dorun+map

15:49 jevgeni: somnium: is the current clojure support in IDEA so bad?

15:50 ambient: i dont know. afaik rich uses IDEA

15:50 LauJensen: ambient, rich is on Emacs I think, no SLIME though

15:50 tomoj: chouser: agreed

15:51 ambient: i just watched his talk from july where he said he uses IDEA, might've switched after

15:51 LauJensen: Hmm... I don't remember him asking Stallman for permission... but I might have missed it

15:51 chouser: I think Rich uses intellij for Java

15:51 somnium: jevgeni: no idea. I've never actually used it. I downloaded ruby mine once but never actually used it :-p

15:52 Raynes-: The last time I used IDEA for Clojure, it was pretty good. I'm not sure if it's still being maintained.

15:52 somnium: enclojure is still a ways from emacs/vim

15:52 jevgeni: somnium: okay, I see:) I'm just newbie in clojure, wonder if I should learn emacs for it until it's not late)

15:52 ambient: i learned emacs for clojure...

15:53 it's really painful at the beginning but i got used to it

15:53 Raynes-: I didn't have to learn Emacs. I learned about 6 commands, and here I am today.

15:53 ambient: when i got emacs configured and memorized about 20 keyboard shortcuts i was ok

15:54 somnium: learning clojure helps to learn to read elisp too

15:54 jevgeni: Raynes: don't you use sophisticated things like refactorings/etc? Or this is not the case with the clojure?

15:54 Raynes: No, I don't really use anything like that with any language.

15:54 ambient: somnium although i wish there was emacs-light written in clojure ;)

15:54 Raynes: And if I need to do something with Emacs that I don't know how to do, I simply google it.

15:54 LauJensen: anyway, about (doall (map ...)) I recommend a Common Lisp style naming: map-which-is-not-lazily-evaluated-because-it-is-being-forced-instead

15:55 Raynes: I typically have to look at a reference just to remember how to search and replace.

15:55 somnium: jevgeni: most dynamically typed languages don't need a lot of refactoring tools

15:55 jevgeni: okay, I see. probably this is not so scary as seems :)

15:55 Raynes: Functional programming isn't scary, and anyone who tells you otherwise has never used functional programming.

15:56 And Lisp in general just /looks/ scary.

15:56 jevgeni: I was rather talking about the emacs as ide

15:56 Raynes: Oh.

15:56 Emacs isn't scary at all.

15:56 tomoj: jevgeni: +1 for emacs

15:56 takes a bit of getting used to

15:56 Raynes: Especially with Google on your side.

15:57 somnium: I think all the google hits involving monads make functional programming scarier than it is

15:57 tomoj: I think it's quite scary at first

15:57 but I got used to it and now I can't live without it

15:57 technomancy: somnium: doesn't help that everyone who first learns Haskell somehow feels compelled to write a monad tutorial once they get it.

15:57 ambient: i got my most used Emacs stuff in google docs, i'll see if i can publish it

15:57 chouser: the emacs learning curve is roughly proportional to your depth of knowledge about your current editor.

15:58 Raynes: technomancy: 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:58 technomancy: Raynes: how do you know you _really_ got it then?

15:58 ambient: jevgeni here: http://tommih.blogspot.com/2009/10/emacs-shortcuts.html

15:58 Raynes: I asked people.

15:58 technomancy: if you got it you would be all like "Monads are so cool! they're ... they're monads! See?"

15:59 somnium: question: since clojure explicitly makes room for side effects, is there any pragmatic reason to really grok monads (when using clojure)?

15:59 jevgeni: ambient: thanks

15:59 Raynes: It 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:59 tomoj: I still don't get it

15:59 namor: me neither

16:00 tomoj: in the process of learning haskell though, maybe I'll have a tutorial of my own soon :P

16:00 jevgeni: actually I use the emacs for org mode, but I shall give it another try for clojure

16:00 * technomancy suspects it's a bit like dependency injection. you have no hope of ever understanding DI unless you have spent a lot of time working in poor languages

16:00 technomancy: except for the "poor languages" part

16:07 LauJensen: Speaking of Haskell. Those of you who read my Brians Brain post, please see an excellent translation to Haskell here http://blog.willdonnelly.net/

16:08 mwoelker: Is there a good intro/video tutorial on using emacs/slime? I googled but only found listings of keyboard shortcuts

16:08 ambient: i might have to do that with python in one line

16:09 mwoelker: I guess what I would like is an "over the shoulder view" to see the actual workflow

16:09 Is code written in the REPL and then pasted to a clj when it works?

16:09 ambient: it can be

16:09 mwoelker: Is it written in then clj and then execute from there?

16:09 LauJensen: ambient, 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:09 ambient: or written in editor and pasted to repl

16:09 dnolen: mwoekler: you can just start writing code in a .clj file then send it to the repl.

16:10 ambient: LauJensen you really, really should look at numpy

16:10 technomancy: mwoelker: you generally send whole files or defns to the repl at a time

16:11 mwoelker: How about managing multiple and/or larger projects? I really like having some sort of structure, and quick navigation to symbol definitions.

16:12 I 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:12 technomancy: yeah, you can jump to the definition of any var easily

16:13 you just have to learn the build-in help commands, they will show you all the available features

16:13 ambient: mwoelker as for larger projects, clojure namespaces are enough for me

16:13 somnium: mwoelker: for common lisp, but over-the-shoulder-slime nonetheless -> http://www.guba.com/watch/3000054867

16:13 technomancy: it's just not as immediately visible as pulling down a menu-bar

16:13 yeah, it's very similar to the way you use slime with CL; so that video would be useful

16:14 ol3````: does slime-symbol completion work with clojure?

16:14 mwoelker: okay thanks I'll check that out

16:14 technomancy: ol3````: yeah, it should

16:14 * mwoelker gets popcorn

17:02 mwoelker: somnium: thanks for the link that was exactly what I was looking for

17:02 somnium: mwoelker: cool

17:14 trying to picture the recursions in clojure.walk is making my head spin, but they work like a charm.

17:35 chouser: mutable state is killing me

17:35 build() has already been called on this Builder.

17:37 oh, found it. grrrr.

17:47 lpetit: chouser: he ?

17:47 chouser: google protobufs have a java api that's "mostly" immutable

17:48 each kind of message has an immutable class and a mutable "builder"

17:48 lpetit: chouser: ok, now I shouldn't have asked :)

17:48 chouser: calling (.build builder) gives you an immutable message, but apparently breaks the builder so you can't use it anymore. :-P

17:49 technomancy: sounds like tranisents. =)

17:49 chouser: yeah, except I somehow doubt .build is constant-time ;-)

17:49 lpetit: ok, interesting

17:49 hiredman: that would be a neat trick

17:50 chouser: but now I figured out where my extra .build call is, I just need to copy the Java string into a C++ std::string ...

17:50 copy this

17:58 somnium: .. (def a (com.mongodb.BasicDBObject.))

17:58 (type a)

17:58 com.mongodb.BasicDBObject

17:58 (isa? a com.mongodb.BasicDBObject) => false

17:59 chouser: try 'instance?'

17:59 'isa?' is for comparing two classes

17:59 oh, and reverse the args.

17:59 (instance? com.mongodb.BasicDBObject a)

18:00 somnium: that worked

18:00 is there a rationale why isa? needs to be false though?

18:00 chouser: 'isa?' is for comparing two classes

18:01 ,(isa? Integer Number)

18:01 somnium: ,(doc isa?)

18:01 clojurebot: "([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:01 true

18:01 chouser: ,(isa? Integer Class)

18:01 clojurebot: false

18:01 chouser: ,(isa? Integer Object)

18:01 clojurebot: true

18:01 chouser: ,(instance? Integer Class)

18:01 clojurebot: false

18:02 chouser: ,(instance? Class Integer)

18:02 clojurebot: true

18:02 chouser: there. now you should be sufficiently confused that I can go have dinner before you come up with a follow-up question. :-)

18:02 somnium: I was sufficiently confused before :)

18:02 now I get it, but no still no idea why its that way...

18:03 so it goes

18:03 chouser: well, my point is that you can't have one function that does both jobs (instance? and isa?) consistently.

18:04 (instance? Class Integer) ==> true (isa? Integer Class) ==> false

18:04 mwoelker: is it clojure's birthday already?

18:05 somnium: right, damn classes. too bad java wasn't prototype based

18:05 chouser: mwoelker: 17th I think

18:06 hiredman: wow

18:06 time flies

18:12 Raynes: Will be 3 years wont it?

18:12 * Raynes will see if he can update the Wikipedia page before anyone else does.

18:17 chouser: 2

18:23 * technomancy always uses isa? as instance?

18:23 technomancy: since in English, "foo" is a String

18:24 somnium: I think it would be helpful if the doc string for isa? at least mentioned something about classes vs. instances

19:08 djpowell: hmm - trying to use clojure.main/repl to do a socket repl, but it doesn't seem to die when the client disconnects

19:10 hiredman: why would it?

19:10 djpowell: i was hoping it would throw an exception or something

19:10 or eof

19:11 technomancy: djpowell: there's a socket repl in contrib; have you seen that?

19:12 djpowell: ill take a look

20:00 qed: god clojure is interesting

20:00 i cant get enough of rich's talks/demos

20:23 ambient: i just realised that if one pronounces closure like clojure, one is lisping :p

20:24 *mind blown* ;)

20:56 chouser: ambient: heh

20:57 Raynes: qed: I'm contemplating building a shrine to Rich Hickey. Maybe we can exchange designs one day.

21:02 qed: Raynes: heh

21:02 Raynes: mine is just a picture of rich's hair

21:02 Raynes: Yeah. He has awesome hair.

21:02 qed: like a jewish afro

21:03 Raynes: <3

21:03 qed: but more anglo

21:04 Raynes: do you know how old he is

21:04 i feel like a jack ass because he's in the room

21:04 but im curious

21:11 Raynes: No idea.

21:11 Older than me.

21:19 chouser: Old enough to know better.

22:04 Raynes: Chouser: Touche.

22:55 hiredman: 19:59 hiredman : cljbot: how much do you know?

22:55 19:59 cljbot : I know 444 things

22:55 :D

22:59 durka42: let's teach him 222 more

23:01 hiredman: clojurebot's response is about 100 less

23:02 cljbot is the derby backed clojurebot of the future

23:03 seba: Hi, I have a simple question: how do you get current file's absolute path

23:03 *file* is relative .... getAbsolutPath uses the cwd .... so, won't work

23:03 durka42: simplicity can be deceptive :)

23:05 seba: 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:06 hiredman: getCanonicalPath

23:06 but I would really recomend you keep things classpath relative

23:06 seba: I get the same result using getCanonicalPath ... it also works from the cwd

23:06 let me explain my problem ... maybe I'm missing a simpler solution

23:07 I'm unit testing a function that gets resources from a directory

23:07 I created a sample directory of resources inside my test directory

23:08 I want to point my class to that sample directory in order to test it's output

23:08 hiredman: class?

23:08 seba: jeje sorry .... Ruby guy

23:09 the functions recibes a File as argument, and I would want to pass that sample directory to test the function

23:09 hiredman: so, uh, what is stoppping you?

23:09 seba: (this is my first clojure project: http://github.com/paraseba/clj-deps

23:10 the problem is .... I don't know how to get a File ... pointing to a directory without using absolute paths in the code

23:10 if I do (File. *file*) I end with a relative file ... so tests would depend on your current working directory

23:11 let me clarify with some more code

23:11 hiredman: but, uh, so does the non-absolute path to the directory

23:12 seba: sorry ... I didn't follow

23:14 hiredman: ok, so aslong as you aren't constantly change the relative directory structure of test/ to file.clj

23:14 but 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:17 seba: hiredman: great, thank you, I'll try that

23:37 jkoppel: I just got burned heavily by false java.lang.Booleans being considered true by 'if

23:38 hiredman: use Boolean/valueOf

23:38 jkoppel: Well

23:38 hiredman: or whatever

23:38 jkoppel: I'm not actually creating any Booleans manually

23:38 hiredman: where are you getting them from?

23:38 jkoppel: I'm writing a multiplayer app, sending actions in the form of PersistentStructMaps

23:39 The deserialization changes boolean primitives to Booleans

23:39 *serialization

23:39 hiredman: eh?

23:39 jkoppel: Identical code processing the actions on both sides, and debug prints say the input is dentical, but...not

23:39 I mean, I have things like this

23:39 hiredman: how are you serializing?

23:40 jkoppel: ObjectOutputStream

23:40 hiredman: well, there you go

23:40 jkoppel: Is there a better thing to use?

23:40 hiredman: prn

23:41 jkoppel: Hmm

23:41 Now 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:42 Though it's more than a bit limiting to constrain the online sections of my code to things that can

23:44 Also, that will suck for bandwidth, though I'll probably write custom code to compress the output beyond what ObjectOutputStream can do anyway

23:44 Thanks though!

23:44 chouser: you can use custom print-method handlers and #=() to read/write just about anything you want.

23:44 jkoppel: Thanks!

23:47 Having a bit of trouble finding information on that. I assume you mean add methods to a general function, but which one?

23:49 hiredman: clojurebot: how much do you know?

23:49 clojurebot: I know 444 things

23:50 durka42: clojurebot: are you cljbot, the derby robot from the future?

23:50 clojurebot: durka42: the fn created by future (like all fns) doesn't close over dynamicly scoped stuff

23:50 durka42: what a delightful non sequitur

23:50 chouser: jkkramer: (defmethod print-method [obj writer] ...)

23:51 oops. just missed jkoppel.

23:51 jkkramer: confused me for a second :)

23:51 hiredman: durka42: yes

23:51 chouser: jkkramer: :-) sorry.

23:52 hiredman: hmmm

Logging service provided by n01se.net