11

To be a bit more clear, I'll state that I've spent lots of time with different languages. But until now it's been either it'll use it all the time or it doesn't support it at all.

Now work has me starting on projects that require VB.net and I see it provides it both ways in terms of AND and ANDALSO. The first one does not short circuit, and the 2nd one does.

So this leads me to wonder why? As having it setup like this seems to imply that it would come up quite often that one would want to switch modes. But I can't think of any situations where it would be a bad thing to use Short Circuit.

I know this could very well get into more of an option thing, so if I need to put this at some place else just tell me where.

Though I'm hoping there is at least an official answer, as to why having both options would be better then always doing Short Circuit, when it's available.

5

Some terms in a logical expression can have side effects. It is sometimes necessary to ensure all side effects happen in the stated order, and none are skipped and it is the evaluation result that guides the logic:

if not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

In other cases, you don't want to evaluate any of the remaining terms if an earlier evaluation returns false.

if IsAirborne() and not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

Some will/have argued that relying on the short-circuit behavior in the second example is bad form, but that's getting into coding style and belief systems. There are many very good bits of code in the world that do rely on nearly every feature a language provides, and that's just the way it is.

VB's ANDALSO is crisp and seems to be an attempt to make the practice more acceptable.

As JimmyJames points out in his answer, there can be measurable performance implications around short-circuit evaluation. Languages that do not provide the mechanism, always evaluate every term of the expression, while those that do provide it, can generate extra branch statements. Either way, much depends on the number of processing steps required to evaluate each of the terms and also on compiler and CPU architectures. You would normally not care about such things until you have a measured bottleneck in the code and need to work out how to alleviate it. Any do or don't rules regarding allowing short-circuit evaluation in your code would have roughly equal chance of causing slower code and optimizing early can be a total waste of time, so always measure, then optimize.

  • 4
    While factually correct, it's not a great design. – Robert Harvey May 30 '18 at 19:42
  • 2
    @RobertHarvey, I can't write a control system that does not have side effects and I cannot control the system correctly if I do not react to outcomes. In other words, get over it ;). – jwdonahue May 30 '18 at 20:25
  • 7
    No, but you can assign the results of those side-effecting functions to boolean variables, check those variables in your if condition and still short-circuit. I do agree that it is, in some ways, a stylistic distinction, but it does have the virtue of making things crystal-clear. – Robert Harvey May 30 '18 at 20:30
  • 3
    @jwdonahue It's okay to use "big words" if the risk of confusion is low. The risk of confusion and missing particular nuances of a block of code like this is extremely high and can be catastrophic to the logic. It's never good to make the reading developer think very hard. – jpmc26 May 30 '18 at 23:50
  • 4
    "Some terms in a logical expression can have side effects" - While this opening statement is correct, I feel this answer fails in not pointing out that relying on side-effects is bad. Far worse, in fact, than relying on short-circuit evaluation to prevent spurious evaluations. Which this answer does suggest may be bad form. – aroth May 31 '18 at 9:01
20

Apparently, your question is not about short-circuiting being good or bad in general, but about why VB.NET provides operators with and and without it. With this in mind, the answer to

when is short-circuit evaluation bad?

is simply: when it violates backwards compatibility.

Ok, now you can say VB.NET is not very backwards compatible to old VB6 or VBA, however at least certain parts of the language are. Microsoft's decision of keeping the old AND and OR semantics (without short-circuiting) made a huge category of errors less likely to occur when when porting old VB programs to VB.NET.

On the other hand, VB.NET language designers probably shared your opinion about short-circuiting being a good thing. When I remember correctly, the first VB.NET pre-release versions provided AND or OR operators with short-circuiting, but the developer feedback must have been so bad MS withdraw this decision before VB.NET 1.0 appeared. So the designers decided to implemented it in terms of new keywords ANDALSO and ORELSE as a trade-off between backwards compatibility and usefulness.

IMHO this was a good decision. I had to port several older programs in the last decade, and not having to make a heavy impact analysis for every logic expression including AND and/or OR (pun intended) made that task a lot easier and more economic. On the other hand, whenever I have to write a new logical expression in VB.NET, my default choice for the operators are the short-circuit forms, that is what I am used to from C, C++, C# etc, and it allows me to write several idioms in more concise form (even if ANDALSO needs 4 characters more to type).

If you are not convinced, I recommend to read Joel Spolsky's great article about Martian Headsets, which is about why early design decisions in software development cannot be easily revoked after the component or language or API in stake has reached a user base of a certain size.

  • Ok, this qualifies as a rant and the link to Martian Headsets doesn't seem to be related at all. – jwdonahue May 30 '18 at 20:26
  • 6
    @jwdonahue: I have no idea why you think this is a rant, quite the opposite. And the article about Martian Headsets is about why some design decisions in software development made several decades ago cannot be easily revoked after the component or language or API in stake has reached a user base of a certain size. Isn't the analogy really so hard to grasp? VB6 was very popular in the past, and I am sure still hundred thousands of companies in the world have mission critical apps running in VB6 or VBA. – Doc Brown May 30 '18 at 20:37
  • I don't quite see how the "Martian headests" article really fits. What's necessary to ensure interoperability between X's and Y's (e.g. nuts and bolts) is to have separate standards for X and Y, such that a worst-case nut will accommodate a slightly-worse-than-specified bolt, and vice versa. One should try to write the specs so as to avoid making nuts or bolts needlessly expensive, or having a needless amount of slop between nuts and bolts, but specifying both halves separately makes it possible to ensure interoperability far more reliably than trying to have one spec serve both sides. – supercat May 30 '18 at 23:22
  • 3
    @supercat: this is about having already trillions of nuts (or lines of VB6 code) existing and in use, and now the bolts (or in this case VB compiler) will be replaced by a newer generation. If the existing nuts fit only to non-metric bolts, it is not economic to make the newer bolts metric-system only. – Doc Brown May 31 '18 at 6:34
  • tl;dr: VB is a dialect of BASIC, a language dating from 1964, and in BASIC the And operation does not short circuit, neither does it in SQL (1974), nor FORTRAN (1956), nor Pascal (1970). – Ben May 31 '18 at 9:46
3

when is short-circut evaluation bad?

They become bad, as soon you start to rely on side effects of expressions you expect to be executed in the evaluation of a boolean overall result.

0

Caveat: This is a bit esoteric in that in almost all cases, developers shouldn't worry about it. But... there can be a performance hit due to conditional evaluation as it creates branching in execution. A non-short circuit operation does not branch and is more predictable.

The reason this rarely matters is that the cost is typically small and also usually outweighed by the cost of evaluating the second (or third, etc.) condition. This will only ever matter in computationally expensive routines when high-performance is required and it might still not matter then either.

  • I think you can only optimize a logical statement so far, eventually you have to take branches. – jwdonahue May 30 '18 at 19:41
  • @jwdonahue I don't get your point. Sorry. – JimmyJames May 30 '18 at 19:42
  • We're talking about combinatorial logic here. Short circuit evaluation or not, you have one or more terms that must be evaluated depending on the result of an earlier term. Hence, branching is involved. – jwdonahue May 30 '18 at 19:48
  • @jwdonahue Of course but every short-circuit is an additional branch. In certain scenarios executing two expressions (for example) is faster than checking the result of the first before executing the second even if it's often the case that the second is irrelevant. Again, this is rarely important. The case someone made to me for this was for things like matrix multiplication where you have lots of simple evaluations. – JimmyJames May 30 '18 at 20:57
  • The case where the short-circuit evaluation mechanism can be bad, is where there needs to be side effects for more than one term in the expression evaluation. In other words, all side-effects must happen before deciding to take the one branch. Where there are no side effects involved, the compiler can generate speculative branch execution and there will still only be on decision point, so yes, you are pointing out an esoteric circumstance where there are no side-effects and the compiler or the CPU can't do speculative execution. – jwdonahue May 30 '18 at 21:22
0

Pascal didn’t define whether AND and OR use short circuit evaluation or not, giving you the worst of both worlds.

C and C++ have bitwise operations & and | which in practice give you non-short circuit operations. And compilers are free to evaluate any way they like if it doesn’t make an observable difference.

  • @Deduplicator: As noted, Pascal didn't define whether AND/OR use short-circuit evaluation. That means "not knowing". – supercat May 30 '18 at 23:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.