Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Automatic coercion and context

7 views
Skip to first unread message

Joshua Choi

unread,
Sep 30, 2006, 2:48:04 PM9/30/06
to perl6-l...@perl.org
Kudos to all(@Larry)!

How does automatic coercion work? Like, when a routine wants a
parameter of a certain type, and is called with an argument of a
different type that C<does>

(For instance, is it something a little like this?

multi sum ( Num $addend1, Num $addend2 --> Num ) { ... }
multi say ( Str *@stuff ) { ... }

class Str does Num { ... }

class Num does Str { ... }

say sum "3", "4";

1. C<sum()> automatically coerces its C<Str> arguments into C<Num>
parameters because C<Str.does: Num>.
2. C<say()> then automatically coerces its C<Num> arguments into
C<Str> parameters because C<Num.does: Str>.

...Or am I completely off the mark?)

Joshua Choi

Jonathan Lang

unread,
Sep 30, 2006, 3:39:51 PM9/30/06
to Joshua Choi, perl6-l...@perl.org
My understanding is that "does" will prevent coercion. In particular,
it is erroneous to say that 'Str does Num' or that 'Num does Str'.

If you say 'Foo does Bar', what this means is that anything Bar can
do, Foo can do, too. As such, any routine that asks for a Bar can
just as easily be given a Foo. It doesn't convert the Foo into a Bar;
it simply uses it as is. As such, the only time coercion might take
place is when the object that you're trying to use _doesn't_ do the
role that's being asked for.

--
Jonathan "Dataweaver" Lang

Lanny Ripple

unread,
Sep 30, 2006, 5:02:44 PM9/30/06
to
I don't think it's specced yet. The topic came up on #perl6 the
other day:

http://colabti.de/irclogger/irclogger_log/perl6?date=2006-09-30,Sat&sel=16#l36

At a very wild guess there will be some way using a sub that an
object can specify how it will coerce in different contexts.
Whether that's internal to a class or external is @Larry's guess.
Should be interesting to see how MMD handles an object that
coerces to two differing contexts both at the same dispatch priority.

class Foo {
...
}

multi * (Foo $x --> Num) { ... }
multi * (Foo $x --> Bool) { ... }

multi do_work (Bool $b) { ... }
multi do_work (Num $n) { ... }

my Foo $o .= new();
do_work( $o );

Maybe something with a Signature specifying the object's
preference for coercion?

class Foo is also {
has $!COERCE = :( Num, Bool );
}

do_work( $o ); # dispatched as do_work( Num $o );

No end to the hokeyness that could be thought up. :)

-ljr

Jonathan Scott Duff

unread,
Sep 30, 2006, 6:23:54 PM9/30/06
to Joshua Choi, perl6-l...@perl.org
On Sat, Sep 30, 2006 at 11:48:04AM -0700, Joshua Choi wrote:
> How does automatic coercion work?
[ deletia ]

> 1. C<sum()> automatically coerces its C<Str> arguments into C<Num>
> parameters because C<Str.does: Num>.
> 2. C<say()> then automatically coerces its C<Num> arguments into
> C<Str> parameters because C<Num.does: Str>.
>
> ...Or am I completely off the mark?)

I hope you're way off the mark. Automatic coercion was one of the
annoyances I remember from C++. Debugging becomes more difficult when
you have to not only chase down things that are a Foo, but anything
you've compiled that might know how to turn itself into a Foo.

I'm of the opinion that if you need a routine to handle multiple
"types" then you should define it such that it is sufficiently general
enough to do so without the benefit of added behind the scenes magic.

-Scott
--
Jonathan Scott Duff <du...@pobox.com>

Bob Rogers

unread,
Sep 30, 2006, 7:22:05 PM9/30/06
to du...@pobox.com, Joshua Choi, perl6-l...@perl.org
From: Jonathan Scott Duff <du...@pobox.com>
Date: Sat, 30 Sep 2006 17:23:54 -0500

On Sat, Sep 30, 2006 at 11:48:04AM -0700, Joshua Choi wrote:
> How does automatic coercion work?
[ deletia ]
> 1. C<sum()> automatically coerces its C<Str> arguments into C<Num>
> parameters because C<Str.does: Num>.

Wouldn't it be better to do the coercion explicitly? E.g.:

multi sum ( Str $addend1, Num $addend2 --> Num ) { sum 0+$addend1, $addend2 }
multi sum ( Num $addend1, Str $addend2 --> Num ) { sum $addend1, 0+$addend2 }

After all, there may be more than one way to do the coercion, especially
for something more complicated than a number.

> 2. C<say()> then automatically coerces its C<Num> arguments into
> C<Str> parameters because C<Num.does: Str>.
>
> ...Or am I completely off the mark?)

I hope you're way off the mark. Automatic coercion was one of the
annoyances I remember from C++. Debugging becomes more difficult when
you have to not only chase down things that are a Foo, but anything
you've compiled that might know how to turn itself into a Foo.

I tend to agree, FWIW.

-- Bob Rogers
http://rgrjr.dyndns.org/

Jonathan Lang

unread,
Oct 1, 2006, 5:17:45 AM10/1/06
to du...@pobox.com, Joshua Choi, perl6-l...@perl.org
Jonathan Scott Duff wrote:
> I hope you're way off the mark. Automatic coercion was one of the
> annoyances I remember from C++. Debugging becomes more difficult when
> you have to not only chase down things that are a Foo, but anything
> you've compiled that might know how to turn itself into a Foo.

OTOH, there is a time and place for so-called "automatic" coercion,
such as the way that perl freely converts between Str and Num.
Indeed, ISTR something about standardized stringifying and numifying
method names that let _any_ object turn into a string or number (or
boolean, IIRC) when placed in the appropriate context. And I can see
some benefit to extending this ability to other types, as long as it's
used sparingly. In particular, I'm thinking about complex numbers -
it would be nice to see perl convert between the rectilinear and polar
representations of complex numbers in the same way that it converts
between Num and Str.

--
Jonathan "Dataweaver" Lang

0 new messages