Code idiom: using logical ^ to change your mind

# 2003-03-26 16:22:41 -0500 | Java | 8 Comments

This idiom is a cool little trick, but I’ve seen coders scratching their head trying to work out what it does; so a detailed explanation is in order.

The ^ bitwise exclusive-or operator (or “XOR”) is standard computer science fare. An XOR is often used to flip bits in a byte/word. In Java, the ^ bitwise operator works on all the integer types (int, byte, short, char, and long) and performs an XOR between each corresponding bit in the arguments.

But, if the operands to ^ are both boolean, then a logical exclusive-or (LXOR) is performed (as opposed to a bitwise XOR). The result of LXOR is “true if the operands are different; otherwise false if they are the same”. The truth table for x ^ y looks like this:

xy falsetrue
falsefalsetrue
truetruefalse


The idiom: using ^ to change your mind

Can you work out what the following code does?

public static boolean isTuesday(boolean invert) {
    GregorianCalendar now = new GregorianCalendar();
    boolean isTue = now.get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY;
    return isTue ^ invert;
}

System.out.println(”is Tuesday? ” + isTuesday(false));
System.out.println(”is not Tuesday? ” + isTuesday(true));

The trick utilises this:

  • (x ^ false) is always just x
  • (x ^ true) negates x, it is !x

So, if you have some code that conditionally needs to do the opposite of what it normally would do (that is, it needs to “change its mind”), just pass an “invert” argument, and LXOR with that argument when making decisions. (You could call this argument “invert”, “reverse”, “negate”, etc. depending on the particular semantics.)

Applied example: AbstractConditionalTag

Here is the code for a useful AbstractConditionalTag JSP Taglib and an example “is Tuesday” tag.

public abstract class AbstractConditionalTag extends TagSupport {
    private boolean invertTest = false;

    public void setInvert(String invert) {
        invertTest = "true".equalsIgnoreCase(invert);
    }

    public int doStartTag() throws JspTagException {
        try {
            boolean result = evaluateCondition() ^ invertTest;
            return result ? EVAL_BODY_INCLUDE : SKIP_BODY;
        }
        catch (RuntimeException e) {
            Logger.log(this, e);
            return SKIP_BODY;
        }
    }

    protected abstract boolean evaluateCondition()
        throws JspTagException;
}

public class IsTuesdayTag extends AbstractConditionalTag {
    public static boolean evaluateCondition() {
        GregorianCalendar now = new GregorianCalendar();
        return now.get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY;
    }
}

And you would use it in a JSP page like this:

<tag:isTuesday>
  It's Tuesday; rubbish day!
</tag:isTuesday>
<tag:isTuesday invert="true">
  Don't put the rubbish out today.
</tag:isTuesday>

8 Responses to this entry:

  1. Alan Green Says:

    I’ve recently saw a pair of conditional tags <IsNull> and <IsNotNull> implemented with an abstract base class that has the method:

    protected abstract boolean isNullAGoodThing()

    Each tag is implemented with a very short subclass, one implementing this method as "return true", and the other "return false". I’ll have a look at that code again and see if I could replace it with a single class using ‘^’.

    Alan

    PS: Your smileys are just too cute :D

  2. Oliver Burn Says:

    You made me :? quite hard with this one, but I am now :-D

  3. Brendan Humphreys Says:

    Matt wrote:

    This idiom is a cool little trick, but I've seen coders scratching their head trying to work out what it does; so a detailed explanation is in order.

    I think the fact that coders are scratching their heads makes this more of a "trick" and less of an "idiom". That you leave coders puzzled is enough of a reason not to use it, since it doesn’t really buy you much, and the readability of the code is reduced.

    For me, I’d prefer to see it spelt out:

    boolean result = evaluateCondition();

    if (invert) {
    result = !result;
    }
    return result;

    Sure it’s a bit more typing, but it doesn’t require the audience to have a knowledge of an arguably obscure language feature. When running the latter chunk thru my wetware language parser, it reads quickly and elegantly.

  4. Oliver Burn Says:

    While I agree with you Brendan, I would redo your example as:


    final boolean result = evaluateCondition();
    return (invert) ? !result : result;

    I find this approach improves code coverage and is easier to read. >:)

  5. Kevin Greer Says:

    You could also do:

    return result == ! invert;

  6. Kevin Greer Says:

    Or just:

    return result != invert;

  7. Anonymous Coward Says:

    too clever by half.
    ..at least.

  8. Will Sargent Says:

    Just plain evil.

Leave a Reply

Click here to leave a reply