Explicit Implicitness

Wednesday, October 14, 2009
Thinking more about implicit type conversion.

I noticed that Wikipedia's article on type conversion states that the term "coercion" means implicit type conversion. This didn't exactly sync up with my understanding of the term, but I certainly could be wrong. Actually, I hope Wikipedia is correct, as it solves a difficult problem for me - what to name the type conversion method. In accordance with my general policy on naming, I don't want to steal commonly used names like "convert" and give them special meaning. The term "coerce" is just esoteric enough that I don't feel quite so bad about reserving it.

I've also decided to diverge from C++ in one important respect: In C++, a constructor with a single argument implicitly acts as a conversion function, unless you opt-out by declaring it explicit. I would prefer to opt-in rather than opt-out. In fact, I'm thinking of divorcing implicit conversions from constructors entirely.

In other words, you have to explicitly declare your implicitness :)

My thought at this moment is that implicit conversion is enabled by declaring a static member function named "coerce" that takes an input argument of the value to be converted, and produces the converted value. Although the declared return type of the coerce method must be the same as the class in which it occurs, the *real* type of the object can be a subclass or any compatible type.

Thus, we can implement auto-boxing by declaring the following methods in class Object:

   static def coerce(value:Object) -> Object { return value; }
   static def coerce[%T] (value:T) -> Object { return Boxed[T](value); }

We want to only box values which aren't already derived from Object. Unfortunately, I'm not sure that the above will work - that is, given a subclass of Object, I am not sure which method the overload resolver will choose. I might have to implement qualifiers on the pattern variable in order to get this to behave as expected.

Auto-stringification can also use the coerce() technique:

   static  def coerce(value:Object) -> String { return value.toString(); }

For the moment, I'm going to limit the use of "coerce" by requiring it to be a member of the class that you are coercing to. I may relax this restriction later, if it proves to be necessary.


Post a Comment