From 8062698e7f6c28debb7e938e472ac64632e6a1ff Mon Sep 17 00:00:00 2001 From: awr <41453959+awr1@users.noreply.github.com> Date: Wed, 29 Aug 2018 13:49:45 -0500 Subject: [PATCH 1/5] [Docs] Added {.reorder.} to manual --- doc/manual.rst | 107 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 35 deletions(-) diff --git a/doc/manual.rst b/doc/manual.rst index bb2650799b..26ff071d7d 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -6823,54 +6823,91 @@ 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. +reorder pragma +-------------- +**Note**: Code reordering is experimental. By default it is turned off. + +The ``reorder`` pragma can be used to turn on and off a special compilation mode +that aims to be able to 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. .. - 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: + NOTE: The following was documentation for the precursor to {.reorder.}, + 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). + 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. + 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. + 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. + 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: +Example: - .. code-block:: nim +.. code-block:: nim - {.noforward: on.} + {.reorder: on.} - proc foo(x: int) = - bar x + proc foo(x: int) = + bar(x) - proc bar(x: int) = - echo x + proc bar(x: int) = + echo(x) - foo(10) + foo(10) +Variables can also be reordered as well. Keep in mind, when we initialize (i.e. +combined declaration and assignment in one statement) variables, that entire +statement itself may be reordered. Be wary of what code you execute at the top +level: + +.. code-block:: nim + {.reorder: on.} + + proc a() = + echo(foo) + + var foo = 5 + + a() # outputs: "5" + +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 + {.reorder: on.} + + proc a() = + b() + proc b() = + echo("Hello!") + + a() pragma pragma ------------- From 47726ecb9e4af38bfdad7f94f03d27385f2ac0f6 Mon Sep 17 00:00:00 2001 From: awr <41453959+awr1@users.noreply.github.com> Date: Tue, 4 Sep 2018 15:25:46 -0500 Subject: [PATCH 2/5] updated manual for declared() --- doc/manual.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/manual.rst b/doc/manual.rst index 26ff071d7d..e76cf3d78a 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -6896,6 +6896,20 @@ level: a() # outputs: "5" +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 + {.reorder: on.} + + 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:* From 32deb70bae984dc034c3f0d61f414f1530701b3f Mon Sep 17 00:00:00 2001 From: awr <41453959+awr1@users.noreply.github.com> Date: Thu, 6 Sep 2018 23:49:38 -0500 Subject: [PATCH 3/5] changed to {.experimental: codeReordering.}, postpoing declared() stuff --- doc/manual.rst | 202 +++++++++++++++++++++++++------------------------ 1 file changed, 105 insertions(+), 97 deletions(-) diff --git a/doc/manual.rst b/doc/manual.rst index e76cf3d78a..33d3e8242a 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -6418,6 +6418,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. Keep in mind, when we initialize (i.e. +combined declaration and assignment in one statement) variables, that entire +statement itself may be reordered. Be wary of what code you execute 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. + + 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 ================= @@ -6825,103 +6930,6 @@ and before any variable in a module that imports it. reorder pragma -------------- -**Note**: Code reordering is experimental. By default it is turned off. - -The ``reorder`` pragma can be used to turn on and off a special compilation mode -that aims to be able to 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 precursor to {.reorder.}, - 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 - - {.reorder: on.} - - proc foo(x: int) = - bar(x) - - proc bar(x: int) = - echo(x) - - foo(10) - -Variables can also be reordered as well. Keep in mind, when we initialize (i.e. -combined declaration and assignment in one statement) variables, that entire -statement itself may be reordered. Be wary of what code you execute at the top -level: - -.. code-block:: nim - {.reorder: on.} - - proc a() = - echo(foo) - - var foo = 5 - - a() # outputs: "5" - -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 - {.reorder: on.} - - 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 - {.reorder: on.} - - proc a() = - b() - proc b() = - echo("Hello!") - - a() pragma pragma ------------- From 5ee924c711fdb04bef0106ccaeb21c37542c2508 Mon Sep 17 00:00:00 2001 From: awr <41453959+awr1@users.noreply.github.com> Date: Fri, 7 Sep 2018 00:00:20 -0500 Subject: [PATCH 4/5] whoops, forgot to remove old pragma section --- doc/manual.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/manual.rst b/doc/manual.rst index 33d3e8242a..a7bec649ce 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -6495,7 +6495,7 @@ level: .. 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. + 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 @@ -6928,9 +6928,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. -reorder pragma --------------- - pragma pragma ------------- From e4c4cbc176b62c8e4ee715a25640e40e1533584e Mon Sep 17 00:00:00 2001 From: awr <41453959+awr1@users.noreply.github.com> Date: Wed, 12 Sep 2018 18:29:01 -0500 Subject: [PATCH 5/5] fixed language wrt initialization --- doc/manual.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/manual.rst b/doc/manual.rst index a7bec649ce..4f0530a8a5 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -6477,10 +6477,10 @@ Example: foo(10) -Variables can also be reordered as well. Keep in mind, when we initialize (i.e. -combined declaration and assignment in one statement) variables, that entire -statement itself may be reordered. Be wary of what code you execute at the top -level: +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".}