Shortcircuiting: OrElse combined with Or
Asked Answered
H

4

5

If I have the following ...

a OrElse b 

... and a is True then clearly b is never evaluated. But if I add an Or, then what?

a OrElse b Or c

Does/should c get evaluated? And what if I put in some brackets?

Apologies if this is basic. Of course I can test for the answer myself but I can't find this question answered here or elsewhere. Lots of questions dealing with Or versus OrElse but nothing dealing with Or with OrElse

Hogue answered 9/9, 2010 at 14:45 Comment(2)
For a question of this nature, while it is possibly faster to ask SO, a simple test program can clear this up and you may learn more in the process.Debarath
@JoelEtherton: sure, in fact i wrote a simple test long before posting this question. still, i was interested in the expert view. the point of the question is to see expert answers of the kind JoelCoehoorn has provided; not just an answer, but background detail plus explanation plus advice too.Hogue
H
3

This is an operator precedence problem. The relevant documentation is here:
http://msdn.microsoft.com/en-us/library/fw84t893.aspx?ppud=4

The important excerpts:

  • Operators with equal precedence are evaluated left to right in the order in which they appear in the expression.

and

Inclusive disjunction (Or, OrElse)

So what we learn here is that Or and OrElse have the same precedence and that operators with the same precedence are evaluated from left to right.

Therefore, I would expect that in cases where a is true, b is not evaluated. However, c still will be. In cases where a is false, b is evaluated and regardless of the b's value the Or operator will evaluate c. So, yes, c is always evaluated.

As a practical matter, you should generally prefer OrElse in your code unless you have a good reason to use Or. Or exists now mainly for backwards compatibility.

Hecate answered 9/9, 2010 at 15:21 Comment(9)
I'm a bit puzzled, given that, according to the documentation, And has higher precedence that Or/Orelse. Still, in my program when I used test(1) OrElse test(2) And test(3) I get 1 and true as output. Any idea?Finisterre
@Finisterre this is being evaluated as such test(1) OrElse resultofAndIsle
@Finisterre Not sure. I would expect 2,3,1,true from that. I suspect that it's jitter optimization of some kind.Hecate
@Isle - yes, but it has to compute the resultofAnd first because of And's higher precedence, and that should cause it to output 2 and 3 prior to the 1.Hecate
@Joel: Yeah, that was what I thought as well.Finisterre
@Joel Coehoorn I agree that it's probably a JIT optimization somewhere thenIsle
@Joel @Finisterre Have I misunderstood something? If the test(x) function outputs x and returns True then test(1) OrElse test(2) And test(3) will always output just 1 and evaluate to true. From the OrElse documentation "If the first expression is True, the second is not evaluated". Are you supposing that using an expression as the second operand to OrElse must cause the second operand to be evaluated before the first operand? That would be rather bizarre. It seems to me it would make OrElse rather useless!Seritaserjeant
@Seritaserjeant - It's a matter of precedence. Because And has higher precedence, it should be as if the full expression were written like this: test(1) OrElse (test(2) And test(3)).Hecate
@Joel Yes indeed, operator precedence means the expression should be parsed like this test(1) OrElse (test(2) And test(3)). That doesn't necessarily determine the evaluation sequence. To evaluate test(2) And test(3) before test(1) would contradict the specification for OrElse. The compiler can easily parse the expressions for the operands before it finally generates any IL. Then it could generate IL to evaluate test(1) first, and then, only if test(1) evaluated to False, to evaluate test(2) And test(3). Surely this must be how it works?Seritaserjeant
I
5

OrElse short circuits between the left and right side parameters (only 2 parameters). So I would say that C will always be evaluated as you could treat this as (A OrElse B) Or C.

MSDN OrElse

Isle answered 9/9, 2010 at 14:49 Comment(0)
F
3

In the case presented, c is evaluated. A small test will tell you:

Debug.WriteLine(test(1) OrElse test(2) Or test(3))

Function test(ByVal a As Integer) As Boolean

    Debug.WriteLine(a)
    Return True

End Function

The above example outputs:

1
3
True
Finisterre answered 9/9, 2010 at 15:7 Comment(0)
H
3

This is an operator precedence problem. The relevant documentation is here:
http://msdn.microsoft.com/en-us/library/fw84t893.aspx?ppud=4

The important excerpts:

  • Operators with equal precedence are evaluated left to right in the order in which they appear in the expression.

and

Inclusive disjunction (Or, OrElse)

So what we learn here is that Or and OrElse have the same precedence and that operators with the same precedence are evaluated from left to right.

Therefore, I would expect that in cases where a is true, b is not evaluated. However, c still will be. In cases where a is false, b is evaluated and regardless of the b's value the Or operator will evaluate c. So, yes, c is always evaluated.

As a practical matter, you should generally prefer OrElse in your code unless you have a good reason to use Or. Or exists now mainly for backwards compatibility.

Hecate answered 9/9, 2010 at 15:21 Comment(9)
I'm a bit puzzled, given that, according to the documentation, And has higher precedence that Or/Orelse. Still, in my program when I used test(1) OrElse test(2) And test(3) I get 1 and true as output. Any idea?Finisterre
@Finisterre this is being evaluated as such test(1) OrElse resultofAndIsle
@Finisterre Not sure. I would expect 2,3,1,true from that. I suspect that it's jitter optimization of some kind.Hecate
@Isle - yes, but it has to compute the resultofAnd first because of And's higher precedence, and that should cause it to output 2 and 3 prior to the 1.Hecate
@Joel: Yeah, that was what I thought as well.Finisterre
@Joel Coehoorn I agree that it's probably a JIT optimization somewhere thenIsle
@Joel @Finisterre Have I misunderstood something? If the test(x) function outputs x and returns True then test(1) OrElse test(2) And test(3) will always output just 1 and evaluate to true. From the OrElse documentation "If the first expression is True, the second is not evaluated". Are you supposing that using an expression as the second operand to OrElse must cause the second operand to be evaluated before the first operand? That would be rather bizarre. It seems to me it would make OrElse rather useless!Seritaserjeant
@Seritaserjeant - It's a matter of precedence. Because And has higher precedence, it should be as if the full expression were written like this: test(1) OrElse (test(2) And test(3)).Hecate
@Joel Yes indeed, operator precedence means the expression should be parsed like this test(1) OrElse (test(2) And test(3)). That doesn't necessarily determine the evaluation sequence. To evaluate test(2) And test(3) before test(1) would contradict the specification for OrElse. The compiler can easily parse the expressions for the operands before it finally generates any IL. Then it could generate IL to evaluate test(1) first, and then, only if test(1) evaluated to False, to evaluate test(2) And test(3). Surely this must be how it works?Seritaserjeant
P
-1

In my personal experience VB tends to obtain the value for all of them regardless of whether they be actually evaulated or not.

This is only helpfull when order matters for items existance and the like. Just wanted to note it.

Piperine answered 9/9, 2010 at 14:56 Comment(1)
Short circuit and orelse visualbasic.about.com/od/quicktips/qt/vbnetlogop.htmLossa

© 2022 - 2024 — McMap. All rights reserved.