New Syntax in twinBASIC: Part 1

Let's cover some new syntax in twinBASIC, including "AndAlso/OrElse"; the ternary If() operator; and "Continue For" and its cousins.

New Syntax in twinBASIC: Part 1

To learn more about twinBASIC, join me at this year's virtual Access DevCon where I will be presenting this exciting new project from vbWatchdog creator, Wayne Phillips.

New Syntax in twinBASIC

twinBASIC introduces several new language features beyond simple VB6 compatibility.  Of course, while this syntax and these features are new compared to VB6, most of them are found in VB6's second cousin, twice-removed, VB.NET.

In this article, I'll cover the following new syntax:

  • Short-circuiting boolean operators, AndAlso and OrElse
  • The ternary operator, If()
  • Statements to skip to the next loop operation, Continue For, et al.

Short-circuiting operators

VBA does not have short-circuiting AND or OR operators.

What exactly is short-circuit boolean evaluation, you ask?  Here's an excerpt from an article I wrote on the topic:

Short-circuit boolean evaluation

In order for an AND statement to evaluate to True, both expressions must evaluate to True. Thus, if the first expression is False, there is no need to evaluate the second expression; the entire statement will be False based solely on the value of the first expression. The same goes for OR statements. If the first expression is True, there is no need to evaluate the second expression; the entire statement will always be True.

Short-circuit boolean evaluation takes advantage of these properties of the AND and OR operations to evaluate only those expressions necessary to return a result. In other words, the second expression of an AND statement is only evaluated if the first expression is True. Likewise, the second expression of an OR statement is only evaluated if the first expression is False.

Without short-circuit boolean evaluation, these expressions will raise errors when the TotalItems variable equals zero:

If (TotalItems <> 0) And ((CompletedItems / TotalItems) > 0.5) Then
    Debug.Print "More than halfway there."
End If

If (TotalItems = 0) Or ((CompletedItems / TotalItems) >= 1) Then
    Debug.Print "Nothing more to do."
End If
Both of these If statements will raise errors when TotalItems equals zero.

Simply changing the behavior of the AND and OR operators would break backwards compatibility.  So, twinBASIC follows VB.NET's lead and introduces two new keywords to enable explicit short-circuiting behavior, AndAlso and OrElse.  

Let's rewrite the above statements so that they won't throw errors when TotalItems equals zero:

If (TotalItems <> 0) AndAlso ((CompletedItems / TotalItems) > 0.5) Then
    Debug.Print "More than halfway there."
End If

If (TotalItems = 0) OrElse ((CompletedItems / TotalItems) >= 1) Then
    Debug.Print "Nothing more to do."
End If
Short-circuit boolean evaluation avoids errors when TotalItems equals zero in this code.

An actual ternary If operator

VBA lacks a proper ternary If operator.  In its place is the immediate If function, IIf().  The downside to using a function for this behavior is that both the true and false parts of the function are always evaluated.  This has performance implications and also limits the usefulness of the function when one part or the other could raise an error based on the value of the conditional.

Instead of:

'This will throw an error if Total = 0
Avg = IIf(Total = 0, 0, Count / Total)

You can use this:

'This avoids the error because Count / Total 
'   is not evaluated when Total = 0
Avg = If(Total = 0, 0, Count / Total)

To see this in action in twinBASIC, I ran the following two similar expressions through the Debug Console.  The first one, using the IIf function, raised an error because the function evaluated the division by zero.  The second one, using the If operator, raised no such error:

The only difference between the two expressions above is that we swapped out the IIf function for the new If operator.

Continue For

My highest-voted answer on StackOverflow is this one, VBA – how to conditionally skip a for loop.  So I know this feature is a welcome addition to the BASIC language.

Instead of this:

For i = LBound(Schedule, 1) To UBound(Schedule, 1)
    If (Schedule(i, 1) < ReferenceDate) Then
        PrevCouponIndex = i
        Goto NextIteration
    End If
    '....'
    'a whole bunch of other code'
    '....'
    NextIteration:
Next

We can avoid the dreaded Goto and use this in twinBASIC:

For i = LBound(Schedule, 1) To UBound(Schedule, 1)
    If (Schedule(i, 1) < ReferenceDate) Then
        PrevCouponIndex = i
        Continue For
    End If
    DF = Application.Run("SomeFunction"....)
    PV = PV + (DF * Coupon / CouponFrequency)
    '....'
    'a whole bunch of other code you are not showing us'
    '....'
Next

The logic is identical, but replacing the GoTo statement makes for safer code, as we no longer have to worry about another developer coming along in the future and accidentally writing code between the NextIteration: label and the Next statement.

Here's the full list of related statements that are part of the twinBASIC language:

  • Continue For
  • Continue While
  • Continue Do
  • Exit While

All original code samples by Mike Wolfe are licensed under CC BY 4.0