On Saturday, April 7, 2012 10:59:00 AM UTC-5, Steven Obua wrote: > > load-node and store-node are custom functions that rely on two other > custom functions serialize and deserialize: > > (defn serialize > "Serializes value, returns a byte array." > [v] > (let [buff (java.io.ByteArrayOutputStream. 1024)] > (with-open [dos (java.io.ObjectOutputStream. buff)] > (.writeObject dos v)) > (.toByteArray buff))) > > (defn deserialize > "Accepts a byte array, returns deserialized value." > [bytes] > (with-open [dis (java.io.ObjectInputStream. > (java.io.ByteArrayInputStream. bytes))] > (.readObject dis))) > > On Saturday, April 7, 2012 4:50:00 PM UTC+1, Aaron Cohen wrote: >> >> On Sat, Apr 7, 2012 at 11:41 AM, Steven Obua wrote: >> >>> ------------------------------------------------------------------------------------------------------------------------------(defrecord >>> >>> M-Node [leaf content]) >>> >>> (def n (M-Node. false "")) >>> >>> (if (:leaf n) "boom" "ok") ;; returns "ok" >>> >>> (def n (load-node (store-node n))) ;; load-node and store-node are just >>> java serialization/deserialization >>> >>> >> Where is load-node coming from? It should be canonicalizing booleans when >> it deserializes, or else it's buggy. >> >>
This behavior would have surprised me too, but I suspect the performance tradeoffs of supporting arbitrary Boolean instances in this way have been carefully considered. from http://clojure.org/special_forms#Special Forms--(if test then else?) ##### (*if* test then else?)Evaluates test. If not the singular values *nil* or * false*, evaluates and yields then, otherwise, evaluates and yields else. If else is not supplied it defaults to*nil*. All of the other conditionals in Clojure are based upon the same logic, that is, *nil* and *false* constitute logical falsity, and everything else constitutes logical truth, and those meanings apply throughout. *if* performs conditional tests of boolean Java method return values without conversion to Boolean. Note that *if* does not test for arbitrary values of java.lang.Boolean, only the singular value * false* (Java's Boolean.FALSE), so if you are creating your own boxed Booleans make sure to use Boolean/valueOf and not the Boolean constructors. ##### Of course, if you use readBoolean/writeBoolean instead of readObject/writeObject in your serialization, you sidestep the issue. Granted, that'd require some additional code, but it could still be reasonably nice w/ polymorphism via protocols or multimethods. You could also avoid it by using Carbonite (which uses Kryo) instead of working with plain old ObjectInputStreams: https://github.com/revelytix/carbonite - Colin Colin Jones @trptcolin -- 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