> Are you sitting comfortably?

yes.

> 
> It's a pretty simple concept. We need to assign one PMC to another.
> We'll have to do it all the time:
> 
>     $a = $b;
> 
> $a and $b are both PMCs, and we need to set the value of one to the
> value of the other, so let's write it as
> 
>     set P1, P2
> 
> Excellent. Until, of course, we have to implement it. We'll implement
> it by calling some vtable method on P1, that much is obvious. But which
> one? Our implementation of the set_p_p op can't know whether or not P1
> wants a string, an integer, or a number. Or something entirely different.
> Indeed, P1 might not know what it wants unless it knows what P2 has to
> offer. 


An observation:

In Perl 5 at least, it is (roughly speaking) the src variable that gets
to stomp on the destination variable, rather than the destination variable
being allowed to modify itself. ie

$dst = $src in Perl 5 is implemented (very approximately speaking) as

mg_get(src);
IVX(dst) = IVX(src);            // old dst values blown away
NVX(dst) = NVX(src);
PVX(dst) = PVX(src);
mg_set(dst);

Now, sometimes we want the destination to have control over how it is
assigned to (eg if it's tied), but most of the time the destination doesn't
care, and is happy to be blown away and have its guts replaced with
whatever the src wants.

With this back-to-front philosophy,

$dst = $src  gets called as

dst->vtable->assign(dst,src);

but most simple dst types implemenent their assign method by just passing
control directly through to the src's clone method:

void dsttype_assign(PMC *dst, PMC* src) {
        src->vtable->clone(dst,src,);
}
void srctype_clone(PMC* dst, PMC* dst) {
        dst->cache.int = src->cache.int; // supposing src is an int type
}

ie, it's the src that actually gets the chance to stomp over the dst, after
the dst lets it.

[ all C syntax here is vague handwaving rather than precise syntax,
especially when it comes to passing key indices ] 

Consider also a lightweight integer array class.
Assigning from it becomes easy:

$dst = @src[5] becomes

dst->vtable->assign(dst,src,5);
void simpletype_assign(PMC *dst, PMC* src, KEYTHINGGY key) {
        src->vtable->clone(dst,src,key);
}
void lightweightarray_clone(PMC* dst, PMC* dst, KEYTHINGGY key) {
        dst->cache.int = src->cache.ptr[INT(key)];
}

and assigning to it is easy:

@dst[5] = $src becomes

dst->vtable->assign(dst,src,5);
void lightweightarray_assign(PMC *dst, PMC* src, KEYTHINGGY key) {
        // NB - we don't pass control to the src
        dst->cache.ptr[INT(key)] = dst->vtable->get_integer;
}



I dont know whether that helps. I haventeven  begun to address list
assignment, %foo = @bar, %foo{@bar} = %baz{%boz}, etc etc.
I ain't got a clue how that might work, of even whether it is the
responsibility of PMCs to handle this.

Just my 0.02 euros.


Reply via email to