summary refs log tree commit diff stats
path: root/doc/manual.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/manual.rst')
-rw-r--r--doc/manual.rst216
1 files changed, 144 insertions, 72 deletions
diff --git a/doc/manual.rst b/doc/manual.rst
index 6dc6794f1..6afc10473 100644
--- a/doc/manual.rst
+++ b/doc/manual.rst
@@ -3638,10 +3638,31 @@ Invocation of a multi-method cannot be ambiguous: collide 2 is preferred over
 collide 1 because the resolution works from left to right.
 In the example ``Unit, Thing`` is preferred over ``Thing, Unit``.
 
-**Performance note**: Nim does not produce a virtual method table, but
-generates dispatch trees. This avoids the expensive indirect branch for method
-calls and enables inlining. However, other optimizations like compile time
-evaluation or dead code elimination do not work with methods.
+**Note**: Compile time evaluation is not (yet) supported for methods.
+
+
+Inhibit dynamic method resolution via procCall
+-----------------------------------------------
+
+Dynamic method resolution can be inhibited via the builtin `system.procCall`:idx:.
+This is somewhat comparable to the `super`:idx: keyword that traditional OOP
+languages offer.
+
+.. code-block:: nim
+    :test: "nim c $1"
+
+  type
+    Thing = ref object of RootObj
+    Unit = ref object of Thing
+      x: int
+
+  method m(a: Thing) {.base.} =
+    echo "base"
+
+  method m(a: Unit) =
+    # Call the base method:
+    procCall m(Thing(a))
+    echo "1"
 
 
 Iterators and the for statement
@@ -6534,6 +6555,111 @@ iterator in which case the overloading resolution takes place:
   var x = 4
   write(stdout, x) # not ambiguous: uses the module C's x
 
+Code reordering
+~~~~~~~~~~~~~~~
+
+**Note**: Code reordering is experimental and must be enabled via the
+``{.experimental.}`` pragma.
+
+The code reordering feature can implicitly rearrange procedure, template, and
+macro definitions along with variable declarations and initializations at the top
+level scope so that, to a large extent, a programmer should not have to worry
+about ordering definitions correctly or be forced to use forward declarations to
+preface definitions inside a module.
+
+..
+   NOTE: The following was documentation for the code reordering precursor,
+   which was {.noForward.}.
+
+   In this mode, procedure definitions may appear out of order and the compiler
+   will postpone their semantic analysis and compilation until it actually needs
+   to generate code using the definitions. In this regard, this mode is similar
+   to the modus operandi of dynamic scripting languages, where the function
+   calls are not resolved until the code is executed. Here is the detailed
+   algorithm taken by the compiler:
+
+   1. When a callable symbol is first encountered, the compiler will only note
+   the symbol callable name and it will add it to the appropriate overload set
+   in the current scope. At this step, it won't try to resolve any of the type
+   expressions used in the signature of the symbol (so they can refer to other
+   not yet defined symbols).
+
+   2. When a top level call is encountered (usually at the very end of the
+   module), the compiler will try to determine the actual types of all of the
+   symbols in the matching overload set. This is a potentially recursive process
+   as the signatures of the symbols may include other call expressions, whose
+   types will be resolved at this point too.
+
+   3. Finally, after the best overload is picked, the compiler will start
+   compiling the body of the respective symbol. This in turn will lead the
+   compiler to discover more call expressions that need to be resolved and steps
+   2 and 3 will be repeated as necessary.
+
+   Please note that if a callable symbol is never used in this scenario, its
+   body will never be compiled. This is the default behavior leading to best
+   compilation times, but if exhaustive compilation of all definitions is
+   required, using ``nim check`` provides this option as well.
+
+Example:
+
+.. code-block:: nim
+
+  {.experimental: "codeReordering".}
+
+  proc foo(x: int) =
+    bar(x)
+
+  proc bar(x: int) =
+    echo(x)
+
+  foo(10)
+
+Variables can also be reordered as well. Variables that are *initialized* (i.e.
+variables that have their declaration and assignment combined in a single
+statement) can have their entire initialization statement reordered. Be wary of
+what code is executed at the top level:
+
+.. code-block:: nim
+  {.experimental: "codeReordering".}
+
+  proc a() =
+    echo(foo)
+
+  var foo = 5
+
+  a() # outputs: "5"
+
+..
+   TODO: Let's table this for now. This is an *experimental feature* and so the
+   specific manner in which ``declared`` operates with it can be decided in
+   eventuality, because right now it works a bit weirdly.
+
+   The values of expressions involving ``declared`` are decided *before* the
+   code reordering process, and not after. As an example, the output of this
+   code is the same as it would be with code reordering disabled.
+
+   .. code-block:: nim
+     {.experimental: "codeReordering".}
+
+     proc x() =
+       echo(declared(foo))
+
+     var foo = 4
+
+     x() # "false"
+
+It is important to note that reordering *only* works for symbols at top level
+scope. Therefore, the following will *fail to compile:*
+
+.. code-block:: nim
+  {.experimental: "codeReordering".}
+
+  proc a() =
+    b()
+    proc b() =
+      echo("Hello!")
+
+  a()
 
 Compiler Messages
 =================
@@ -6567,18 +6693,12 @@ The deprecated pragma is used to mark a symbol as deprecated:
 This pragma can also take in an optional warning string to relay to developers.
 
 .. code-block:: nim
-  proc thing(x: bool) {.deprecated: "See arguments of otherThing()".}
+  proc thing(x: bool) {.deprecated: "use thong instead".}
 
-It can also be used as a statement, in that case it takes a list of *renamings*.
-
-.. code-block:: nim
-  type
-    File = object
-    Stream = ref object
-  {.deprecated: [TFile: File, PStream: Stream].}
 
 noSideEffect pragma
 -------------------
+
 The ``noSideEffect`` pragma is used to mark a proc/iterator to have no side
 effects. This means that the proc/iterator only changes locations that are
 reachable from its parameters and the return value only depends on the
@@ -6943,55 +7063,6 @@ the created global variables within a module is not defined, but all of them
 will be initialized after any top-level variables in their originating module
 and before any variable in a module that imports it.
 
-
-..
-  NoForward pragma
-  ----------------
-  The ``noforward`` pragma can be used to turn on and off a special compilation
-  mode that to large extent eliminates the need for forward declarations. In this
-  mode, the proc definitions may appear out of order and the compiler will postpone
-  their semantic analysis and compilation until it actually needs to generate code
-  using the definitions. In this regard, this mode is similar to the modus operandi
-  of dynamic scripting languages, where the function calls are not resolved until
-  the code is executed. Here is the detailed algorithm taken by the compiler:
-
-  1. When a callable symbol is first encountered, the compiler will only note the
-  symbol callable name and it will add it to the appropriate overload set in the
-  current scope. At this step, it won't try to resolve any of the type expressions
-  used in the signature of the symbol (so they can refer to other not yet defined
-  symbols).
-
-  2. When a top level call is encountered (usually at the very end of the module),
-  the compiler will try to determine the actual types of all of the symbols in the
-  matching overload set. This is a potentially recursive process as the signatures
-  of the symbols may include other call expressions, whose types will be resolved
-  at this point too.
-
-  3. Finally, after the best overload is picked, the compiler will start
-  compiling the body of the respective symbol. This in turn will lead the
-  compiler to discover more call expressions that need to be resolved and steps
-  2 and 3 will be repeated as necessary.
-
-  Please note that if a callable symbol is never used in this scenario, its body
-  will never be compiled. This is the default behavior leading to best compilation
-  times, but if exhaustive compilation of all definitions is required, using
-  ``nim check`` provides this option as well.
-
-  Example:
-
-  .. code-block:: nim
-
-    {.noforward: on.}
-
-    proc foo(x: int) =
-      bar x
-
-    proc bar(x: int) =
-      echo x
-
-    foo(10)
-
-
 pragma pragma
 -------------
 
@@ -7675,20 +7746,21 @@ documentation for details. These macros are no magic, they don't do anything
 you cannot do yourself by walking AST object representation.
 
 More examples with custom pragmas:
-  - Better serialization/deserialization control:
 
-  .. code-block:: nim
-    type MyObj = object
-      a {.dontSerialize.}: int
-      b {.defaultDeserialize: 5.}: int
-      c {.serializationKey: "_c".}: string
+- Better serialization/deserialization control:
 
-  - Adopting type for gui inspector in a game engine:
+.. code-block:: nim
+  type MyObj = object
+    a {.dontSerialize.}: int
+    b {.defaultDeserialize: 5.}: int
+    c {.serializationKey: "_c".}: string
 
-  .. code-block:: nim
-    type MyComponent = object
-      position {.editable, animatable.}: Vector3
-      alpha {.editRange: [0.0..1.0], animatable.}: float32
+- Adopting type for gui inspector in a game engine:
+
+.. code-block:: nim
+  type MyComponent = object
+    position {.editable, animatable.}: Vector3
+    alpha {.editRange: [0.0..1.0], animatable.}: float32