user=> (defn truthy? [x] (if x true false))
#'user/foo
user=> (truthy? nil)
false
user=> (truthy? Boolean/FALSE)
false
user=> (Boolean. false)
false
user=> (truthy? (Boolean. false))
true

Wait, what?

Looks like Clojure's truthy check is looking for something to be
either nil (= Java null) or the specific java.lang.Boolean instance
Boolean/FALSE. A novel Boolean instance with the value false is
treated as truthy!

This may not be desirable behavior. I doubt checking against
Boolean/FALSE with .equals instead of identical? will be much more
expensive -- it's likely, after JIT optimization, to boil down to a
dereference and a comparison to a constant in place of a direct
pointer comparison, so one extra instruction.

The biggest case where this is liable to cause problems is with Java
serialization:

user=> (def q (java.io.ByteArrayOutputStream.))
#'user/q
user=> (.writeObject (java.io.ObjectOutputStream. q) Boolean/FALSE)
nil
user=> (truthy? (.readObject (java.io.ObjectInputStream.
(java.io.ByteArrayInputStream. (.toByteArray q)))))
true

As you can see, round-tripping Boolean/FALSE through serialization
does not readResolve() it to Boolean/FALSE but rather constructs a de
novo false instance, so boxed booleans that pass through serialization
become truthy to Clojure.

The other potential source of trouble is interop with Java code that
for any reason calls the Boolean constructor instead of using the
class constants.

Autoboxing of the primitive boolean false seems to produce the
specific instance Boolean/FALSE, fortunately:

user=> (truthy? (.contains (java.util.HashSet.) 42))
false

Of course, if it didn't, this would have been noticed a long time ago.

-- 
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