Darren Duncan darren-at-darrenduncan.net |Perl 6| wrote:
So, how does one get an object to pretend to be a value type for
purposes of assignment? Currently if I do the following


    class Dog { ... }
    my $a = Dog.new;
    my $b = $a;

then $a and $b both refer to the same Dog object.  How would I
define Dog such that it acts like a value type -- i.e., so that
$b would be a copy of $a and future changes to the object in $a don't affect $b.

I have been under the impression that value types are supposed to define immutable objects, or at least objects that pretend to be immutable; any operators on them would produce new objects rather than mutating existing ones. Therefore assignment can actually work the same way for all types, whether value types or not, by making the LHS container just hold an additional reference to what the RHS container holds. Since the value types are effectively immutable, there is no harm to them not being copied by default, and in fact this would be a feature, making it simpler to avoid unnecessary work.

If you are wanting to actually mutate a Dog in a user-visible way rather than deriving another Dog, then I don't think that calling Dog a value type is appropriate.


I agree.  A "value type" is "immutable", where the identity is keyed to
the value.  Making a "value type" that can mutate can cause confusion.

I'm now thinking that the normal = you write should always give
reference assignment semantics.  In the case of "value types", assuming
they are indeed immutable, it does not matter whether they have value or
reference assignment semantics, since the same value will give the same
identity, regardless of memory (or in-register) representation.

Furthermore, just because you CAN write an infix:<=> for some types that
give value assignment semantics, you SHOULDN'T do that, any more than
you should write an infix:<=> to do addition.  We want to avoid the Java
et.al. mess, and the ideas behind value types in Perl 6, and the
conceptual separation already present in comparison operators, gives the
natural solution:

You don't have "value types" a'la Java that behave differently with
respect to assignment.  Just like you can TEST for identity or value
equality by your choice of === or 'eqv', you can specify reference
assignment or value assignment (if available) by your choice of
operator.  To match the testing operators and existing meaning for '=',
I suggest that '=' ALWAYS be reference assignment and not be overloaded
to do something else, and the word 'assign' (to go with words being used
for value tests: 'eqv', 'before', 'after') be a method that mutates the
object to become 'eqv' the argument.  And, if you want to get fancy,
define ← as an infix operator for that meaning.

--John


Reply via email to