Updated NEP 2 Catching up with C and Rust: Ownership, destructors, unique pointers (markdown)
This commit is contained in:
parent
86e84a8e20
commit
c8d00f319c
|
@ -39,7 +39,7 @@ echo "end of program"
|
|||
|
||||
The obvious problem is, that the discarded value is not deinitialized at all. This should not be possible so easily. The less obvious problem is, that there are two initializations for v. One is with the values (1,2) and the other one is with the values (5,6), but there is only one deinitialization.
|
||||
|
||||
My suggestion would be to trigger deinitialization of the left operand of the assignment operator, before assignment takes place. Meaning that `v = MyType(a:5, b:6)` compiles to something equivalent to this pseudocode: `destroy(v); init(v, MyType(...))`. This would also solve the problem, that current implementors of the `=` operator have to implement some logic that needs to determine weather the left operand is already initialized or not, because the compiler would ensure that the left operand is not initialized.
|
||||
My suggestion would be to trigger deinitialization of the left operand of the assignment operator, before assignment takes place. Meaning that `v = MyType(a:5, b:6)` compiles to something equivalent to this pseudocode: `destroy(v); init(v, MyType(...))`. This would also solve the problem, that current implementors of the `=` operator have to implement some logic that needs to determine whether the left operand is already initialized or not, because the compiler would ensure that the left operand is not initialized.
|
||||
|
||||
```Nim
|
||||
type
|
||||
|
@ -52,7 +52,7 @@ proc `=`(dst: var MyType; src: MyType) =
|
|||
dst.resources = src
|
||||
```
|
||||
|
||||
I just heard, that self assignment on types that have deinitialization would not work anymore. This can be handled by implementing some logic that checks weather it is self assignment, or by simply declaring self assignment illegal. One version that works with self assignment is the following (again in pseudocode), but it still needs to explain what move semantics are.
|
||||
I just heard, that self assignment on types that have deinitialization would not work anymore. This can be handled by implementing some logic that checks whether it is self assignment, or by simply declaring self assignment illegal. One version that works with self assignment is the following (again in pseudocode), but it still needs to explain what move semantics are.
|
||||
|
||||
```Nim
|
||||
proc `=`(dst: var MyType; src: MyType) =
|
||||
|
@ -63,13 +63,13 @@ proc `=`(dst: var MyType; src: MyType) =
|
|||
|
||||
# move semantics
|
||||
|
||||
Move semantics mere introduced into c++ as a new way to construct objects. A move to `a` from `b` means that `a` get's contructed from `b`, but `a` may exploit `b` to do so. To support this feature C++ added two entirely new kinds of references to the language, to move reference, and the forward reference. One reference is marked as `&&T` and the other one `&&T`, but here T is a templated type. And then there is move initialization and move assignment.
|
||||
Move semantics mere introduced into c++ as a new way to construct objects. A move to `a` from `b` means that `a` gets constructed from `b`, but `a` may exploit `b` to do so. To support this feature C++ added two entirely new kinds of references to the language, to move reference, and the forward reference. One reference is marked as `&&T` and the other one `&&T`, but here T is a templated type. And then there is move initialization and move assignment.
|
||||
|
||||
Nim also needs some sort of move semantics, when it doesn't want to have everything garbage collected, but I do think that the c++ way of doing this is just too complicated, and for most cases unnecessary. The most important context for move optimization is the return value, because nobody wants create a complex copy operation that keeps the source object alive, just to delete this objects instantly after that. And to have move optimizations for return values, the language does not need to have additional move operations.
|
||||
|
||||
# My Suggestion to the problem
|
||||
|
||||
My proposition is, to use swap, for things that are solved with move in other languages (C++). The idea to do is, comes from the fact, that Nim does not have the concept of a contructor, and therefore is not able to introduce a new kind of constructor. Neither does it have a state to describe a variable as _is moved from_ (ivalid to read).
|
||||
My proposition is, to use swap, for things that are solved with move in other languages (C++). The idea to do is, comes from the fact, that Nim does not have the concept of a constructor, and therefore is not able to introduce a new kind of constructor. Neither does it have a state to describe a variable as _is moved from_ (ivalid to read).
|
||||
|
||||
Swap has the advantage, that it never introduces new entities, it just swaps two objects of the same type. Therefore the operation contains two move operations, but without destroying any other variable
|
||||
|
||||
|
|
Loading…
Reference in New Issue