Approach 1: scalar assignment as bindings ## $a = 4; $P0 = new 'Int' $P0 = 4 store_lex '$a', $P0 ## $b = $a; $P1 = find_lex '$a' store_lex '$b', $P1 ## $a++; $P2 = find_lex '$a' 'postfix:++'($P2) ## FAIL, also modifies $b Note that we're essentially stuck here, because any modification we perform to $a will also happen to $b, and there's no way for the 'postfix:++' sub to re-bind the $a lexical. -------- Approach 2: PMCs as scalar containers (via copy semantics), no Scalar type ## item assignment ## $a = [1,2,3]; $P0 = 'circumfix:[ ]'(1, 2, 3) $P1 = find_lex '$a' unless null $P1 goto vivify_1 $P1 = get_hll_global 'Object' $P1 = clone $P1 store_lex '$a', $P1 vivify_1: $P0 = $P0.'!VALUE'() copy $P1, $P0 The !VALUE method is responsible for getting the appropriate value of $P0 to be stored in $P1 here via the 'copy' opcode. The notion of "value" is a little special here -- for PMCs that are Objects, Arrays, or Hashes, the correct value is a form of object reference (call it ObjectRef). For value types like Int, Str, and Num, the value will be the PMC itself. For List, the PMC is coerced to an Array and then an ObjectRef is taken of that. ObjectRef PMCs return self -- i.e., they act like an immutable value type. Protoobjects and Iterators return an ObjectRef PMC. Type constraints are placed as properties on the PMC itself via 'setprop'. Note that the 'copy' opcode above doesn't modify or copy PMC properties on either PMC, so properties effectively remain with their PMC "container". To handle type constraints for parameter lexicals in sub and method definitions, this means we have to either (1) locally add constraints to the parameter PMC at the beginning of the sub that are then removed upon exit, or (2) use a wrapper PMC (something like the existing Scalar) for the lexical that can impose local constraints in addition to any constraints already existing on the parameter PMC. That basically handles item assignment for the various situations I can come up with. Now for list assignment: PMCs representing array and hash variables have an implementation type property that points to the protoobject of the correct implementation type. We may end up also using this property for scalar variables and PMCs that are elements of aggregates -- this would make it easy to distinguish "container" PMCs from non-containers. OTOH, it would be nice to not have property entries (more GC-able stuff) to every PMC in an aggregate. In Perl 6, list assignment occurs whenever the lhs is not a simple scalar (S03:2270). This includes the obvious @a = @b, but also the not-so-obvious @a[1] = 4, which looks like an item assignment but really isn't. When performing a list assignment, we first (eagerly) generate a list of containers from the expressions on the lhs of the assignment (S03:2252), then we iterate that list of containers and allow each to take values from the front of the rhs list. An array container -- i.e., a PMC that is marked with an Array or similar implementation type -- will "grab" all of the remaining elements of the rhs list, copying any values it finds and taking references to any lazy iterators that exist. Here's a possible pseudocode starting point for list assignment of an array slice: ## @a[3,5] = 100, 200; base = find_lex '@a' indexes = 'list'(3,5) lhs = base.'postcircumfix:[]'(indexes, 'lvalue'=>1) rhs = 'list'(100, 200) it = iter lhs it_loop: unless it goto it_done lvalue = shift it if lvalue is Array container goto copy_array $P0 = shift rhs $P0 = $P0.'!VALUE'() copy lvalue, $P0 goto it_loop copy_array: lvalue.'!ASSIGN'(rhs) goto it_loop it_done: unless rhs goto list_assign_done $P0 = pop rhs $I0 = isa $P0, 'Whatever' if $I0 goto list_assign_done 'warn'('Possible information loss') list_assign_done: ## result is lhs In the above, we use postcircumfix:[ ] as a method call instead of overloading get_pmc_keyed because we need a way to signal the array that the requested elements are being used in lvalue context and should be vivified (with suitable properties) if they don't already exist. Use of a true method here may also help avoid the problem we have with conflation of get_keyed and get_keyed_int methods. Other forms of list assignment are just compositions of the above -- i.e., ($a, @b[$a], %foo ) = 1, 2, 3, 4; simply builds an iterable list of container PMCs on the lhs and then iterates through them to assign values on the rhs. Summary: still need reference capability a la Mutable no explicit Scalar type or object type constraints are just properties on PMCs use properties to identify containers/implementation types only create extra "reference" objects for those containers that need them easily promote Parrot PMCs from other HLLs into Perl 6 equivalents on assignment