February 12, 2003
My suggestion to change cast would make it expressible in my template syntax, if unimplementable:

   $to cast ($to, $from value) { ... }

But if cast were made into a normal template function for the purposes of the semantic phase, then it would enable boxing and unboxing a la C#.  C# allows you to do this:

   int i = 4;
   object o = i; // Create an object instance representing i.
   int j = o; // Check that "o" can be casted to int and do so.

The problem is that because the boxed object results in a different instance of the value object, this pseudo-code:

   struct Foo { int x = 10; }
   Foo p = new Foo ();
   object box = p;
   p.x = 20;
   Console.Write(((Foo)box).x);

Behaves differently depending upon whether Foo is a struct or a class; it tries to bring their syntaxes too close together, IMO.  Anyway, I'm just justifying the fact that my boxing/unboxing takes more effort to use.  Here's the partial implementation:

   struct generic
   {
       TypeInfo type;
       void *data;
   }

   generic cast ($to (generic), $from value)
   {
       generic result;

       result.type = $from;
       result.data = ((ubyte *) &value) [0 .. $from.size].dup;
       return result;
   }

   $to cast ($to (int, float, double, ...), $from (generic) value)
   {
       TypeInfo type = value.type;

       if (cast (IntType) type)
           return *(int *) value.data;
       if (cast (FloatType) type)
           return *(float *) value.data;
       if (cast (DoubleType) type)
           return *(double *) value.data;
       ...
       throw new CastError (type, $to);
   }

   /* Other implementations needed for struct and class. */

And some usage:

   int i = 4;
   generic o = cast (generic, i);
   int j = cast (int, o);