Don’t Overuse Variants

At XDC 2019 my session was titled Xojo Design Mistakes (the alternate but way longer title was ‘Thankfully time travel doesn’t exist or my future self might travel back and murder my younger self for the stupid coding mistakes I’ve made’).  These are things that I’ve discovered over the years, both in my own projects and in other peoples projects that are just plain wrong or less than ideal.  This will be an on-going series since I had well over 50 slides and left about 150 out.  So when I get bored I’ll bring these topics up.

Variants are a very powerful datatype in Xojo. It allows you do set it to anything including null. It’s a wonderful thing to use in ListBox row, column, and cell tags where the you, the developer, could be anything into it.

Variants are evil too if you use them in ways you shouldn’t. Take the example below:

This is truly a made up example but it shows how subtle Variants can stab you in the back. Just adding the three Variants together where one is a string, the other an integer, and the other a double, can change depending on the order they’re used. Frankly, I don’t care how the compiler came up with the value because in both cases it’s ‘wrong’. Wrong in the sense that it depends on order and no programmer should have to depend on order.

How did we get here? Variants have implicit conversion. So if you try to add a variant to an integer it attempts to convert it to an integer. If you try to add it to a string it converts it to a string. What happens if you have a number inside the string and it really should be a string? The answer is that it depends.

That’s just a poor use of the language, in my opinion. Xojo is a strongly typed language and I like that it won’t let me willingly add an integer to a string. I like that I have to explicitly convert from one datatype to another. Variants break that rule in that they’ll implicitly convert from one to the other and the compiler will never tell you.

The variant datatype allows the Xojo developer to query what it is. For example you can use the Type method to see what variable type is it. You can see if it’s an array using the IsArray method. You can see if it’s a Numeric value using IsNumeric but you get into the same problem where assigning an integer 8 and a string “8” will both return true from IsNumeric. So it’s a bit of a problem because it could be either. We should rename it Schrödinger’s datatype because it could either either value until the compiler asks for it.

Auto was introduced in the Xojo framework (deprecated now?) to replace Variant. It didn’t do any implicit conversion for you. In fact, it wouldn’t even tell you what datatype was in it and the only way to do was to use Introspection. It certainly solved the problem of implicit data conversion but replaced it with a harder to use datatype. For what it’s worth I didn’t think it was hard to come up with your own “what is your type” methods using the extends keyword but it was something that many Xojo developers weren’t comfortable doing and frankly seemed silly to rely on Introspection to do that work.

I turned down a project many years ago because the original developer had used Variants for everything. Didn’t matter what (local, object, global), they used variants and they wanted me to tell them why their project wasn’t working right. When I told them I wouldn’t do it and asked why they had used variants for everything they simply said, “Because they could be anything. Why not use them?”

I know that many languages are not as strictly typed as Xojo and perhaps that’s where they came up with that mentality. I find some comfort in knowing that if I try to put a string into a numeric value the compiler won’t let me unless I explicitly convert it. I like the certainty of knowing that my data can’t change on my unless I tell it too.

Variants are good for storing things temporarily. Stashing values and objects in a Tag for use later is convenient and useful and a good use for them. For everything else it makes sense to use a datatype. If you finding yourself using a lot variants you should rethink what you’re doing because they can subtly make your calculations change in ways you don’t expect.

Formatted Text Control 3.2.1

BKeeney Software has released version 3.2.1 of the Formatted Text Control, a canvas based word processing control for Xojo Mac OS X and Windows applications. The FTC is an alternative to the built-in TextArea control and allows for in-line graphics, hyperlinks, custom components, better RTF support and much more. The demo project has quite a few examples, including a Masked Text Field, XojoScript example, Embedded FTC (in your own canvas), as well as a word processor with page view.

The Formatted Text Control costs $150 and is 100% unencrypted Xojo code. Version 3 and above requires the use of the Text Input Canvas plugin (included in package) to allow for proper text handling in Cocoa builds.

Download links and more information at http://www.bkeeney.com/formatted-text-control/ 

This version has a number of bug fixes reported by users since release. It is recommended for all users. Registered users should be receiving an email from our automated distribution system.

Bug Fixes:

  • Fixed issue where all StyleRuns after a hyperlink will also be marked as hyperlink
  • Issue #4074: RTF clipboard ignores hyperlinks with umlauts and cuts them
  • Issue #4087: missing RTF space after “\kerning0” keyword
  • Issue #4130: FTXojoScriptField: Left part of the text is hidden by the section of the line number.
  • Issue #4135: Migrating texts from a TextArea to the FTC (Ich migrieren Texte aus einer TextArea in das FTC)
  • Issue #4196: Remove GOTO calls from FTC