"Jim - FooBar();" <jimpil1...@gmail.com> writes: >> (= (Boolean. false) false) ;=> true >> >> now, that is really weird. By all means (at least those, I can come >> up with ;-) it looks like false and (Boolean. false) are the same: > > I think when you use the = operator in Clojure it calls to the > .equals() method for java Objects. That is why the above works > "correctly" while the if test condition "fails". Also when you call > compareTo I'd expect the .equals() method to be invoked again...
Just to throw something in: at least the docs are pretty clear. ,----[ http://www.clojure.org/special_forms#Special Forms--(if test then else?) ] | 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. `---- `if' only does a null-check for `nil' and a primitive `false' check (aka Boolean.FALSE). Here's its implementation: --8<---------------cut here---------------start------------->8--- public Object eval() { Object t = testExpr.eval(); if(t != null && t != Boolean.FALSE) return thenExpr.eval(); return elseExpr.eval(); } --8<---------------cut here---------------end--------------->8--- One could easily add || (t instanceof Boolean && ((Boolean) t).booleanValue()) to the clause to remove that unexpected behavior. That would mean, from a theoretical standpoint, that `if' would be a bit slower in the falsy and the "new Boolean()"-truthy case. To check that, I've created the simple benchmark below that runs the current and enhanced implementation 10 million times with a evenly distributed set of numbers, Booleans "created properly" with valueOf(), Booleans created with the constructor, Strings, and nulls. To my amazement, the variant that explicitly checks for Boolean wrapper objects is not at all slower. On my machine with IcedTea7-2.1, the 10 million checks with either the current null/false-check or the null/false/Boolean-check take about 155 milliseconds. So at least from a performance standpoint, there doesn't seem to be a reason not to do it. It's just a semantic question: should (Boolean. false) bo a truthy thing? Right now, it is and the docs state that. But is that good, especially since this topic pops up every few months on the list? And equally important: is there existing code that relies on (Boolean. false) being truthy? Bye, Tassilo --8<---------------cut here---------------start------------->8--- public class IfTest { public static Object eval(Object t) { if ((t != null) && (t != Boolean.FALSE)) { return 1; } return -1; } public static Object eval2(Object t) { if (((t != null) && (t != Boolean.FALSE)) || ((t instanceof Boolean) && ((Boolean) t).booleanValue())) { return 1; } return -1; } public static void main(String[] args) { int MAX = 10000000; List<Object> l = new LinkedList<Object>(); for (int i = 0; i < MAX; i++) { double d = Math.random(); if (d < 0.2) { l.add(i); } else if (d < 0.4) { l.add(Boolean.valueOf(Math.random() < 0.5 ? true : false)); } else if (d < 0.6) { l.add(new Boolean(Math.random() < 0.5 ? true : false)); } else if (d < 0.8) { l.add(String.valueOf(i * i * i)); } else { l.add(null); } } // For warmup... for (Object o :l) { if (eval(o) != eval2(o)) { throw new RuntimeException(); } } long time = System.currentTimeMillis(); for (Object o : l) { eval(o); } long time2 = System.currentTimeMillis() - time; System.out.println("eval(): " + time2); time = System.currentTimeMillis(); for (Object o : l) { eval2(o); } time2 = System.currentTimeMillis() - time; System.out.println("eval2(): " + time2); } } --8<---------------cut here---------------end--------------->8--- -- 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