# New Ticket Created by  Zefram 
# Please include the string:  [perl #128927]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/Ticket/Display.html?id=128927 >


The description of coercion in S02 says:

# The type outside the parens indicates the desired end result, and
# subsequent code may depend on it being that type.

Rakudo does not actually ensure that the result of a coercion is of the
requested type.  We can readily see this by constructing an object with
an uncooperative coercion method:

> (sub (Int() $a) { $a })("abc" but role { method Int () { :xyz } }).perl
:xyz

Here the sub's $a is supposedly guaranteed to be an Int, but it's actually
a Pair.  This doesn't only arise from code deliberately constructed to
do this.  It also arises from some reasonable use of the built-in numeric
types, among which there are a couple of uncooperative coercion methods:

> (sub (FatRat() $a) { $a })(Inf).^isa(FatRat)
0

The value received in $a here is apparently a Rational[Num,Int], and it
fails to .perl.  It's definitely not the promised FatRat.

Because coercion methods are identified by the name of the target type,
rather than by some first-class reference to the type, and because
scoping allows the same name to refer to different types in different
places, there's an inherent possibility that a coercion method written
with cooperative intent might be invoked for coercion to the wrong type.
Similarly, because coercion methods aren't formally distinguished from
other named methods, it's inherently possible for a method never intended
for coercion to be invoked for a coercion.  Both of those situations
look like an uncooperative coercion method.  So it is not possible to
resolve this problem by putting the onus entirely on coercion methods
to return the right type.  There has to be enforcement.

-zefram

Reply via email to