Strong-typing just rocks
By A.Bouchez on 2011, Sunday December 11, 09:59 - Pascal Programing - Permalink
To my understanding, the so-called "strong-typing" feature is one big benefit of the Delphi object pascal language.
As stated by wikipedia:
Most generally, "strong typing" implies that the programming language places severe restrictions on the intermixing that is permitted to occur, preventing the compiling or running of source code which uses data in what is considered to be an invalid way. For instance, an addition operation may not be used with an integer and string values; a procedure which operates upon linked lists may not be used upon numbers. However, the nature and strength of these restrictions is highly variable.
Some Delphi users may find this is a limitation of the language, in
comparison with other "fashionable" script idioms (like Python, Javascript of
Ruby). For me, runtime strong typing (alla Python or Ruby) is not true strong
typing. Simon Stuart just
proposed a smartstring kind of string, which is in fact a
weakstring type. As far as I understood his point, he wanted to
get rid of all the warnings emitted by Unicode-version of the Delphi compiler,
about explicit string conversion.
In fact, I use to go in the opposite direction. For wide projects, strong-typing is one of the big benefit of using Delphi (like other main "serious" languages like Java, C, C++, Ada or C#).
Our SQLite3/mORMot Framework has 100% UNICODE compatibility, that
is compilation under Delphi 2009/2010/XE/XE2. The code has been deeply
rewritten and tested, in order to provide compatibility with the
String=UnicodeString paradigm of these compilers. But the code
will also handle safely Unicode for older version, i.e. from Delphi 6 up to
Delphi 2007.
Since our framework is natively UTF-8 (this is the better character encoding for fast text - JSON - streaming/parsing and it is natively supported by the SQLite3 engine), we had to establish a secure way our framework used strings, in order to handle all versions of Delphi (even pre-Unicode versions, especially the Delphi 7 version we like so much), and provide compatibility with the Free Pascal Compiler.
Some string types have been defined, and used in the code for best
cross-compiler efficiency (avoiding most conversion between formats):
- RawUTF8 is used for every internal data usage, since both
SQLite3 and JSON do expect UTF-8 encoding;
- WinAnsiString where WinAnsi-encoded
AnsiString (code page 1252) are needed;
- Generic string for i18n (e.g. in unit
SQLite3i18n), i.e. text ready to be used within the VCL, as either
AnsiString (for Delphi 2 to 2007) or UnicodeString
(for Delphi 2009/2010/XE/XE2);
- RawUnicode in some technical places (e.g. direct Win32 *W() API
call in Delphi 7) - note: this type is NOT compatible with Delphi
2009/2010/XE/XE2 UnicodeString;
- RawByteString for byte storage (e.g. for
FileFromString() function);
- SynUnicode is the fastest available Unicode native
string type, depending on the compiler used (i.e. WideString
before Delphi 2009, and UnicodeString since);
- Some special conversion functions to be used for Delphi 2009/2010/XE/XE2
UnicodeString (defined inside $ifdef UNICODE...$endif
blocks);
- Never use AnsiString directly, but one of the types above.
Note that RawUTF8 is the preferred string type to
be used in our framework when defining textual properties in a
TSQLRecord and for all internal data processing. It's only when
you're reaching the User Interface layer that you may convert explicitly the
RawUTF8 content into the generic VCL string type,
using either the Language. UTF8ToString method (from
SQLite3i18n.pas unit) or the following function from
SynCommons.pas:
/// convert any UTF-8 encoded String into a generic VCL Text // - it's prefered to use TLanguageFile.UTF8ToString() in SQLite3i18n, // which will handle full i18n of your application // - it will work as is with Delphi 2009/2010/XE/XE2 (direct unicode conversion) // - under older version of Delphi (no unicode), it will use the // current RTL codepage, as with WideString conversion (but without slow // WideString usage) function UTF8ToString(const Text: RawUTF8): string;
Of course, the StringToUTF8 method or function are available to
send back some text to the ORM layer.
A lot of dedicated conversion functions (including to/from numerical values)
are included in SynCommons.pas. Those were optimized for speed and
multi-thread capabilities, and to avoid implicit conversions involving a
temporary string variable.
In fact, this enforce the n-tier layered architecture of the project:
RawUTF8is to be used at Storage and Business layers;stringtype for the User Interface (at the VCL level).
Warnings during the compilation process are not allowed, especially under Unicode version of Delphi (e.g. Delphi 2010): all string conversion from the types above are made explicitly in the framework's code, to avoid any unattended data loss.
With such an implementation pattern, we keep all our code benefit from the strong typing feature of Delphi, whereas we can handle safely Unicode content even with older Ansi versions of Delphi.
Comments are welcome on our forum.