The idea is Perl methods and subs will always return references or scalars by default, just as method/sub arguments always take references or scalars by default; so we have symmetry between the in/out. And they would do this the same way regardless of the caller scalar/list context.
If the writer of a method/sub wants to return a copy of a non-trivial structure like a hash or array, they explicitly copy it and return the copy. This is elegant because when they are explicitly copying, they can also fully control to what depth in a tree-like structure the items have either their values or their references copied.
For example, with the same $:foo, @:bar, %:baz attributes ...
These would return references to the structure root, in all contexts:
return \$self.:foo; return $self.:bar; return $self.:baz; return \$:foo; return @:bar; return %:baz;
These would return a new structure with level-1 copies of the elements, but if any elements are references then the copies point to the same things in all contexts:
return $self.:foo; return [$self.:bar]; return {$self.:baz}; return $:foo; return [@:bar]; return {%:baz};
The exact syntax could vary. The above would scale to, say, explicit 2-dimensional copy similarly to Perl 5, like this:
return [$self.:bar.map:{ [$_] }]; return [@:bar.map:{ [$_] }];
Now, I am operating under the assumption here that in Perl 6, the line between having a reference to something or having that thing is blurred, and so there is no need to do explicit dereferencing; eg, no @{} or %{}.
All that the caller context would then determine is whether what the method/sub returned is flattened or not; the caller context would not determine whether the method/sub returns a copy or a reference.
Question: Is there a trait for a sub/method that specifies whether it forces a scalar or list context?
Any opinions on this?
-- Darren Duncan