----- Original Message -----
From: "Dan Sugalski" <[EMAIL PROTECTED]>
To: "T.O.G. of Spookware" <[EMAIL PROTECTED]>;
<[EMAIL PROTECTED]>
Sent: Monday, August 04, 2003 9:18 AM
Subject: Re: Set vs. Assign..?


> At 11:45 AM -0700 8/1/03, T.O.G. of Spookware wrote:
> >
> >Hi, all. I've been following Parrot development and
> >been playing with Parrot for a...bout a year and a
> >half, now. First time posting to the list, though, so
> >forgive me if this has already been covered or is
> >stupid in some way :-)
> >
> >Anyway, while playing around with IMCC, this kind of
> >bugged me:
> >
> >P3 = 32   # tells the PMC referenced by P3 to
> >             set its value to 32
> >P3 = P5   # copies reference in P5 to P3
> >
> >What I don't like about this is that it's not
> >immediately obvious from looking at the code whether
> >you're telling P3 to change its value or simply
> >replace the PMC reference stored in P3 with another.
>
> This is a reasonable thing to worry about, because we have three
> separate semantics, set, assign, and clone.
>
> For I and N registers, all three are identical, since integers and
> floats are value types at this level.
>
> For S and P registers, things get odd. set just copies the contents
> of one register to another. Since P and S registers are pointers, it
> means you have two registers that point to the same string or PMC
> structure.
>
> Assign takes the contents of the structure that the S or P source
> register points to and puts those contents into the structure the
> destination register points to. A new structure is not created, and
> if the destination is supposed to do something when a value is put
> into it, then the destination does that. (If, for example, the
> destination variable overloads assignment or is tied, depending on
> the language you come from)
>
> Cloning makes a copy of the source, complete with new structure, and
> puts a pointer to the new structure into the destination register,
> throwing away whatever pointer was in there to begin with.
>
> It's a bit funky, but you need all three semantics to make things
> work out right.

Ok. It *is* possible to implement all these different types of assignments
(reference copies, "real" copies).
However, what about this:

suppose there is some language Foo. This language has 2 different data
types: FooNumbers, which are always used by value, and FooObjects, which are
always used by reference. Both are PMC classes.
When a FooNumber is copied, then I'd like *not* to copy the reference, but
to copy the real value. This implies the usage of "assign"

---------------------------------------------------------------
P0 = new .FooNumber
P0 = 123
P1 = new .FooNumber
assign P1, P0
# now, when incrementing P1, P0 (the original) is not changed.
-------------------------------------------------------------------------

However, when a FooObject is copied, I'd like to copy this by reference.

-------------------------------------------------------------------
P0 = new .FooObject
P0["x"] = 999
P1 = new .FooObject
set P1, P0             #used PASM to be explicit on which op I used.
# now P1 should reference the same object.
---------------------------------------------------------------------


Ok. This works. However, it is annoying if run-time checks have to be done
on the type for deciding which
type of copy has to be applied. Like in this example:

----------------------------------------------------------------------------
------------------
#P0 references some variable, I don't know if it is a FooObject, or a
FooNumber
#P1, same as P0

typeof S0, P0
unless S0 == "FooObject", copyval #if P0 is a FooObject, do "set", otherwise
do "assign"
set P1, P0 # copy by reference
end

copyval:
assign P1, P0 # copy by value
end
----------------------------------------------------------------------------
-----------------
# If P0 is an object, I'd like P1 to get a copy of the reference to that
object. If P0 is a FooNumber, I'd like P1 to
# get a copy of that, so P1 can safely change its own copy.

This is not very nice code for a simple assignment.
However, it would be so much easier when the Foo compiler could just emit
some instruction and the destination PMC decides what to do: just copy the
reference, or do a real "assign"

On a more technical level:

clone uses the vtable of the source PMC (right?), and makes a complete copy
(as is implied by the name "clone")
assign uses the vtable of the destination PMC (so the *destination* decides
what to do).

I'd like an opcode that uses the vtable of the source PMC, like this:

let_src_pmc_decide_what_to_do    P1, P0 # P1 will get its own copy of P0 if
P0 is a FooNumber, otherwise just
                                                                    # a copy
of the contents of register P1.

"let_src_pmc_decide_what_to_do" is the name of this op.

(Some weeks ago, there was also a thread on this (if I remember correctly),
and the proposed opname was "copyval", I believe.)

So, would this be a good idea?

Klaas-Jan





Reply via email to