Skip to content
Home » Blog » The forgotten logical operators

The forgotten logical operators

Here’s something I notice in a lot of other people’s code I look at, which has always bothered me. This isn’t language-specific — I see it everywhere.

Programmers create logical expressions with the boolean operators And, Or, and Not. It seems to require a sort of sideways view of things to apply the additional operators that work with boolean values, Eqv and Xor (or to use their non-bitwise counterparts which more people might recognize offhand, = and != (<> in LotusScript).

This neglect often results in inefficient and hard-to-read logical expressions. For instance, suppose the code needs to test the assertion: “Either a and b are both 0, or neither is 0.” I often see such a test written as:

If (a = 0 And b = 0) Or (a <> 0 And b <> 0) Then

Instead, we could write this:

If (a = 0) = (b = 0) Then

People reading this code and seeing the admittedly unusual way we’re using the = operator, might do a double take. But it shouldn’t be unusual. It’s completely legit, takes fewer comparisons, and, once you get that = can also compare logical values, easier to verify that the expression is doing what you intended.

In LotusScript I could’ve used Eqv here instead of = and gotten the same result, but a lot of people would’ve had to look up Eqv, whereas they surely already know what = does.

Another weird thing I see people doing with boolean values, is using an unnecessary test for equality, e.g.:

If isFixed = True Then

So they plainly realize the equality test is legitimate on booleans, but here it wasn’t necessary — one can just write:

If isFixed Then

I suppose the programmer in this case felt, I don’t know, it would look a little naked without an operator? They thought it added clarity?

I think the way to add clarity in expressions such as this is to name your variables and functions in a way that makes it clear they’re logical values. If the name starts with “is” or “has” it’s pretty clear. I also tend to use the prefix “b” to indicate a Boolean variable.

Anyway, just something to think about when coding.

4 thoughts on “The forgotten logical operators”

  1. Yeah, bugs me too, the = .

    Another: all the code actually declaring a Boolean in LotusScript. In my thinking, since Boolean is implemented in LotusScript as a Variant, this is slow. I try to use Integer instead of Boolean. I tried Byte but somehow that was not reliable.
    Another: instead of doing a test and documenting the meaning of the test in the variable name, often the test is repeated, including getting an item value from a NotesDocument object, etc, etc…
    Or using a variable but naming it c, or counter, instead of nBruisedApples.

  2. I tried this test using the performance timer I described earlier. The results were as follows:

    0.07083517s - boolean
    0.05319149s - integer

    for the following code inside the loop:

    For i = 1 To 1000000
    	bFlag = Not bFlag
    Next

    The difference in timing is attributable to two million operations on a Boolean versus an Integer (a million reads and a million writes). So the added time due to using a Boolean was about 9 nanoseconds (maybe it would be a bit less if my computer were plugged in currently).
    I suppose this might make a difference in an application where performance was a key concern, but it doesn’t seems like a good tradeoff for clarify in most cases.
    Knowing this, though, I’d certainly opt for an Integer over a Boolean in applications where I don’t care about the value — e.g. if using a List variable just to keep track of a list of strings.

    Note: Tried Byte also, timing result was similar to Boolean. Not sure what’s meant about its reliability but it doesn’t help performance to use it instead of Boolean.

  3. 0.07083517s – boolean 0.05319149s – integer
    53 vs. 70 is quite a lot, and it’s very strange, because in memory boolean is represented as __int16…
    I also did a little test
    Dim v1 As Integer, v2 As Boolean
    l1= Getthreadinfo(6)
    For i=1 To 10000000: v2= Not(v2): Next
    Print “bool”, Getthreadinfo(6) -l1
    l1= Getthreadinfo(6)
    For i=1 To 10000000: v1= Not(v1): Next
    Print “int”, Getthreadinfo(6) -l1
    On the 8.0.2 x32 client, I got an average difference of 3%: int 8130ms vs. bool 83910ms. Apparently there is some overhead…
    What is interesting – on client 12.0.2 x64 the same code ran int 8813 bool 9083, i.e. 5-8% longer than on version 8)

Leave a Reply

Your email address will not be published. Required fields are marked *