The issue for me is that posts about `--gc:arc` still reference concepts like
`sink` and `lent` parameters. These are described in [the post about
destructors](https://github.com/nim-lang/Nim/blob/devel/doc/destructors.rst#nim-destructors-and-move-semantics),
but, well, that document is not very understandable. Also, it is not clear
whether the two mechanisms are going to coexist or `--gc:arc` will be a
substitute for `--newruntime` (which then won't by ever enabled).
All of this is complicated by the fact that - as far as I understand -
`--gc:arc` will not support exceptions as they are today, thus introducing
other changes.
In short: I am lost. I don't know which mechanism will be used in place of a
GC. I don't know if that requires me, as a library author, to introduce `sink`
or `lent` parameters, which I still do not understand. (related to this, I have
stopped writing Nim libraries, because I am unsure about its directions). I
don't even know if existing libraries are supposed to be working with
`--gc:arc` or `--newruntime`, so I don't submit issues about them.
I think we really need an ELI5 of these mechanisms, and this thread, until now,
does not explain much.
Let me give some examples of what I do not understand in the destructors
document. For instance, let's see sink parameters.
> To move a variable into a collection usually sink parameters are involved.
Ok-ish. Let us see what this entails
> A location that is passed to a sink parameter should not be used afterwards.
> This is ensured by a static analysis over a control flow graph.
Not sure what a location is, but if the compiler ensures it, seems fine.
> If it cannot be proven to be the last usage of the location, a copy is done
> instead and this copy is then passed to the sink parameter.
So the compiler does not ensure this, after all. Looks like I can introduce
copies by accidentally using a location (variable?) after putting it into a
collection? Not sure if I am reading correctly
> A sink parameter may be consumed once in the proc's body but doesn't have to
> be consumed at all. The reason for this is that signatures like proc put(t:
> var Table; k: sink Key, v: sink Value) should be possible without any further
> overloads and put might not take owership of k if k already exists in the
> table.
What is ownership? Is it defined elsewhere? It is not defined earlier in the
document. As far as I know, Nim does not currently (v1) have a concept of
ownership, so if it is relevant, it should be explained. I sort of understand
the concept intuitively, and know a little Rust, but if Nim deviates from Rust
(I assume it does) it should explain what it means for a a procedure to take
ownership of a parameter.
> The employed static analysis is limited and only concerned with local
> variables
So what happens for things that have a longer lifetime?
> however object and tuple fields are treated as separate entities
This sentence is supposed to be explained by the following code sample, but I
do not understand what the code sample is meant to convey
proc consume(x: sink Obj) = discard "no implementation"
proc main =
let tup = (Obj(), Obj())
consume tup[0]
# ok, only tup[0] was consumed, tup[1] is still alive:
echo tup[1]
Run
> Sometimes it is required to explicitly move a value into its final position:
Uh... sometimes when? Why should I explicitly move a value into its final
position? The following code sample does not explain at all why here one should
use explicitly `system.move`
proc main =
var dest, src: array[10, string]
# ...
for i in 0..high(dest): dest[i] = move(src[i])
Run
And so on, and so on. Sorry for the rant, but I think an ELI5 is really needed,
even if the whole concept is still in flux. At least the final vision should be
clear.