Operator_And not allowing short-circuiting of If statement

I created a class, BooleanClass, that acts like a nilable boolean. I implemented Operator_Convert, Operator_And/AndRight, and Operator_Compare. Now consider this code, which works:

  dim b as BooleanClass = true
  
  if b then
    System.DebugLog "just b"
  end if
  
  if true and b then
    System.DebugLog "true and b"
  end if
  
  if false and b then
    System.DebugLog "false and b"
  end if

All of these do exactly what you think, except the last one fires the Operator_AndRight of the BooleanClass rather than simply evaluating false and moving on. Why is this an issue? Consider this code:

dim myObject as SomeObject
if myObject isa Object and myObject.BooleanClassProperty then
  // NilObjectException
end if

When myObject is nil the code attempts to fire Operator_AndRight of the non-existent myObject.BooleanClassProperty. And boom.

Is this a bug, intentional, or have I missed something?

BTW, I can always write this code like this:

if o isa Object and o.BooleanClassProperty = true then …

But since I’m replacing an existing Boolean property with my class, I’d like it to work the same way.

No comments? Should I file Feedback?

That’d be a good start :slight_smile:

I thought a “good start” was asking here in the Pro channel. My time is limited and I don’t want to use it on unnecessary Feedback reports, considering what’s involved.

This is intentional.

OK, thanks Joe. I guess I’ll just be aware.

I’ll take this topic to general so others can benefit.

But… Since the class is evaluated by the compiler to determine that Operator_And should and can be used, couldn’t it go one step further and use Operator_Convert As Boolean if that’s available instead?

It could special case boolean-like things, sure. The catch is that Operator_And has behaved like this for the last eleven years and such a change could subtly break existing projects.

Understood, but I can’t imagine how this would break code considering it’s an edge case. This applies only when a class implements both Operator_Convert As Boolean, and Operator_And/Or/Xor/etc. against a boolean. The latter is only necessary because the If statement doesn’t honor the Operator_Convert, otherwise, how would the result ever be different? When would someone implement Operator_And, for example, to give a different result when comparing the value to itself than the compiler would by converting the class to boolean first?

What’s more, I think this will actually fix subtle bugs that might exist. The compiler does not have a problem with the statement if o isa object and o.BoolProp then, so if o is never nil during testing, this bug won’t be caught.

Classes implementing Operator_And have no obligation to perform a logical And.

When the class offers a boolean representation of itself, and is And’d against another boolean, I can’t imagine what else it would do.

At the least, what about keeping the current behavior when Operator_And/etc. are available, but letting the compiler do the conversion if it’s not? That wouldn’t break anything, right?

just make operator_and return something other than a boolean - like a dictionary of arrays of pairs or something :stuck_out_tongue:

or make it return an integer and have it be “bitwise” and like

the boolean would be a specific edge case