On Thu, 07 Dec 2000, Dan Sugalski <[EMAIL PROTECTED]> mused:

> >My original suggestion was that scalar types provide a method that says
> >how 'big' it is (so complex > bigreal > real > int etc),
> >and pp_add(), pp_sub() etc use these values to call the method associated
> >with the biggest operand, swapping args if necessary (and passing a flag
> >indicating that arg swapping has taken place).
> 
> Right, but that only works when the two scalar types are in the same line. 
> If, for example:
> 
>     my Complex $s1 = 4 + 4i;
>     my Image $s2 : filename(foo.gif);
> 
>     $s3 = $s1 + $s2;
> 
> how would you handle the addition if perl doesn't know about complex types? 
> You've got two entirely different scalars that really have no basis for 
> comparison to judge which is really 'bigger' than the other.

Well, in this particular case I would expect $s1 + $s2 to cause a run-time
error, since an image scalar type has no natural numeric value. If the implementer
of the image type (probably unwisely) chose to give a numeric meaning to
images (eg overall brightness of the image), then I would expect $s1 + $s2
to return a complex value equal to $s1 + bightness($s2). In the other hand
I would expect that $s2 * 1.1 would return an image with brightness 10% greater
than that of $s1.

My scheme doesnt cover all eventualites, but I think it covers more cases before
it's necessary to punt. Also, it reduces the number of functions that need to
be implemented per scalar type to O(N) rather than O(N^2): ie rather than
add[INT](), add[NUM](),....,
sub[INT](), sub[NUM](), ...,
div....
....
there is just
get[INT], get[NUM], get.... (or get_int, get_num, ......)
plus a bit of code in pp_add(), pp_sub() etc which 'does the right thing'.

If we assume that ints and nums are perl builtins, and that some people
have implemented the following external types: byte (eg as implemented
as a specialised array type), bigreal, complex, bigcomplex, bigrat,
quaternian; then the following table shows how well my system copes:

num - int               gives accurate num
int - num               gives accurate num
int - byte              gives accurate int
byte - int              gives accurate int
byte - bigreal          gives accurate bigreal
num - complex           gives accurate complex
complex - complex       gives accurate complex
bigreal - complex       gives complex with potential loss of precison from the bigreal
bigreal - bigcomplex    gives bigcomplex probably with no loss of precison
complex - bigcomplex    gives bigcomplex, but (depending on the implementation of
                                complex), probably evaluates as
                                        modulus(complex) - bigcomplex or
                                        real(complex) - bigcomplex
complex - quaternian    gives quaternian, with similar coercion to num of LHS
complex - bigrat        gives bigrat; ditto coercion to num of LHS
bigcomplex - bigrat     may give bigcomplex or bigrat depending on precise
                                defintion of 'bigness'. Ditto about coercion of 1 arg
                                to num (or bignum).
quaternian - quaternian gives accurate quaternian

I think in practice people would be reasonably happy where complex types
(in the English rather than mathematical sense) operate fine with others of the
same type and interoperate with all other types with the proviso that only
a (possibly big) numeric value can be extracted from them.

With the sv1->sub[typeof(sv2)](sv2) scheme, even something as simple as
byte - bigreal is problematic, as this would cause byte->sub[GENERIC] to be called,
which has very little chance of 'doing the right thing'.


Reply via email to