To conform or to convert?
October 2004Can you assign the value 3 to a "real" variable? In most programming languages
the answer is yes, but only as a kind of special, somewhat shameful trick. In an
object-oriented context we might be tempted to believe that inheritance will
take care of the issue, but if the temptation lasts much longer than half a
minute it's time for a refresher course in object technology. Polymorphism (say
attaching a value of type SAVINGS_ACCOUNT to an entity of type ACCOUNT) doesn't
change any objects; conversion does. Since 3 is an integer, not a real, the
value that will be assigned is a different one, the real 3.0. Such a mechanism,
it seems, only exists to accommodate traditional modes of computation, not only
pre-O-O but also pre-computer-era. Better not mention it too loudly.
And what if it weren't so -- if conversions were a great, innovative programming
idea? That's what recent versions of Eiffel have discovered. Not only is
conversion compatible with an object-oriented framework: it actually enriches it
considerably, complementing inheritance.
With the new conversion mechanism of Eiffel -- almost completely implemented in
today's EiffelStudio -- lots of things fall into place: the language lets you
convert between basic types such as INTEGER and REAL without any special rules,
but it also allows you to use conversions for your own types, as in
next_new_year_date := [1, "January", 2004]
|
as long as one of the creation procedures of class DATE takes a TUPLE [INTEGER,
STRING, INTEGER] as argument and is marked with the keyword `convert'. This is
also what in EiffelStudio enables you to pass Eiffel strings to .NET routines
and back, even though .NET strings are internally different: silent conversions
occur, not bothering the programmer. (Imagine having to write ("ABCDE").to_dotnet_string
every time you pass a string, and similarly when you get one back!)
The mechanism has been carefully crafted to make sure that everything is clear,
unambiguous, and efficient. The key property is the "Conversion Principle":
A type may either convert or conform to another, but not both.
This way, when you see `a := b', or `p (b)' where `a' is the corresponding
formal, you know exactly what to expect: if there is conformance, through
inheritance, we'll just have polymorphism, with no change of object; if there's
convertibility, the object will change. (If there is neither, of course, the
assignment or argument passing is prohibited, and the compiler will tell you in
no uncertain terms!)
There's more fine tuning. For example, a type may conform "from" another, or
"to" another. The reason is very simple: when you want one of your types T to
convert to or from a type A, for example INTEGER, or the String type of .NET,
you can adapt your class, but not always the other side's class. (Try telling
Microsoft to change .NET "String" for you.) So sometimes you'll specify that T
converts to the other guy, and sometimes that the other guy converts to T. As
you may have guessed by now, clarity and unambiguity again intervene to dictate
a companion principle:
A type may convert to another, or the other from it, but not both.
So once again, when you see an assignment or argument passing, you know
immediately if a conversion will occur, and if so, which exact mechanism, "to"or
"from", it will trigger.
Since convertibility was introduced into ISE Eiffel about three years ago, then
refined progressively and brought to the ECMA standardization process, users
have come to appreciate it as a key component of the approach. It's one of these
Eiffel innovations that provide a major boost to the power of expression of the
language, and that programmers immediately start using, discovering
applications often far beyond what had been initially envisioned.
There's nothing like Eiffel's conversion in other common languages. Try it!
-- Bertrand Meyer
References:
The original article on conversion is at:
http://www.inf.ethz.ch/~meyer/publications/joop/conversion.pdf
This introduces the basic concepts but many details have been improved since
then. |