diff options
Diffstat (limited to 'doc/manual.rst')
-rw-r--r-- | doc/manual.rst | 216 |
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 |