From f3c917fbe8a8b9ca6a3f222d26d8263edc5d9d2f Mon Sep 17 00:00:00 2001 From: treeform Date: Tue, 9 Nov 2021 18:24:36 -0800 Subject: [PATCH 1/2] Call {.cursor.} a pragma. Its hard to find .curser annotation while googling because all other things like it are called pragmas. See https://nim-lang.org/docs/manual.html#pragmas Also the . in front of the name makes it hard to find and search for. Can we just call it cursor pragma? --- doc/destructors.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/destructors.rst b/doc/destructors.rst index d6f240deec412..ba8c88fcbfa79 100644 --- a/doc/destructors.rst +++ b/doc/destructors.rst @@ -555,14 +555,14 @@ for expressions of type `lent T` or of type `var T`. echo t[0] # accessor does not copy the element! -The .cursor annotation -====================== +The cursor pragma +================= Under the `--gc:arc|orc`:option: modes Nim's `ref` type is implemented via the same runtime "hooks" and thus via reference counting. This means that cyclic structures cannot be freed immediately (`--gc:orc`:option: ships with a cycle collector). -With the `.cursor` annotation one can break up cycles declaratively: +With the `cursor` pragma one can break up cycles declaratively: .. code-block:: nim @@ -575,7 +575,7 @@ But please notice that this is not C++'s weak_ptr, it means the right field is n involved in the reference counting, it is a raw pointer without runtime checks. Automatic reference counting also has the disadvantage that it introduces overhead -when iterating over linked structures. The `.cursor` annotation can also be used +when iterating over linked structures. The `cursor` pragma can also be used to avoid this overhead: .. code-block:: nim @@ -586,10 +586,10 @@ to avoid this overhead: it = it.next -In fact, `.cursor` more generally prevents object construction/destruction pairs +In fact, `cursor` more generally prevents object construction/destruction pairs and so can also be useful in other contexts. The alternative solution would be to use raw pointers (`ptr`) instead which is more cumbersome and also more dangerous -for Nim's evolution: Later on, the compiler can try to prove `.cursor` annotations +for Nim's evolution: Later on, the compiler can try to prove `cursor` pragmas to be safe, but for `ptr` the compiler has to remain silent about possible problems. @@ -597,7 +597,7 @@ problems. Cursor inference / copy elision =============================== -The current implementation also performs `.cursor` inference. Cursor inference is +The current implementation also performs `cursor` inference. Cursor inference is a form of copy elision. To see how and when we can do that, think about this question: In `dest = src` when @@ -612,7 +612,7 @@ indirections: .. code-block:: nim proc main(tab: Table[string, string]) = - let v = tab["key"] # inferred as .cursor because 'tab' is not mutated. + let v = tab["key"] # inferred as `cursor` because 'tab' is not mutated. # no copy into 'v', no destruction of 'v'. use(v) useItAgain(v) From 78ba9fd360c4486f46d7aeaff061c479450606f7 Mon Sep 17 00:00:00 2001 From: treeform Date: Tue, 9 Nov 2021 18:26:06 -0800 Subject: [PATCH 2/2] Small fix for comment. --- doc/destructors.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/destructors.rst b/doc/destructors.rst index ba8c88fcbfa79..83a50230b915a 100644 --- a/doc/destructors.rst +++ b/doc/destructors.rst @@ -612,7 +612,7 @@ indirections: .. code-block:: nim proc main(tab: Table[string, string]) = - let v = tab["key"] # inferred as `cursor` because 'tab' is not mutated. + let v = tab["key"] # inferred as cursor because 'tab' is not mutated. # no copy into 'v', no destruction of 'v'. use(v) useItAgain(v)