On Mon, May 16, 2011 at 2:15 AM, Meikel Brandmeyer <m...@kotka.de> wrote:
> From the Java documentation:
>
> "Note: It is rarely appropriate to use this constructor. Unless a new
> instance is required, the static factory valueOf(boolean) is generally a
> better choice. It is likely to yield significantly better space and time
> performance."
>
> Emphasis not mine.
>
> IIRC, it was deemed that people doing such stuff basically write buggy
> programs and it is not Clojure's task to fix this (paying a speed penalty in
> if).

I cannot concur here. Sun could have omitted to include a public
constructor in the class Boolean, but that was not their choice, and
their own serialization mechanism also can produce additional
instances of the class. They also have not @deprecated either of the
public constructors after the fact, and the warning you cite a)
appears on only one of them and b) does not itself warn of any kind of
semantic difficulty resulting from using it, only that it wastes
processor and memory.

> Does the serialisation thing shed some new light on this issue?

Only what I already said: Clojure relying on false Booleans being
identical to the specific instance Boolean/FALSE may break in the
presence of serialization of objects that contain boxed booleans. One
circumstance where this plausibly could occur is if Clojure data
structures containing booleans were used in combination with RMI in a
client/server app.

It's also a risk if anyone decides to prefer serialization to prn/read
for persisting data (likely out of impure motives, such as to
obfuscate a file format to deter competitors making interoperable
products, or "security through obscurity" such as making game data
files harder for cheaters to alter profitably -- though an encrypted
zipped text file would be as good, and perhaps as compact, in such
cases).

I am also unsure what happens with various scenarios involving
database persistence. I expect it may depend on how embedded Booleans
are stored and reconstituted in the particular database and how they
are handled by the Java API being used to access it. Storage as
reader-interpreted text would be safe, and storage as the database's
native boolean type, converted via a Clojury API, probably also would
be safe; storage as a serialized BLOB obviously won't be.

One workaround would be to run deserialized/problematic data
structures through something like this:

(defn fix-booleans [obj]
  (cond
    (= obj false) false
    (coll? obj) (into (empty obj) (doall (map fix-booleans obj)))
    :else obj))

This *should* preserve sorted-maps, etc. but I haven't tested it
thoroughly. Note that (= obj false) returns true for (Boolean. false),
so the first branch of the cond collapses all falses to the "one true
false". (Interestingly, (false? obj) does not work here -- it returns
false for (Boolean. false).) The second, obviously, recurses the
transformation in data structures and the third returns other atoms
(including true) unaltered. The likely edge cases involve java.util
collections that are not Clojure collections -- likely either they
don't get recursed into or else (empty obj) blows up on them,
depending on how coll? reacts in each separate case. Unfortunately
that edge case might be common in practice, since if you're using
serialization with Clojure data structures it's likely because you're
having to interoperate with Java code that uses serialization, and
then it's fairly likely you also have java.util collections in the mix
(or even arrays or Apache Commons collections).

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to