On Wed, Nov 29, 2006 at 04:43:59PM -0500, Matt Diephouse wrote:
> Leopold Toetsch <[EMAIL PROTECTED]> wrote:
> >Am Mittwoch, 29. November 2006 05:50 schrieb Matt Diephouse:
> >> It also means that "string", "int", and "float" no longer work as MMD
> >> types -- you can't distinguish between native types and PMCs. I think
> >> this is the right way to go now that we have autoboxing; I don't see
> >> any reason to differentiate.
> >
> >I don't think this is the best strategy. It seriously prevents all native
> >type optimizations. While 'Integer' should be MMD-distancewise
> >close to 'int', it should not be the same.
>
> What native type optimizations? Using S, I, and N registers? If using
> an I register is faster, wouldn't you want to unbox an Integer PMC and
> use an I register anyway?
Sure, but Parrot is unboxing for us already, without us having
to do anything special:
.sub 'foo' :multi(_, String)
.param int abc
.param pmc xyz
...
.end
foo(1, 'xyz') # boxes 'xyz', leaves 1 alone
foo($P0, $P1) # unboxes $P0 to an int, leaves $P1 alone
If I understand things correctly, specifying :multi(_, String)
doesn't actually do any form of coercion, it simply says that
this sub is called only if the second argument is "compatible"
with the String type.
This is true even if we have a :multi with a native type:
.sub 'bar' :multi(int)
.param pmc abc
## abc is an autoboxed int for us here, even though this
## sub can only be reached if the (single) argument
## is an integer register or integer constant
...
.end
.sub 'baz' :multi(pmc)
.param string def
## Baz can only be called with a pmc argument, and that
## pmc (whatever it is) is auto-unboxed into a string register.
...
.end
I'm not at all an expert on the topic of multis, but it sounds to
me as though :multi is being somehow conflated with "when to
auto[un]?box". I think :multi should limit itself to being a way
of selecting which sub(s) to call, while autoboxing should be
based solely on the arguments of the caller and parameters of the
called sub (once that sub has been chosen by :multi).
Now then, for purposes of selecting the sub(s) to call, :multi
can take into account the fact that native arguments can autobox,
and call a sub that specifies the autoboxed type in :multi
(but preferring a sub with the native type in :multi, if one
exists).
And I don't think :multi should go the other way -- i.e., to
assume that a boxed type will match a native type in :multi.
With what I just described there's already a way to get that
semantic, namely:
.sub 'foo' :multi(Integer)
.param int xyz
...
.end
With this, a foo(1) or foo($I0) call will still find the sub,
but won't do any boxing or unboxing. If foo is called with an
Integer pmc argument, :multi will find the sub, and the Parrot
calling conventions will end up autounboxing the argument into
an 'int', which is what we wanted. And if foo(...) is called
with something that isn't compatible with Integer (e.g., a subclass),
then :multi won't select this sub at all.
But as I said, I'm no expert -- this is just my best stab
at how things ought to work, at least in the short term
until a more sophisticated Parrot object model is in place.
And as I also indicated, I don't have nearly as strong feelings
about this as I do about the fact that we need a way to
specify 'any type' (including native types) in the :multi
pragma.
Thanks,
Pm