Skip Menu |
Report information
Id: 128927
Status: open
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: zefram [at] fysh.org
Cc:
AdminCc:

Severity: (no value)
Tag: Bug
Platform: (no value)
Patch Status: (no value)
VM: (no value)



From: Zefram <zefram [...] fysh.org>
To: rakudobug [...] perl.org
Subject: [BUG] coercions don't ensure result type
Date: Sun, 14 Aug 2016 16:01:26 +0100
Download (untitled) / with headers
text/plain 1.6k
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: Show quoted text
> (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: Show quoted text
> (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
On Sun, 14 Aug 2016 08:01:48 -0700, zefram@fysh.org wrote: Show quoted text
> 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
Just a thought: we cannot avoid runtime checks when the argument can be anything, but if we know its type at compile time, and if we found and introspected the coercion method, and if that method defined a return type, we might be able to catch errors ahead of time. (We'd still have to deal with Nil/Failure at runtime, though.)


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org