Regarding the tentative list of vtable functions:
I'm rather worried about binary operators, eg 'is_equal', 'add' etc.
The danger with these is that they may impose a single implementation
of scalars upon us.

As an example, suppose I wrote an alternative scalar implementation that
was optimised for many small string appends followed by a single get
of the wholpe string at the end. (I might internally do this with a linked
list of blocks, say; then allocate a single large block at the end to
return the whole string.)

If sv1 is a standard SV and sv2 is an append-optimised one, then

(sv1->vtable[IS_EQUAL])(sv1,sv2) would crash and burn, because
sv1's 'is_equal' function doent know that sv2 has a different internal
representation.

Here is what I propose:

The binary vtable functions should be called only on two sv's of the
same type (ie same vtable pointer), and may possibly be optional.
Perl then provides a standalone function that can operate on any 2 SV's
by accessing only their external methods, but which as an optimisation,
attempts to call the implementation-specific function if it exists.
For example (messy typecasting etc skipped for clarity):

int publicAPI_is_equal(SV *sv1, SV *sv2)
{
        void *fn;
        STRING *s1, *s2;
        if (sv1->vtable == sv2->vtable && fn = sv1->vtable[IS_EQUAL]) {
                // do it the efficient way
                return (fn)(sv1,sv2);
        } else {
                // do it the inefficent way without reference to internals
                s1 = (sv1->vtable[GET_STRING])(sv1);
                s2 = (sv2->vtable[GET_STRING])(sv2);
                return (strcmp(s1,s2) == 0); // or whatever
        }
}

In fact, if you progress along this path a bit further, we start heading
into the territory of operator overloading at the C level, which might be
considered a very desirable feature.

However, a lot more thought would have to be put in to make proper
overloading possible. For example, consider a new scalar type implementing
a complex number. If the add method returned a new SV rather than just
a direct value, then adding two complex numbers together would give the
expected fresult. However, adding a complex to a standard scalar would
cause the numeric value of the complex scalar to be extracted (probably
the modulus or real component depending on implemenetation), which
would be added to the standard scalar and a standard result returned,
which isnt necessarily what you want.

One way to advance this is for the evaluation context to know
what type of SV is being assigned to (ie it's given the vtable pointer).

So

$a = $b + $c;   # the add op is given a copy of $a's vtable pointer, which
                # is probably the standard numberic or string one.

my complex $a; # or whatever
$a = $b + $c;   # the vtable pointer passed to a is the complex one

[ Similar things would happen for list assignment - we would know
whether we are assinging to a standard array or a maths vector type for
example ]

We might then change the semantics of publicAPI_is_equal to be

int publicAPI_is_equal(SV *sv1, SV *sv2, VTABLE *context)
{
        void *fn;
        STRING *s1, *s2;
        
        if (sv1->vtable == context)
                return (sv1->vtable[IS_EQUAL]))$sv1,$sv2)
        else if (sv2->vtable == context)
                return (sv2->vtable[IS_EQUAL]))$sv2,$sv1)
        else {
                ????
        }
}


I'm starting to ramble here - basically I'm a bit out of my depth,
but I just have this gut feeling that with some careful thought, the
vtable API could be done in such a way that it makes operator overloading
at the C level very easy. And if we get it wrong, it could make it very
hard.


* Dave Mitchell, Operations Manager,
* Fretwell-Downing Facilities Ltd, UK.  [EMAIL PROTECTED]
* Tel: +44 114 281 6113.                The usual disclaimers....
*
* Standards (n). Battle insignia or tribal totems

Reply via email to