Oh, yeah… this is a question about an “ownership”.
What parts of the code may/can modify some underlying data?..
What parts of the code should allocate on the heap and which one should/must free()?..
aside note: IMHO, rust-lang approach to these really (in general) hard issues to handle
is a bit “schizophrenic”:
at hardware level we have
physical memory cells in some data storage device
a state of that cells - it is a “value” of those memory cells
Note, that a physical memory cell can not exits apart of it’s content (“a value”)
at a programming language level we have
a variable name
and a “value”, assotiated with that exact name
Note again - one “variable” - one “value”, they can not exist apart, as some independent “entities”.
What rust-lang (the sooper-pooper, yeah) is doing with all that weird “ownership” conception?
It tries to separate a physical storage and it’s content (“who owns a value?”)
It is schizophrenic way of thinking, isn’t it?
My terms/words are probably was not the best in the post,
but let it be as is…
@dee0xeed : In Rust, types that are not trivially copyable (like integers, floats, bool, etc.) are governed by the strict ownership model that only one variable may own a value in memory and if you assign this value to another variable, it moves to the other variable, leaving the original variable uninitialized. This latter part is what they refer to as move semantics. In this way, the compiler can ensure at compile time that no two parts of a program can simultaneously access and mutate a value in memory, given that it’s only ever accessible through a single variable.
This works very well in guaranteeing memory safety and even eliminating data races as a nice side-effect, but it does impose a very rigid structure for a program that needs to share its values and even mutate them in complex, interconnected ways (i.e. a doubly linked list is far from trivial to implement in Rust.) So in the end, if your program can work well with the strict ownership model and move semantics, Rust will help you write memory safe, performant code. In all other cases, just use Zig.
Yeah, I know. As soon you have two or more mutually referring structs,
an explicit lifetime “markers” hell begins… when I tried to implement
something like this in Rust,
after some struggling with Rust compiler I just gave up and switched
to usual pointers. But then all my code became smudged with unsafe blocks.
I think I like the idea of managing almost everything with arenas like described in this talk (although my use of arenas in zig has been pretty minimal so far):
I guess with zigs Allocator interface there isn’t really a need to require a arena parameter everywhere, because we already have allocator everywhere, but maybe we can still use some ideas of the talk (It has been a while since I saw it and I didn’t take notes)
Regarding rust style ownership, the OCaml-ized version seems better to me, because it doesn’t force a straight jacket on you and still seems to give you 95% what was wanted: