#clojure log - Jul 22 2008

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

6:27 meredydd: Hey - did anyone end up building (jmap)? I kinda got distracted over the weekend.

6:41 * meredydd waits for rhickey

7:23 meredydd: hey, rhickey

7:23 rhickey: hey

7:23 meredydd: Had a question about (jmap)

7:23 rhickey: ok

7:24 meredydd: Wondering whether you'd consider a recursive version as well

7:24 give it a tree of Clojure collections, it gives you the same collection, but with every IPersistentMap replaced (or wrapped) with a Map

7:25 If you do it recursively, it solves the nested-Map problem I was talking about before the weekend

7:26 So, am wondering (a) Whether you think it's a good idea, and (b) if you did, what you thought of eager vs lazy translation

7:26 rhickey: If JavaMapOnPersistentMap implements both Map and IPersistentMap, is the only time you'd need this is if you were creating nested maps from literals?

7:27 i.e. if you always want maps that implement Map, won't you always use jmap to create them initially?

7:28 meredydd: Ah - the problem I'm trying to solve is the one where you have lots of Clojure code on one side, which is slinging normal Clojure collections around

7:28 and lots of Java code on the other side, which is slinging Java-idiomaic collections around

7:28 and you don't really want to (or, if you're using libraries, physically can't) embed knowledge about the one into the other

7:29 so you can't have the Java code slinging IPersistentMaps rather than java.util.Maps, and you can't have the Clojure code throwing (jmap) calls around everywhere

7:30 so you have to do translation in the glue code.

7:30 rhickey: then maybe it's more like jview - dynamically wrapping all values, but you'd want it on lists and vectors as well, no?

7:30 meredydd: yep

7:30 which is the plan

7:30 auto-wrapping Clojure lists, vectors, sets and maps in Java-idiomatic versions

7:31 (although vectors and sets should be able to implement java.util.List/Set anyway, so it's more about making sure that any maps contained within them are wrapped too. Maybe even lists too, although I haven't looked closely)

7:31 rhickey: at some point they'll implement List and Set, so it's only map values that won't be Maps

7:32 meredydd: Indeed. I'm prepping a patch to do List and Set implementations atm.

7:32 rhickey: I wonder if you are solving a real and not a theoretical problem

7:32 most idiomatic Java code mutates collections

7:33 meredydd: Hmm. I'm fairly sure I've seen collections with read-only semantics in the wild.

7:34 (otherwise, nobody would ever use the Collections.xxx() immutable singletons and empties in anger)

7:37 rhickey: yep, but note how they use a function (i.e. immutableMap), to get the view they want

7:37 unmodifiableMap

7:38 meredydd: Oh, absolutely - I'm not trying to claim that immutable collections are the norm or the default in Java

7:38 just that being able to pass them into Java code is likely to be useful

7:39 In any case, I don't want to have a huge head-butting about it. I have a definite need for a subset of (jview) functionality in my current project, so I've written a quick and dirty version

7:39 and I'll probably flesh it out to full functionality for my own use, sooner or later

7:40 rhickey: but by the time you get to the use case of having idiomatic Java code that expects nested immutable collections, I think it's less real than theoretical

7:40 meredydd: 'tis just a question of whether you'd be interested for mainline integration, and if so what sort of shape you'd prefer it to take.

7:40 rhickey: simple jmap first

7:41 meredydd: okies.

7:41 rhickey: (jmap amp) returns an instance of something that implements Map and IPersistentMap

7:41 meredydd: okay

7:42 rhickey: should probably be written in Java

7:42 meredydd: Yeah - the Clojure version is the basis of the quick and dirty hack :)

7:43 rhickey: also it should copy nothing, must implement emptySet, keySet and values with no copying

7:43 meredydd: Uh-huh.

7:43 rhickey: there may also be issues with hashCode semantics

7:44 meredydd: (Oh, sorry, of course - you never saw my java.util.Map implementation patch. I've already done that part.)

7:44 rhickey: Actually, that's something I'd left blank, pending questions about equality semantics

7:44 I'm *assuming* you'd want it to be equal() to the IPersistentMap it was created from

7:45 (in which case, hashCode() isn't so much of a problem)

7:45 * rhickey just looking to see if hashCode semantics are dictated by Map

7:46 rhickey: "The hash code of a map is defined to be the sum of the hashCodes of each entry in the map's entrySet view."

7:46 ugh

7:46 meredydd: Oh, bugger.

7:47 * meredydd checks how you currently do IPersistentMap hashcodes

7:48 meredydd: Could we not just change the algorithm for hashcode calculation in APersistentMap to match?

7:49 oh, hold on. It's already an addition :)

7:49 ...ignore that line. Util.hashCombine is an addition. APersistentMap does a ^=

7:50 Do you have great opposition to changing the APersistentMap calculation?

7:56 rhickey: but it also dictates that it be the sum of Map.Entry hashes, which it dictates be a lame ^ of key and value hashes

8:00 meredydd: ah.

8:02 Hmm...so, it's sacrifice equals()-equality with the source map, or equals()-equality with other java.util.Map implementations.

8:03 Can I ask something unrelated for a moment, please?

8:05 What would you say to allowing RT.print() to print Java collections in clojure reader syntax?

8:06 (trying to figure out whether to do that or to stop using reader syntax as my wire encoding and go to something custom)

8:15 rhickey: meredydd: at some point I want to move print out of RT and make it a proper multimethod. Printing for Java classes may move to JavaBeans XML serialization, so you can get back the same type

8:16 meredydd: Ooh, clever.

8:17 Off the top of my head, would a multimethod, dispatched on class, make it quite difficult to do, eg, a catch-all for "anything implementing Map"

8:17 ?

8:17 rhickey: yes

8:18 of course you can get 'anything implementing map' runtime polymorphism in Java either

8:19 still thinking about how best to leverage interfaces in multimethods

8:19 meredydd: Uhh...actually, that's one thing you can do. (In fact, pretty much the only thing you can do)

8:19 public static void print(Map m)

8:19 public static void print(Object o)

8:19 rhickey: that's compile-time overloading, not polymorphism

8:20 meredydd: Oh, point. In which case, yes.

8:20 hoeck: rhickey: gen-and-save-class doesn't create the package directory for the generated *.class property

8:21 rhickey: hoeck: correct

8:21 enough people seem to be asking for it that I might change that, my only concern was creating directories on typos

8:25 hoeck: you mean creating huge directories by accident?

8:27 rhickey: not huge, just wrong. I guess my thought was, the namespaces, and thus the corresponding directories, would be created fairly rarely If I don't create them, then it can catch typos

8:29 blackdog: rhickey, did you get to record any video in Europe?

8:31 rhickey: blackdog: I did get a screencast recording of the Lisp workshop, nothing from Dynamic Languages Symposium. I'm holding off on posting the Lisp Workshop as I'm giving a very similar talk to the Boston Lisp Group in September

8:32 blackdog: ok, thx

8:33 hoeck: rhickey: okay, what about providing a 'create-dir' flag to genclass. I was fairly confused that it didn't wrote the dirs, and i thought is was my mistake ... until i read the java docs

8:34 or maybe just mention it in the docs that the dir has to be created by hand

8:35 rhickey: hoeck: hmm... (doc gen-and-save-class)

8:36 hoeck: I'm not opposed to the flag

8:43 * hoeck is reading (doc gen-and-save-class)

8:45 * hoeck recognizes the phrase: "the directories for which must already exist"

9:20 toyvo: Hi! Does anyone know where to look for documentation on the exact let form semantics? I'm thoroughly confused.

9:20 rhickey: toyvo: http://clojure.org/special_forms

9:21 toyvo: Been there. However let doesn't seem to nest with def as I expect.

9:22 (do (def y) (let [y* y] (def y 1) y*))

9:22 rhickey: toyvo: def is not Scheme define, def is always global definition

9:23 toyvo: rihickey: I almost got that; however, I thought let is like Scheme let*

9:23 rhickey: if you say (def y 1) at any level in namespace user, you are saying - I want user/y to be 1

9:23 let does bind sequentially

9:23 toyvo: Yes, but why the expression above gives an error?

9:24 It says y is unbound (presumably the issue is in (let [y* _y_]

9:24 I thought (let [y* y] ..) would mean let y* stand for y in what follows

9:24 rhickey: (def y) leaves y unbound, but your let tries to take its value in order to initialize y*

9:25 toyvo: Exactly. But let shouldn't *take* values, or should it? Hm...

9:25 rhickey: let is not an aliasing mechanism

9:25 toyvo: Ok, is there an aliasing mechanism?

9:25 rhickey: let binds names to the values of expressions

9:26 toyvo: Evaluating the expressions?

9:26 Oh, ok.

9:26 rhickey: yes, it's not a lazy language

9:26 toyvo: Right :) My fault.

9:27 So, is there an aliasing mechanism?

9:27 rhickey: there's no aliasing for vars at the moment, what are you trying to achieve?

9:27 toyvo: I'm trying to get at letrec, as a macro perhaps

9:28 rhickey: ah

9:28 letrec really needs language-level support

9:29 toyvo: Well a really heavy macro can do that, basically implementing a subset fo scheme, but that's going to be heaevy

9:29 Wasn't Scheme implemented on top of CL in the good old days...

9:30 rhickey: the problem is, if you ar ecoming from Scheme, you might be used to mutually recursive letrec Schemes for state machines etc, but because Clojure has no TCO, that's not a good thing to emulate

9:30 letrec schemes

9:31 right no, only top-level defns can be mutually recursive. If you want them to be private implementation details, you can use defn-

9:31 right now

9:32 toyvo: Yes, I know the no-TCO implications. Still, I'm kind of used to locally define functions inside other functions (it's the same in Scheme, Haskell, ML maybe)...

9:32 Ah.. Private functions? How private are those?

9:32 rhickey: you can totally define local functions, just not mutually recursive ones. just use (let [foo (fn []...)...

9:33 toyvo: Yes, that's what I do when they do not recurse.

9:33 Let me look up the docs on defn-

9:34 As a side note - is 'array?' predicate missing? 'vector?' is there

9:34 rhickey: and they can self-recurse (let [foo (fn self [] ... (self)...

9:36 all of these blah? type predicates are kind of tedious. Maybe they made sense in Scheme where there are only 5 types, but once in a richer language with an open type set, at some point people have to deal with instance? (not directed at you, this comes up a lot)

9:37 toyvo: That being said, (partial instace? clojure.lang.IPersistentList) is a bit verbose, is it not?

9:37 Chouser: #(instance? IPersistentList %)

9:37 toyvo: that's better :)

9:38 Chouser: of course that requires an (import), but you wanted to do that anyway. :-)

9:38 toyvo: But still.. What I though of, is perhaps have a (type x) function, to returns keywords. That would help a lot. For example, to write polymorphics that dispatch on type.

9:39 rhickey: array? is an interesting case, as there is no common base type - > (.isArray (class x))

9:39 toyvo: why not (class x) ?

9:39 toyvo: Yes, I thought about that. How about representing their 'types' with vectors of subtype? Like [:java.lang.String]

9:40 rhickey: what' wrong with classes?

9:40 what's

9:41 toyvo: rhickey: hmm.. like you say - arrays; also, what are semantically clojure lists can be represented by different classes

9:41 Chouser: that one comes up a lot too.

9:41 rhickey: Still, there's no reason to parallel the type system with keywords IMO.

9:42 instance? can check for interfaces

9:42 Chouser: toyvo: "semantically clojure lists" means things that (seq) works on?

9:43 toyvo: Chouser: no. Sometimes you want to differentiate between lists and vectors. That's the case I have in mind.

9:44 Okay then - if the language stick with (instance?) checks, for consistency - why don't drop vector? predicate :)

9:44 Chouser: hm. seq? might do what you want, I guess depending on what you mean by "list"

9:44 toyvo: list as in IPersistentList

9:44 rhickey: See - once you define list then you have to keep explaining what it means

9:44 seq?

9:44 toyvo: Ah

9:45 rhickey: all the predicates

9:45 There are some useful marker interfaces too, like Sequential

9:45 toyvo: Ah (seq? [1 2 3]) is false.. Nice. i didn't know that.

9:46 rhickey: user=> (seq? ())

9:46 false

9:46 toyvo: Why is that?

9:46 rhickey: see?

9:46 because an empty list is not a seq

9:46 toyvo: Oh my

9:46 rhickey: a seq always has a first

9:47 otherwise it would be nil

9:47 most lists are their own seqs, but not ()

9:47 toyvo: I'm used to this definition: List x = Nil | Cons x (List x)

9:48 So seq? is actually testing for Cons part

9:48 rhickey: nil can represent any type, so the type constructor analogy breaks rapidly

9:49 seq? tests for ISeq

9:49 toyvo: Wonderful Java platform :)

9:49 OK, I'll check that.

9:50 Maybe I'll have to write about this on the Wiki, in the "for Scheme programmers" section

9:51 Can I build the Javadocs for Clojure? Or are they online?

9:51 To look up ISeq and all the rest/

9:51 rhickey: This is Clojure design, and it is nice, but one can't take the presumptions of a world with one (concrete!) list type and apply them to one with a rich set of overlapping abstractions

9:51 Chouser did a neat class diagram

9:53 http://groups.google.com/group/clojure/msg/ef51d43ea0898c81

9:53 Chouser: I need to post a new one, that one's a bit out of date.

9:53 toyvo: Thanks

9:53 But still - can the javadocs be built?

9:54 rhickey: toyvo: I think you can always get a mechanical JavaDoc, but I haven't manually written any yet - sorry

9:54 toyvo: No problem... Hopefully it will come later. You are doing a great job anyway.

9:56 Another q: Is there a structure preserving map? like (fmap (partial + 1) [1 2 3]) -> [2 3 4]

9:56 meredydd: rhickey: Okay, I think I have a patch with List and Set support

9:57 covering APersistentVector, ASeq, and APersistentSet

9:57 Need to test it properly, though

10:06 toyvo: I modified the ANT buildfile to have a new target, docs, which builds the javadocs. Should I mail the tiny patch?

10:06 rhickey: toyvo: (into (empty x) (map f x))

10:07 toyvo: rhickey: yes, but that has not polimorphism. I want fmap to preserve structure (list to list, vector to vector, set to set)

10:08 You can also view the (mechanical) javadocs here http://clojure.fajno.net/

10:08 rhickey: empty is polymorphic

10:08 toyvo: Ah

10:08 Nie

10:08 Nice

10:09 meredydd: rhickey: I think I have a patch for List and Set support. Also (dependently), I've modified RT.print() to work with all Lists, Sets and Maps with normal reader syntax.

10:09 rhickey: meredydd: cool, can you post (List/Set patch) to the group? print I'd like to consider separately

10:10 toyvo: would it be possible to limit to just clojure.lang, asm is an implementation detail

10:11 toyvo: I will try! It gave me an error before, but I'll try.

10:16 meredydd: meredydd: Okay. There's a slight overlap, in that both modify RT (I've made subvec() return APersistentVector, so as to make subList() work), but it's trivial

10:16 toyvo: rhickey: limited to clojure.lang, uploading.

11:00 meredydd: rhickey: Posted. Feedback welcome.

11:49 rhickey: meredydd: still looking at it. I kind of hate the List interface for non-indexed collections (not your fault, it's just such a bad fit)

11:50 personally, I wouldn't support it for other than vectors

12:03 meredydd: I don't think all Lists should print like [..], only RandomAccess derivees

12:42 i've made vectors implement java.util.List and sets implement java.util.Set

12:48 lisppaste8: drewr pasted "Function dispatch on string" at http://paste.lisp.org/display/64047

12:49 drewr: I need (symbol ~cmd) to return the function pointed to by that name. What am I overthinking here?

12:50 Chouser: cmd is a string?

12:50 drewr: Yes.

12:52 (dispatch-cmd "foo" 1 2 3) should expand to (apply foo '(1 2 3)). At least I think that's the way I want to do it.

12:52 Chouser: I think to go from string to function you'll need eval.

12:52 and if not, rhickey will just in here and shout at me in a moment.

12:53 (defmacro dispatch-cmd [cmd & args] `((eval (symbol ~cmd)) ~@args))

12:54 that's dropping the args in place rather than going through apply.

12:56 drewr: Yeah, that works for me.

12:56 Chouser: gah, no

12:56 (defmacro dispatch-cmd [cmd & args] `(~(symbol cmd) ~@args))

12:56 that's what you (and I!) were over-thinking.

12:57 drewr: Ahhh. Yes.

13:07 meredydd: rhickey: Hmm. That's two halves of the same thing.

13:07 rhickey: There's a definite mismatch with sequences, which are most definitely ordered but a pain to index

13:08 rhickey: OTOH, Java treats LinkedList as a List, so I reckoned it should be your call.

13:09 rhickey: I'm also happy with only RandomAccess being printed with [...] - but can we have (...) for everything else, in that case?

13:09 (in fact, (...) for all Iterables would be swell)

13:15 lisppaste8: drewr pasted "Exception not caught" at http://paste.lisp.org/display/64050

13:16 drewr: I don't understand this. (bar) is throwing the same exception I caught just before it. Am I missing a paren somewhere?

13:19 kotarak: I suppose this exception is thrown during compilation because bar is not defined. But your code only catches exceptions at runtime.

13:20 drewr: kotarak: Yes, that's probably correct.

13:21 meredydd: drewr: (try (eval '(bar)) (catch Exception e "darn!"))

13:22 Delay compilation till runtime, and run-time (try) will catch it

13:24 drewr: meredydd: Good call. Thanks.

13:38 rhickey: meredydd: as I said earlier, I might want to do a printed version of Java data types that reads as the original type, so unifying with the Clojure types would not be something I'd want to promise long-term (request for a flag coming, I'm sure :)

13:39 meredydd: heheh

13:39 Actually, for once, no (at least not from me)

13:39 But is that a "go" for [...] for vectors?

13:40 rhickey: not if I later want ArrayList's print representation to read an ArrayList

13:40 meredydd: Okay, so that's a no then

13:40 (or "not in the immediate future")

13:41 * meredydd adds a java collections to clojure data structures fn to his todo list

13:42 rhickey: meredydd: wouldn't you want read/print for Java types?

14:43 stacktracer: is there a bug tracker for clojure?

14:43 rhickey: do you have a bug?

14:44 stacktracer: yes, unless I'm misunderstanding something

14:44 rhickey: you can paste it

14:44 stacktracer: Numbers.java, line 1311

14:44 sure

14:45 in Numbers.double_array(sizeOrSeq), the value assigned to ret[i] is truncated to an int

14:46 (let [a (double-array '(1.2 2.3))] (aget a 1))

14:46 gives:

14:46 2.0

14:47 (I expected it to give 2.3)

14:50 similar thing with float_array at Numbers.java:1280

14:51 rhickey: all fixed - thanks for the report

14:52 stacktracer: awesome -- thanks

14:52 kotarak: bugtracker? what for? ;)

14:56 rhickey: kotarak: exactly

14:56 outstanding bugs are just a source of stress

14:56 kotarak: no pet bugs, my motto

16:29 Chouser: rhickey: are you at all sympathetic to reader syntax for apply? Something like (f @args) instead of (apply f args)?

16:30 hm, not @ of course. or * (like python).

16:33 rhickey: Chouser: probably not - the best argument for reader syntax is to remove a set of parens, which this doesn't

16:33 Chouser: ok

16:37 hoeck: rhickey: what about a reader macro like & but not generating a list but instead a hashmap?

16:37 mebaran151: what's the best way to do io in clojure

16:37 it seems rather unfortunate to have to call into nasty java to do reads

16:38 rhickey: hoeck: looking for keyword args are you?

16:39 * hoeck is rolling his eyes

16:39 hoeck: rhickey: yeah, kind of

16:40 cemerick: oh noes, not more standard read macros! :-)

16:40 rhickey: I keep thinking this should just be a destructuring variant, but haven't thought much more than that about it

16:40 hoeck: just a thought, i'm doing pretty well with hashmaps

16:40 cemerick: rhickey: You mentioned you were taking the reflection out of proxy at some point; has that happened, or not yet? (I've been concentrating elsewhere of late.)

16:40 rhickey: there aren't going to be any infix ops, read-macro or otherwise, this is not Arc

16:41 hoeck: i often come across (defn fun [arg options] where options is a hashmap and then somewhere in the function body: (merge options *default-options*)

16:42 rhickey: hoeck: it would be easy to write a defnk macro that did the boilerplate for you

16:43 cemerick: I haven't figured out if it is possible yet

16:47 hoeck: rhickey: what do you think about keyword args, good/bad/ugly??

16:48 rhickey: hoeck: I like them, but they are not primitive, so not in fn

16:51 hoeck: this is an old one I whipped up, even easier now: http://groups.google.com/group/clojure/msg/51bb53ca077154f8

16:52 cemerick: rhickey: ok, thanks, just checking. Would you be open to a patch that added a protected function makeNew to PersistentStructMap that passed on all of the arguments needed by PersistentStructMap's constructor, and routed all PersistentStructMap constructor calls through that makeNew function? Something like that will be necessary in order to implement the structmap/javabean notion we've talked about a couple of times.

16:54 rhickey: cemerick: refresh my memory - why is this needed?

16:54 hoeck: rhickey: i'm afraid of using keywords cause they are not included in `the standard', it feels like bad style writing my own defn macros

16:55 keywords -> keyword args

16:55 rhickey: hoeck: then think about a destructuring variant to support them

16:58 cemerick: rhickey: I'd like to be able to define a struct that subclasses PersistentStructMap, and whose fixed keys' values are returned by suitably (and automatically) named methods on that subclass. The patch I just suggested is necessary to allow the subclass to easily return an instance of itself as the result of assoc, etc (rather than it returning an instance of PersistentStructMap).

16:58 That makes for a data structure impl that can cross the clojure/java divide, and be used in optimally "native" ways on both sides.

17:03 rhickey: are the fixed fields stored as Java fields or still in an array?

17:03 cemerick: The fixed fields are stored in PersistentStructMap's vals.

17:05 rhickey: cemerick: I'm hesitant only because I used to have a lot of that polymorphic construction in the library and it becamse very fragile - and that was with me controlling both base and derivee. You've considered the containment option as well?

17:10 cemerick: rhickey: Understood. Yes, composition is my fallback. The only downside of that is additional complexity in the macro and generated classes involved...but, a downside I'd obviously like to avoid. :-)

17:10 rhickey: would Java clients access extended keys?

17:11 would there be an interface corresponding to the fixed keys?

17:12 cemerick: rhickey: (1) sure, via valAt (or, perhaps via a more idiomatic java method name)

17:12 rhickey: (2) yes, each fixed key would get a java method generated for it that fetched the current value of the corresponding key

17:12 (2) is what really makes it all worthwhile

17:13 rhickey: cemerick: no, I meant an Interface corresponding to the set of fields

17:14 cemerick: rhickey: Ah -- not by default -- it'd be a concrete bean. I would provide an option to specify an interface that the keys map correspond to, though.

17:17 rhickey: If you'd prefer, I can post a composed implementation, and we can consider a patch to PSM later. No need to force these sorts of things on the spot.

17:21 rhickey: cemerick: the PSM patch would be easy and harmless, it's the evolution/maintenance problem, for instance at some point I'd like to make most data structures Serializable. Do you add any fields in your derivee?

17:23 cemerick: rhickey: No -- just what's necessary to make the fixed keys' values available via corresponding methods. All of the model absolutely stays within clojure.

17:27 rhickey: cemerick: alright, why don't you post the patch to the group - did you send me a CA yet? (haven't checked the box yet today)

17:28 cemerick: rhickey: OK, will do. No, I haven't sent in a CA. I'll ship one to you tomorrow.

17:28 rhickey: cemerick: can you email me a scan while it's on the way?

17:29 cemerick: rhickey: sure, np

17:29 rhickey: thanks, as usual :-)

18:15 meredydd: rhickey: Say again? What did you mean by "Wouldn't you want read/print for Java types"?

19:07 rhickey: meredydd: wouldn't you want the printed version of say, ArrayList, to read as an ArrayList (rather than a vector)?

20:09 meredydd: rhickey: Above all, I'd like it to read as a List.

20:09 rhickey: I'd be happy with ArrayList if it round-tripped well

20:09 rhickey: List is an interface, read returns a concrete data structure

20:10 [1 2 3] is going to be a Clojure vector, not an ArrayList

20:10 meredydd: Indeed; what I'm saying is that I don't care *what* it is, as long as it implements List

20:10 rhickey: so printing ArrayLists as [1 2 3] won't round-tri[p

20:10 meredydd: (although I can see that not exactly being an, ahem, general solution :P)

20:11 My personal position was that, assuming as I was that there were no extra primitives going to be added to the reader,

20:12 that I would prefer an ArrayList to come back as at least *something* implementing List

20:12 rhickey: I'm sure the reader will be extended to more Java types

20:12 meredydd: rather than a reader failure (which is what would have happened otherwise)

20:12 in which case, the assumption upon which I based that feature request was flawed.

20:12 rhickey: as I said, probably based on some generic mechanism like JavaBean serialization

20:13 meredydd: The underlying problem is "I have an object, I need to get it from here to there"

20:13 JavaBean serialisation would do the trick, verbosity notwithstanding.

20:15 Ooh, by the way, while we're talking about the reader - there's what looks like a subtle round-tripping bug in the metadata stuff

20:16 if you put a map into an obj's :tag

20:16 then write it out with metadata output turned on, then read it back in, you get that map as the whole metadata rather then the tag

20:17 (why anyone would do this, I have no idea, but it struck me looking through that code)

20:17 rhickey: could you paste an example?

20:19 meredydd: (def x (with-meta 'quack {:tag {:x 15}}))

20:19 (binding [*print-meta* true] (prn x))

20:19 --> #^{:x 15} quack

20:20 rhickey: ah

20:20 meredydd: If I can find a more obscure or trivial bug, I shall be sure to let you know ;)

20:21 in RT.java:

20:21 if(meta.count() == 1 && meta.containsKey(TAG_KEY))

20:21 adding an instanceof check should do it

20:36 rhickey: wow, XMLEncoder version of ArrayList is verbose!

Logging service provided by n01se.net