summary refs log tree commit diff stats
path: root/doc
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2019-08-27 12:13:06 +0200
committerAraq <rumpf_a@web.de>2019-08-27 12:13:06 +0200
commit1ccff0324c74051da445852b31932aa2bbdb0c7a (patch)
tree0fd2deb623fc08ba2cb2a0be44043595599457dc /doc
parentddc155af64c2e7762c0efa33f8cc9fe9150f5d21 (diff)
downloadNim-1ccff0324c74051da445852b31932aa2bbdb0c7a.tar.gz
manual: more precise rules about evaluation order
Diffstat (limited to 'doc')
-rw-r--r--doc/manual.rst38
1 files changed, 38 insertions, 0 deletions
diff --git a/doc/manual.rst b/doc/manual.rst
index a40e83809..f0945f78d 100644
--- a/doc/manual.rst
+++ b/doc/manual.rst
@@ -721,6 +721,44 @@ Rationale: Consistency with overloaded assignment or assignment-like operations,
 ``a = b`` can be read as ``performSomeCopy(a, b)``.
 
 
+However, the concept of "order of evaluation" is only applicable after the code
+was normalized: The normalization involves template expansions and argument
+reorderings that have been passed to named parameters:
+
+.. code-block:: nim
+    :test: "nim c $1"
+
+  var s = ""
+
+  proc p(): int =
+    s.add "p"
+    result = 5
+
+  proc q(): int =
+    s.add "q"
+    result = 3
+
+  # Evaluation order is 'b' before 'a' due to template
+  # expansion's semantics.
+  template swapArgs(a, b): untyped =
+    b + a
+
+  doAssert swapArgs(p() + q(), q() - p()) == 6
+  doAssert s == "qppq"
+
+  # Evaluation order is not influenced by named parameters:
+  proc construct(first, second: int) =
+    discard
+
+  # 'p' is evaluated before 'q'!
+  construct(second = q(), first = p())
+
+  doAssert s == "qppqpq"
+
+
+Rationale: This is far easier to implement than hypothetical alternatives.
+
+
 Constants and Constant Expressions
 ==================================