Nicholas Clark <[EMAIL PROTECTED]> wrote:
> It looks to me like add needs to be polymorphic and work out the best
> compromise for the type of scalar to create based on the integer/num/
> complex/oddball types of its two operands.
> 
> [Oh. but I'm blinkered in this because I'm attempting to make pp_add in
> perl5 do this sort of thing, so I may be missing a better way of doing it]

This sounds supiciously like an earlier discussion:

http://www.mail-archive.com/perl6-internals@perl.org/msg01532.html

Where I proposed that each numeric SV class should have a precison()
class method that indicates how 'big' that numberic type is:

Let d be the dimension of the variable (eg complex and bigrat numbers
would be 2); Let t be:
              0 for integer
              1 for floating point
let b be the bits of storage used (eg 32 for an INT32, 64 for a double)
then define the precision by (d<<24 + t<<23 + b) or similar.
Classes which allow arbitrary dimension or precision should set d or t
to its maximum value.

Then when pp_add wants to call the add() method of one of it's args,
it chooses the biggest of the two.

I gave some sample psuedo-code for pp_subtract:

pp_subtract {
              SV *sv1 = POP;
              SV *sv2 = POP;
              SV *result;
              if (
                      // if they're the same type (common case),
                      // avoid the overhead of calling precision() twice
                         sv1->vtable == sv2->vtable
                      || sv1->precision() >= sv2->precison()
              )
                      result = sv1->subtract(sv1,sv2,0);
              else
                      result = sv2->subtract(sv2,sv1,1); // operands swapped
              PUSH(result);
      }


The implication was that arithmetic operations on mixed types get a result
equal to the type of it's 'biggest' operand.
So num + int gives num, bigrat + num gives bigrat, and so on.

A lot of issues were then discussed (but not resolved), such as:

* do values ever get demoted - eg an expression inolving bigints that evaluates
to 0: should this be returned as an int or a bigint?

* for the code '$c = $a + $b' - is the current SV type of $c thrown away
and replaced  with whatever type ($a + $b) evaluates to?

* If we allow the syntax

my bigreal $c = $a + $b

[ this is an extention of the "my dog $spot" syntax, since that currently
advises that $spot is likely to hold a reference to dog object; I don't
believe there are yet any semantics defined directly for different SV types.]
In this case, is $a + $b evaluated then promoted to a bigreal; or does
$c end up being whatever $a+$b is, and not necesarily a bigreal?
Or is the expression ($a+$b) now evaluated in the context of knowing that
a bigreal is expected???

* How are scalar constants handled?

eg does this work as expected?

use bigreal;
my $br = 1E99999999999999999999999999999999999999999999999999999999;

and can the parser be dynamically extended to allow

use complex;
my $twosqrtminusone = 2i;



Some of these issues affect the design of the SV vtable API; some have
wider semantic implications.

Dave M.

Reply via email to