4 ms·
Seems Nim will do some static analysis where if it can infer a reference is locally scoped in some way, it will deterministically inject a call to the destructo
by didibus 6y ago
Seems Nim will do some static analysis where if it can infer a reference is locally scoped in some way, it will deterministically inject a call to the destructor at the end of the scope. If not, it will do reference counting which will also have (if using orc) an extra cycle detection pass so that the references count references can also handle cycles. Finally, Nim will also do some static analysis, and if it can infer that even though a reference is passed to something else, if it can tell that it isn't used afterwards from the previous place, instead of copying the data, it will share it, bit since it's not used by the previous owner you can think of it as moving it rather then sharing it. If Nim can't be sure this is the case or sees it isn't, then data will be copied.
That's what I understood at least. So ya, it does look like some kind of hybrid between statically inferable ownership semantics, reference counting, ARC and GC.
- k__ 6y agoSo if I understand that correctly: Nim will try to do a light version of Rust's borrow checking and then gradually move from static to dynamic solutions for memory management. I read that Nim's GC is optional, does this mean it can be deactivated and when the static memory management fails, I can do it manually for the edge cases that would otherwise done by the GC? Hope this makes sense, haha.
- beagle3 6y ago> does this mean it can be deactivated? Sort of. You either deactivate it completely with --gc:none ; or, you do it on per-variable basis by using a "ptr" (pointer) type, which is outside of the GC's realm. Any variable declared "ref" (reference) is within the realm of Nim's GC, and will be tracked by the gc you chose (none, boehm, mark&sweep, arc, orc, ...). Additionally, you can define type bound operators to help the GC do its job, but IIRC (and I'm not sure I understand correctly), that doesn't turn off arc/orc - rather, it tells them how to apply some things.
- didibus 6y ago> So if I understand that correctly: Nim will try to do a light version of Rust's borrow checking and then gradually move from static to dynamic solutions for memory management I think that's an okay way to put it. Though it might be best to think of it the other way around. It'll default to GC and copying data around (pass by value) and will try to optimize things if it can to more deterministic memory management and pass by reference. > I read that Nim's GC is optional, does this mean it can be deactivated and when the static memory management fails, I can do it manually for the edge cases that would otherwise done by the GC? It isn't optional like that. It's more that by default all data is passed by value and allocated on the stack. And if you want to create things on the heap, you need to be explicit about it, at which point you can choose if you want the pointer to be managed by Nim's GC or manually. That's done by having two type of pointers, ref will be under GC, and ptr won't.
- nikki93 6y agoRefcounted refs have copy and destruct semantics, and then what you're talking about is basically move semantics over those refs. Refcount increments be elided if the ref is "moved." The increment is only needed on copy. Additionally, a moved-from value doesn't need to be destructed (in the case of a refcounted ref -- decrementing the count and deallocating the pointed-at memory if count goes to zero). A talk about similar concepts in the "Lobster" language that explains it pretty well I think: https://youtu.be/WUkYIdv9B8c https://youtu.be/WUkYIdv9B8c
- didibus 6y ago> Refcounted refs have copy and destruct semantics You're talking accross threads I believe. But accros scopes they are passed by reference I believe.
- nikki93 6y agoI meant the copy semantics of the ref itself. The copy operation on a refcounted ref increments the refcount at the object it's referring to. The references themselves are values. Another way of looking at this--in C++ the copy constructor of std::shared_ptr. Move semantics as generally applied across values, when applied to such references, is what gives rise to the refcount elison stuff (the move constructor of std::shared_ptr does no increment).