The New Xojo If() Operator

Xojo 2014 Release 1 introduced a new conditional operator: if(). Although it looks like a function, it is not. It is an operator, and behaves in a very special way.

IIF Functions

Many developers, have kept a function called iif in their toolbox of reusable code. It typically looks something like this:

Function IIF (Test As Boolean, TrueValue As Variant, FalseValue As Variant) As Variant
  If Test Then
    Return TrueValue
    Return FalseValue
  End If
End Function

This makes it very handy to write something like:

Dim Message As String = "You have " + iif(NumItems = 1, "1 item", Str(NumItems) + " items") + " in queue."

Nothing we couldn't do with a few more lines of code:

Dim Message As String = "You have "
If NumItems = 1 Then
  Message = Message + "1 item"
  Message = Message + Str(NumItems) + " items"
End If
Message = Message + " in queue."

So we get it done in 1 line instead of 7 lines. Not a deal breaker by any means, but there are certainly times when this behavior is useful.

The Problem With IIF In Xojo

When calling a function, all possible parameters must be evaluated before the function can begin. In this example, the function receives True, "1 item", and "X items". Not a big deal in this example, but consider the following usage:

Function CellValue (Index As Integer) As String
  Return IIF(Index <= UBound(Cells) And Index > -1, Cells(Index), "")
End Function

The idea is to return the value from Cells(Index) only if the index is a valid value. With such a function, Cells(Index) will always be evaulated, so if passing in an invalid Index, an OutOfBoundsException will be thrown and thus defeating the purpose entirely.

The other problem is casting. The possible responses are converted to variants, and the function returns a variant. Variants, although very helpful at times, are also very evil and prevent the compiler from doing its job. Consider this code:

Dim Message As String = IIF(TextField1.Text <> "", TextField1, "No Value")

This will compile without error, but it'll produce an exception at runtime. Of course it is a typo, the second parameter should have been TextField1.Text, but that's entirely the point. The compiler should have caught that typo.

The Solution

The new if() operator solves all these problems. It behaves exactly like the traditional If construct, but allows for assignment, something the If construct cannot do.

Most importantly, input parameters are not evaluated until needed. So if the boolean evaluates to true, the false value will never be evaluated at all. This means our CellValue example from earlier will work as intended:

Function CellValue (Index As Integer) As String
  Return if(Index <= UBound(Cells) And Index > -1, Cells(Index), "")
End Function

The if() operator also checks types. The type it returns is the lowest common denominator of the two return values. If there is nothing common between the two, a compiler error is thrown. And then the value returned must also be assignable to whatever variable it is being assigned to. So it would have caught our TextField1 typo from earlier.


Overall, the new if() operator has its places where it's useful. Not only can you compact some lengthy parts of code but it also helps in replacing your custom IIF function or porting from languages that already use IIF.

Special Attributes In Xojo

Introduction to Attributes

Attributes are key-value pairs that can be attached to nearly anything in a Xojo project. They actually don't even need a value, it is perfectly acceptable to leave the value empty. All three of the following are valid attributes:

Key = True
Key = "String"

But, reading the attributes of an item requires introspection and overall isn't very useful. So what value is there in attributes that warrants a blog post? There are two special attributes the IDE is aware of and actively looking for on objects: Hidden and Deprecated.

The Hidden Attribute

This attribute hides the item from autocomplete and the debugger. It does not prevent access to the item, it simply hides it. Many developers used an underscore prefix trick in the past to accomplish the same thing, but the IDE now disallows that.

The Hidden attribute is especially useful for cleaning up the properties backing a computed property. Consider the following:

Public Computed Property HasFocus As Boolean
        Return Self.mHasFocus
  End Get
        If Self.mHasFocus <> Value Then
            If Value Then
            End If
        End If
    End Set
End Property

Private Property mHasFocus As Boolean

When the object is viewed in the debugger, both HasFocus and mHasFocus will appear with identical values. By placing the Hidden attribute on the mHasFocus property, the property is completely ignored by the debugger and autocomplete. In this case, autocomplete isn't as important, since the property is private anyway.

The attribute can also be used on methods, including methods in interfaces. A good place to use this attribute is any of the Operator_ methods, such as OperatorConvert and OperatorCompare. Constructors are also a great place for this attribute. Normally, these methods will appear in the autocomplete list, but should probably never be called directly. Yes, calling the constructor chain is useful, but this attribute does not prevent that.

The attribute helps to make the object self-documenting. Since autocomplete will not show these items, there is reduced risk of using the object incorrectly.

The Deprecated Attribute

The Deprecated attribute allows developers to mark nearly anything as deprecated, while hiding it from autocomplete just like the Hidden attribute. This is most useful for developers who release their code to the public, but can also be useful in code which is shared between projects.

With the Deprecated attribute defined, any line using the item in question will be flagged when running an Analyze operation from the Project menu. The IDE will not show the deprecation warning when the project is loaded however, and will still run the project normally. The attribute only applies to the Analyze feature.

This can be useful in refactoring. Ever add a single character to a method name so the compiler will highlight every use of that method? While this is quite an effective trick, the project is left broken until every instance is fixed. Alternatively, the Deprecated attribute could be added to the method. When using Analyze, every use will be highlighted just as intended, but the project can be updated in pieces rather than all at once.

If releasing the code for the public to use, Deprecated can be even more powerful. This happens all the time in the Xojo framework, and happens to all code as it grows.

Imagine a List class that maintains a list of items. The class is released with a method Item(Index As Integer) As String for accessing individual items. Later, for the sake of clarity, it is decided that Item really should have been called ItemAtIndex. So the developer marks Item as deprecated.

When a user runs the analyzer, all uses of Item will be highlighted with the text "Item is deprecated." However, this won't help the user correct the problem. The user will need to look up in the documentation what should be used instead. This is when adding a value to the Deprecated attribute makes sense (remember: attributes are key/value pairs). Values are code, so when inputting a string, quotes will be necessary. In this case, the value will be "ItemAtIndex". Now the project analyzer will show "Item is deprecated. You should use ItemAtIndex instead."


Creating your own custom attributes aren't very useful because they are difficult to use through introspection. However, the "special" built in hidden and deprecated attributes can provide a lot of information to the Xojo IDE about the intention of your code which will ultimately make your code easier to use.