----- 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