Shortcircuiting: OrElse combined with Or - vb.net

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

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

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.

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

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.

Related

Why And operator in vb.net

I always use AndAlso while checking multiple conditions as it doesn't evaluate right side unless left one is true. I don't see any situation where someone would like to evaluate right side even if left one fails. If it was needed then why they didn't include same in C#.
Update:
As accepted answer pointed out that it exists because it is used for bitwise operation, that fine enough but I still think they would have overloaded And operator to serve both purposes and just not created AndAlso. If anyone can pour some light on it, this question is still open :)
They included the same in C#. In C# you can use & (And) or && (AndAlso).
There's no real use case i can imagine for the not short-circuit operator when comparing booleans, but And can be used with numeric values, and it then does a bitwise comparison. That's why it exists. But when comparing boolean types, you'll always be using the short-circuit version.
And is also a bit operator. Here is an example showing a mix of And an AndAlso.
Dim foo? As Integer = 5
If foo.HasValue AndAlso (foo And 1) = 1 AndAlso (foo And 4) = 4 Then
Stop
End If

Logic operator syntax in VB for my School Project

so I'm writing a Blackjack game for my Advanced Higher Computing Science project at school, and I have a question about the syntax of the logical operators in VB.
Here's the situation..
If X>Y AND (A=True Or B=True Or C=True) Then
Do something
End IF
Let's say for instance that X is indeed greater than Y, and A is true, but B and C are false. As I understand it the statement will execute, because X is greater than Y, AND at least one of the conditions within the brackets is true, but I'm not entirely sure if this is correct. Can the brackets be used this way for things to be logically correct? Or do I have to write conditions regarding A, B and C separately? For example...
If X>Y AND A=True Then
Do something
End IF
If X>Y AND B=True Then
Do something
End IF
If X>Y AND C=True Then
Do something
End IF
Basically, can the brackets be used as a 'short hand' method to make the code slightly shorter and less cluttered? I'm using the latest version of VB, 2015.
Thanks a lot for any help, I appreciate it!
P.S. - I can't put my actual code on the internet, as this could get me in trouble with my exam board as this is an official assessment.
Consider this original example
If X>Y AND (A=True Or B=True Or C=True) Then
It says, that 2 conditions must be met to evaluate this to True. X must be more than Y and also, condition in parenthesis must evaluate to True. First, lets optimize your code to use .net efficiently
If X>Y AndAlso (A OrElse B OrElse C) Then
In your case, if X>Y evaluates to False there is no reason to continue. Hence, AndAlso. This is a shortcut. Same with OrElse. If A evaluates to true, we don't need to evaluate other conditions - this is supported by your logic. Now, A=True - this is noise. And this is why you name Boolean variables, isSomething, hasSomething, [doneSomething], where doneSomething is a verb, i.e. created, completed, disposed, allowed.
Now, lets look at your second piece of code. Obviously what comes into view first, is that you re-evaluating X>Y 3 times and along, you may do Do something 3 times. This syntax widely used but it would be something along these lines (to create same logic as first evaluation)
If Not X>Y Then
Return ' exit because your first evaluation must be true
End If
If A Then
' Do something
Return ' Success and return
End If
If B Then
' Do something
Return ' Success and return
End If
If C Then
' Do something
Return ' Success and return
End If
Of course, the code above makes little sense because there is obvious repetition. This is better
If Not X>Y Then
Return ' exit because your first evaluation must be true
End If
If A OrElse B OrElse C Then
' Do something
End If
This makes more sense but then again, go to line #2 and use optimized single line code - it will do same.

Which is better for performance? And vs AndAlso

When writing an If statement, I've always used And when needed like:
If 1=1 And 2=2 Then
The only time I ever used AndAlso is if the second condition will error if the first isnt true like:
If Not IsDbNull(Value) AndAlso Value=2 Then
However, recently I've heard that AndAlso is better for performance than And as the second condition is only read when the first is true.
In this case, should I always just use AndAlso?
Yes, AndAlso can be faster than And, because it doesn't evaluate subsequent conditions if an earlier condition proves false.
And is a throwback to earlier versions of Visual Basic.
Most (I hesitate to say all) modern languages use boolean operators that short-circuit conditions that don't strictly need to be evaluated.
e.g. && the and operator for C style languages all perform as AndAlso.
Be careful if you've lots of code that use And and Or, a global search and replace can change existing behaviour, if the second condition involves a function call that has side effects.
I would prefer using AndAlso and OrElse unless you specifically require the functionality provided by And & Or
Coming from a C and C++ background into VB (V5 initially) it was always really annoying that VB's and and or didn't short circuit. So the case where the second expression was dependent on the first was always harder to write.
I wouldn't expect to see much of a performance increase most of the time, unless the second expression has significant overhead, short circuiting operators will avoid executing it and thus speeding things up.
But if that second expression is a significant overhead then I would be concerned about side effects which will only be performed sometimes—this will make future maintenance harder and could make correctness harder to maintain.
When the conditions are also functions:
If functionA() And functionB() Then
...
public shared functionA() As Boolean
IF A is false THEN log -> return true or false
...
public shared functionB() As Boolean
IF B is false THEN log -> return true or false
Using AndAlso here could be the wrong way to go, because then it will only log B when both A and B are false.

When is "Or" better to use than "OrElse"?

Is there any situation where Or is better to use than OrElse?
If not, why don't they just "upgrade" the internal code?
The only reason to use Or is when you want bitwise arithmetic, i.e. you want to manipulate the bits in a number:
Sub SetBit(value As Integer, Bit As Integer)
value = value Or (1 << Bit)
End Sub
This kind is the only case appropriate for Or. In all other cases (i.e. when using Boolean logic), use OrElse.
Despite their similar names, Or and OrElse are semantically quite distinct operations which should not be confused with each other. It just so happens to be that the internal representation of Booleans makes it possible to use bitwise Or to achieve a similar (but not the same) effect to OrElse. (Old versions of BASIC and VB – before .NET – exploited this relationship by only providing an Or operation, no OrElse.)
You should always use OrElse instead of Or, except when doing bit-wise arithmetic.
OrElse is a short-circuiting comparison, meaning it will not evaluate the second clause if the first was true. This is extremely useful, because you will often want clauses which could fail without shortcircuiting (eg. x is nothing OrElse not x.HasSomeProperty).
The reason it is not possible to automatically upgrade all 'Or's as 'OrElse's is because the evaluation of the second clause may be important. For example, I could write "True Or SomeBooleanMethodWhichMightThrowAnEception()". Changing that Or to an OrElse would change the meaning of the program.
Edit: This code is evil; I merely added this answer to indicate that this is possible.
Another case would be to use Or when evaluating expressions that perform some sort of side effect that must occur:
Sub DoSomething()
Dim succeeded As Boolean
succeeded = FirstThing() Or SecondThing() Or ThirdThing()
If succeeded Then
' Do something here
End If
End Sub
In this case FirstThing, SecondThing, and ThirdThing are methods that must be executed as a whole whether any of them fail or not, while accumulating a success value. If you used OrElse then if FirstThing or SecondThing fail, then the operations behind the failing method wouldn't occur.

Not keyword vs = False when checking for false boolean condition

When I'm using an If statement and I want to check if a boolean is false should I use the "Not" keyword or just = false, like so
If (Not myboolean) then
vs
If (myboolean = False) then
Which is better practice and more readable?
Definitely, use "Not". And for the alternately, use "If (myboolean)" instead of "If (myboolean = true)"
The works best if you give the boolean a readable name:
if (node.HasChildren)
Since there's no functional difference between either style, this is one of those things that just comes down to personal preference.
If you're working on a codebase where a standard has already been set, then stick to that.
Use True and False to set variables, not to test them. This improves readability as described in the other answers, but it also improves portability, particularly when best practices aren't followed.
Some languages allow you to interchange bool and integer types. Consider the contrived example:
int differentInts(int i, int j)
{
return i-j; // Returns non-zero (true) if ints are different.
}
. . .
if (differentInts(4, 8) == TRUE)
printf("Four and Eight are different!\n");
else
printf("Four and Eight are equal!\n");
Horrible style, but I've seen worse sneak into production. On other people's watches, of course. :-)
Additionally to the consensus, when there is both a true case and a false case please use
if (condition)
// true case
else
// false case
rather than
if (not condition)
// false case
else
// true case
(But then I am never sure if python's x is not None is the true-case or the false case.)
Definitely use "Not", consider reading it aloud.
If you read aloud:
If X is false Then Do Y
Do Y
Versus
If Not X Then Do Y
I think you'll find the "Not" route is more natural. Especially if you pick good variable names or functions.
Code Complete has some good rules on variable names. http://cc2e.com/Page.aspx?hid=225 (login is probably required)
! condition
In C and pre-STL C++, "!condition" means condition evaluates to a false truth value, whereas "condition == FALSE" meant that the value of condition had to equal what the system designed as FALSE. Since different implementations defined it in different ways, it was deemed better practice to use !condition.
UPDATE: As pointed out in the comment -- FALSE is always 0, it's TRUE that can be dangerous.
Something else: Omit the parentheses, they’re redundant in VB and as such, constitute syntactic garbage.
Also, I'm slightly bothered by how many people argue by giving technical examples in other languages that simply do not apply in VB. In VB, the only reasons to use If Not x instead of If x = False is readability and logic. Not that you’d need other reasons.
Completely different reasons apply in C(++), true. Even more true due to the existence of frameworks that really handle this differently. But misleading in the context of VB!
It does not make any difference as long you are dealing with VB only, however if you happen to use C functions such as the Win32 API, definitely do not use "NOT" just "==False" when testing for false, but when testing for true do not use "==True" instead use "if(function())".
The reason for that is the difference between C and VB in how boolean is defined.
In C true == 1 while in VB true == -1 (therefore you should not compare the output of a C function to true, as you are trying to compare -1 to 1)
Not in Vb is a bitwise NOT (equal to C's ~ operator not the ! operator), and thus it negates each bit, and as a result negating 1 (true in C) will result in a non zero value which is true, NOT only works on VB true which is -1 (which in bit format is all one's according to the two's complement rule [111111111]) and negating all bits [0000000000] equals zero.
For a better understanding see my answer on Is there a VB.net equivalent for C#'s ! operator?
Made a difference with these lines in vb 2010/12
With the top line, Option Strict had to be turned off.
If InStr(strLine, "=") = False Then _
If Not CBool(InStr(strLine, "=")) Then
Thanks for answering the question for me. (I'm learning)