I think the issue of type coercion (forcing one type to another) should be decided separately from the issue of "implicit" types (recognizing when an untyped variable can be KNOWN at a given point to hold a specific type, even if it isn't explicitly stated.)

As far as true coercion goes: for the sake of example, let's assume we have a class, C<MyClass>, that doesn't inherit from str, but that can be converted to a str if necessary.

sub foo(str $s);

   my str $a = 'blah';
   my MyClass $myclass = MyClass.new;

   foo($a);          # OK
   foo($myclass);    # COMPILE ERROR; WRONG TYPE

That last line is a type coercion... we know it's one type, but it needs to be another. Previous implication is that you'd do it like this:

foo($myclass.str); # OK

I'm not keen on that syntax, personally, because it means you're cluttering up the method namespace of MyClass with every possible type/class you want to be able to convert to, which I have to think would cause problems in larger libraries. I at one point suggested:

   class MyClass {
       to str {...}
       to num {...}   # etc
   }

foo($myclass to str);

as a way to separate the 'coercions' namespace from the normal 'methods' namespace. But regardless, the A6 question being asked is whether the C<sub> or C<multi> can know when it's allowed to implicitly coerce arguments from one type to another, such that

foo($myclass);

can work without having to first define 'foo' variants to explicitly handle each and every possible type. Possibilities:

(1) If MyClass isa str, or MyClass implements str, problem solved -- it will work on anything that a str works on, right? (But maybe you don't want your class to actually _implement_ str, because we don't ordinarily want it to be considered a str... we actually just want a one-directional way to _convert_ instances to strs.)

(2) Maybe we can mark a given C<multi> as being specifically willing to coerce an argument if necessary, probably with a trait:

multi foo (str $s) {...} # Normal syntax
multi foo ($s to str) {...} # OK, should attempt to COERCE $s to a str
multi foo (str from $s) {...} # alternate spelling???


... thereby identifying that we want to convert it if the compiler and/or runtime can figure out how. Would something like that achieve the desired effect?

My main points being, untyped-to-typed coercion is different from true type coercion, and that the 'coerce to' and 'implements' relationships might be worthy of syntactic separation.

POMTC: 70%

MikeL



Reply via email to