What's wrong with the following implementation of move? [T] move(src:T) returned:T { memcpy(&returned, &src, TypeSize(T)); } It will fail in the following case: foo() { var a = Vector[Int](1, 2, 3, 4, 5); return move(a); } The returned vector will contain a dangling pointer within it, as the pointer will be freed when the local 'a' is destroyed. So, the source should be 'cleared' when a move is performed. Like this: [T] move(src:T) returned:T { memcpy(&returned, &src, TypeSize(T)); src <-- T(); } The default constructor is used to reset the source. What is wrong with this version of move? The problem is that certain types may not have a default constructor. For example, variant types don't have a default constructor. So, perhaps we can define a 'reset' operation. reset(x:T) { x <-- T(); } [V | Variant?(V)] overload reset(x:V) { reset(*x); } We can simply require that 'reset' be defined for _all_ types. Here is the updated version of 'move': [T] move(src:T) returned:T { memcpy(&returned, &src, TypeSize(T)); reset(src); } This works for all types. (except address-tracked types, which are considered later). Let's consider the Vector container. When it's internal buffer overflows it allocates a new bigger buffer and moves the elements from the older buffer to the newer buffer. Should the 'move' operation be used for that? In this case, it's not necessary to reset the source, as we can simply free the older buffer without calling the destructor on its elements. So we define a new operation called 'rawMove' which doesn't clear the source. [T] rawMove(src:T) returned:T { memcpy(&returned, &src, TypeSize(T)); } and 'move' can be implemented in terms of 'rawMove': [T] move(src:T) returned:T { returned <-- rawMove(src); reset(src); } Address tracked types can simply override 'rawMove' to update the tracked addresses.