3 ms·
IMO destructive move is rather tangled up with another language feature: the ability to usefully have a variable of type T where all values must be actual value
by amluto 11mo ago
IMO destructive move is rather tangled up with another language feature: the ability to usefully have a variable of type T where all values must be actual values that meet the constraints of a T.
Suppose T is a file handle or an owning pointer (like unique_ptr), and you want to say:
T my_thing = [whatever]
and you want a guarantee that T has no null value and therefore my_thing is valid so long as it’s in scope.
In C++, if you are allowed to say:
consume(std::move(my_thing));
then my_thing is in scope but invalid. But at least C++ could plausibly introduce a new style of object that is neither copyable nor non-destructively-movable but is destructively movable.
Interestingly, Go is kind of all in on the opposite approach. Every instance of:
my_thing, err := [whatever]
creates an in-scope variable that might be invalid, and I can’t really imagine Go moving in a direction where either this pattern is considered deprecated or where it might be statically invalid to use my_thing.
I actually can imagine Python moving in a direction where, if you don’t at least try to prove to a type checker that you checked err first, you are not allowed to access my_thing. After all, you can already do:
my_thing: T | None = [whatever]
and it’s not too much of a stretch to imagine similar technology that can infer that, if err is None, then T is not None. Combining this in a rigorous way with Python’s idea that everything is mutable if you try hard enough might be challenging, but I think that rigor is treated as optional in Python’s type checking.