Cast(), Str(), or Transform() — Choose wisely!
It’s been said that if you can’t do something 3 different ways in FoxPro, then it can’t be done. I’m not sure where this phrase originated, but it’s stuck with me over the years. With options though, come responsibility. Yes, you can often solve a problem using several methods, but your job as a developer is to pick the most reliable and best performing of the options available. This could mean making a choice to use the REPLACE statement instead of SQL-UPDATE, MEMLINES/MLINE over ALINES, or TRANSFORM instead of STR.
Trimmed conversion of number n
For example, run this code from a program file a few times over. They are functionally equivalent, producing a trimmed string conversion of a number n:
clear nSec = SECONDS() FOR n = 1 TO 100000 lc = ALLTRIM(STR(n)) NEXT ? "Run 1 with STR(): " ?? SECONDS() - nSec nSec = SECONDS() FOR n = 1 TO 100000 lc = TRANSFORM(n) NEXT ? "Run 2 with TRANSFORM(): " ?? SECONDS() - nSec nSec = SECONDS() FOR n = 1 TO 100000 lc = CAST(n as Varchar(10)) NEXT ? "Run 3 with CAST: " ?? SECONDS() - nSec
You will notice right away that using CAST is by far the fastest (on average 2.5 times faster than ALLTRIM(STR())). Transform is a little faster than ALLTRIM(STR()) as well (on average 1.3 times faster using 100000 iterations as a test). If you reduce the number of iterations, this ratio reduce until finally ALLTRIM(STR()) begins to outperform TRANSFORM().
CAST is new to VFP9, so it is likely that it hasn’t made its way into a lot of your code — but perhaps some refactoring is in order! Especially in loops with many iterations or in SQL statements.
nLength conversion of number n
In the previous example, I returned a trimmed string of a number n. Consider that you want your numeric transformation to be of a particular size. What’s faster now?:
clear nSec = SECONDS() FOR n = 1 TO 1000000 lc = STR(n,10,2) NEXT ? "Run 1 with STR(): " ?? SECONDS() - nSec nSec = SECONDS() FOR n = 1 TO 1000000 lc = TRANSFORM(n,"9999999.99") NEXT ? "Run 2 with TRANSFORM(): " ?? SECONDS() - nSec nSec = SECONDS() FOR n = 1 TO 1000000 lc = CAST(n as Character(10)) NEXT ? "Run 3 with CAST: " ?? SECONDS() - nSec
Again, CAST is faster than both STR and TRANSFORM (on average 2.7 times faster). Transform (which surprised me) still outperforms STR() (at 100,000 iterations, the ratio on average was still about 1.3). But take heed! The last example here isn’t functionally equivalent: CAST will left-align the results, while STR and TRANSFORM right-align the results. STR and TRANSFORM will round decimals to the specified amount, CAST will not.
Obviously, there are many things you can do with TRANSFORM that you cannot do with either STR or CAST. In most cases, however, CAST seems to be the way to go. Using ‘Varchar’ in CAST trims your string, using ‘Character’, does not. TRANSFORM automatically produces a TRIMed string as well, unless you specify a format code.
I like the new CAST function in VFP9. I got used to using it while writing code to interact with SQL Server. But I soon found CAST sneaking into my code in various other places — often replacing ALLT(STR()) and TRANSFORM.
I'm a Quant Technical Specialist (Data Warehousing and Business Intelligence), with expertise in business analysis, data modeling, and data integration. I have extensive experience developing vertical and integrated desktop, Internet, and BI applications spanning municipal, clinical, and financial industries.

August 13th, 2007 at 2:04 pm
Great to know, Tod.
I’ve been switching a lot of items over to Transform primarily because we’re hearing a lot of “can you make it look like xxxx” but using CAST makes very good sense.
What’s too bad is that now that you have 3 ways of doing the same thing, you have 3 ways of screwing it up!
August 13th, 2007 at 3:20 pm
Very neat, Todd! I knew about CAST for SQL statements, but hadn’t thought of using it in place of these other commands in code. Thanks!
August 19th, 2007 at 3:45 pm
[…] post by Tod McKenna explains the differences between CAST(), STR() and TRANSFORM() in Visual FoxPro. He […]