Having read this thread, I think that the real problem is not just that there are multiple assignment semantics -- it's that the names "set" and "assign" are not really meaningful -- that is, they *look* to english speakers as if they are synonyms... their names alone aren't enough info to know what precisely they're doing.
Furthermore, the current division of assignments to those three types is not what *I* would consider intui^H^H^H^H^H the most logical and sensible of arrangements. IMHO, we should rename the ops, dividing them up more clearly by behavior. I would suggest the opnames/categories "mutate," "alias," and "create." The mutate ops would all re-use the string or pmc headers, changing the contents of the first argument to match the contents of the second argument. The (two) alias ops would simply copy pointers. The create ops would create new strings or new pmcs. The ops which target ints and nums would be lumped with the mutate ops, since they neither create aliases, nor allocate new pmcs or new strings. Yes, I realize that changing the names of so many ops will require changing lots of code, and may temporarily introduce breakage, but I belive that it would be good in the long term. It would make the different assignment ops *much* easier to remember and understand, and make it easier for someone looking at parrot code understand which semantics a particular assignment operation is using. (Not changing the names would have the same bad effects as breaking a chain letter >:->) The changes in ops that I am proposing would be as follows: Alias would be the existing "set(out STR, invar STR)" and "set(out PMC, in PMC)." Mutate would be all the existing "assign" opcodes, plus most of the other "set" opcodes (except the ones which have "out STR" as their first argument), plus the following new ops: inline op mutate(in str, in int) { string_set(INTERP, $1, string_from_int(INTERP, $2)); } inline op mutate(in str, in num) { string_set(INTERP, $1, string_from_num(INTERP, $2)); } inline op mutate(in str, in pmc) { string_set(INTERP, $1, VTABLE_get_string(INTERP, $2)); } And lastly, Create would be the remaining "set" ops (which target strings, creating new strings), and the two "clone" ops, plus the following new ops: inline op create(out pmc, in int) { $1 = pmc_new(INTERP, enum_class_PerlInt); VTABLE_set_integer_native(INTERP, $1, $2); } inline op create(out pmc, in num) { $1 = pmc_new(INTERP, enum_class_PerlNumber); VTABLE_set_number_native(INTERP, $1, $2); } inline op create(out pmc, in str) { $1 = pmc_new(INTERP, enum_class_PerlString); VTABLE_set_string_native(INTERP, $1, $2); } (I realize that each of these would be the same as new $Px, .SomeClass, followed by mutate $Px, $foo... however, the combined ops here would be easier to write and read (one line instead of two), and in non-jit environments, faster to run, as well.) I believe that the most in^H^H logical shorthand spellings of these opcodes would be ":=", "=", and "<==", for alias, mutate, and create, respectively. -- $a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca );{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "[EMAIL PROTECTED] ]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}