add MMD bug in Integer PMC

Andrew Whitworth wknight8111 at gmail.com
Mon Nov 2 15:03:22 UTC 2009


On Fri, Oct 30, 2009 at 5:01 PM, Austin Hastings
<Austin_Hastings at yahoo.com> wrote:
> My further understanding is that the default case applies to pmcs that are
> neither Integer, Float, String, Complex, Bignum.

There are a handful of special cases written in for Float, String,
Complex, BigNum and Integer. "Default" is code for "Everything else".

> I can understand the default being to use float, so as to avoid losing
> precision. That is, if whatever PMC is capable of returning 3.14159, and the
> default is to treat it as an integer, it would always get truncated.

I'm not sure it's an issue of precision. When you're calling a VTABLE
for an Integer PMC, I feel pretty strongly that we should be doing
integer operations. If we want floating-point behavior, we should be
calling the VTABLE on Float instead (likewise, we don't call VTABLEs
in Float expecting to have operations done as BigNums, which we might
expect if precision were everything).

This does make order-of-operands matter more at the PIR level, but I
don't see any reason why that's a bad thing. PIR is an assembly-level
language, and the extra hassle of worrying about operand order gives
us the added ability to precisely determine behavior when mixing
operand types. HLLs do want a more consistent behavior, and they can
subclass types to provide that. Trying to make Parrot account for
every possible type combination, and every possible ordering of those
operand types, is a big mistake. Even in simple cases we're losing the
ability for Parrot to anticipate what functionality users are going to
need, and our missed guesses cause problems and remove consistency
that people are trying to rely on.

> Anyway, my original problem came about when I defined a class with a
> get_string vtable, and a get_integer vtable. When I printed the object, I
> got the string version -- not unreasonable. So I printed C<  0  + $object >,
> figuring that would force an integer conversion. But it doesn't, apparently
> because it wants a float instead (so it goes through get_string, naturally.
> :-(

A perfect example of my point: We have a custom integer type and
Parrot is trying to automagically DTRT without having any prior
knowledge or understanding of this type. The more we try to make
Parrot guess what the user wants, the more it's going to end up doing
the wrong thing, and the less possible it's going to be to manually
correct it.

> 2. Non-numeric objects appear to use get_string as a route to conversion,
> instead of get_integer.

Another great example. If people wanted this odd conversion path, they
would define a custom PMC that implemented it. When I try to add an
Integer to a custom "MyInt" type, we shouldn't be calling
get_number/set_number, and we definitely shouldn't be defaulting to
calls to get_string/set_string. Maybe we need a way to activate these
weird fallbacks, or maybe we need to define new types that use them.

> 3a. In particular, this seems like a place where a role would be useful. "I
> can be a number" or "I can be an integer" might be good things to have in
> the MMD chain for operators. Of course, attaching "I can be a number" and "I
> can be a string" to the same class brings us back here, but surely there is
> some mechanism in C3, or whatever operator-mmd uses, for specifying
> precedence.

I agree with this very strongly. If we're talking about a custom PMCs
type, Parrot shouldn't be guessing at it's interface, it should be
asking for a precise answer. When we're writing a custom PMC type, if
we want it to act like an integer we should be able to specify that.
If we want it to act like a float, we can specify that too.

> 4. As shown in my second nopaste (http://nopaste.snit.ch/18506), there
> appears to be a fourth object involved in a $P0 = $P1 + $P2 operation. (I am
> printing the get_addr of the PMCs, and there are 4 different addresses.) So
> C< add > appears to create a temporary PMC.
>
> 5. The add would not succeed until I provided a C< set_number_native >
> vtable entry as well. Which suggests that you can't have a read-only object.
> :-(
>
> And #4 and #5 seem like bugs. Why would "add" need a temporary? Why write to
> it?

Looking into this, I'm *very* unhappy about how the add VTABLE works
at all levels. I don't like the way it handles arguments, I don't like
how it does promotions, or how it uses space, and how it respects the
needs of the various operands. However, this is another issue for
another discussion (or series of discussions).

It does indeed create a 4th pmc as a result, ignoring the "dest"
argument that's passed in. I don't think it should do that, and would
consider this another bug.

--Andrew Whitworth


More information about the parrot-dev mailing list