summary refs log tree commit diff stats
path: root/doc/manual.txt
diff options
context:
space:
mode:
authorrumpf_a@web.de <>2009-10-21 10:20:15 +0200
committerrumpf_a@web.de <>2009-10-21 10:20:15 +0200
commit053309e60aee1eda594a4817ac8ac2fb8c18fb04 (patch)
tree0f1ce8b0de0b493045eb97eeca6ebf06542de601 /doc/manual.txt
parent581572b28c65bc9fe47974cfd625210a69be0f3f (diff)
downloadNim-053309e60aee1eda594a4817ac8ac2fb8c18fb04.tar.gz
version 0.8.2
Diffstat (limited to 'doc/manual.txt')
-rwxr-xr-xdoc/manual.txt97
1 files changed, 91 insertions, 6 deletions
diff --git a/doc/manual.txt b/doc/manual.txt
index 3c24e4b1a..9cf1f3bc2 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -342,7 +342,7 @@ Syntax
 ======
 
 This section lists Nimrod's standard syntax in ENBF. How the parser receives
-indentation tokens is already described in the Lexical Analysis section.
+indentation tokens is already described in the `Lexical Analysis`_ section.
 
 Nimrod allows user-definable operators.
 Binary operators have 8 different levels of precedence. For user-defined
@@ -363,8 +363,7 @@ Precedence level    Operators                                     First characte
 ================  ==============================================  ==================  ===============
 
 
-The grammar's start symbol is ``module``. The grammar is LL(1) and therefore
-not ambiguous.
+The grammar's start symbol is ``module``.
 
 .. include:: grammar.txt
    :literal:
@@ -875,8 +874,7 @@ Procedural type
 ~~~~~~~~~~~~~~~
 A `procedural type`:idx: is internally a pointer to a procedure. ``nil`` is
 an allowed value for variables of a procedural type. Nimrod uses procedural
-types to achieve `functional`:idx: programming techniques. Dynamic dispatch
-for OOP constructs can also be implemented with procedural types.
+types to achieve `functional`:idx: programming techniques.
 
 Example:
 
@@ -946,6 +944,16 @@ each other:
 
 Most calling conventions exist only for the Windows 32-bit platform.
 
+Assigning/passing a procedure to a procedural variable is only allowed if one 
+of the following conditions hold: 
+1) The procedure that is accessed resists in the current module.
+2) The procedure is marked with the ``procvar`` pragma (see `procvar pragma`_).
+3) The procedure has a calling convention that differs from ``nimcall``. 
+4) The procedure is anonymous.
+
+These rules should prevent the case that extending a non-``procvar`` 
+procedure with default parameters breaks client code.
+
 
 Distinct type
 ~~~~~~~~~~~~~
@@ -1054,7 +1062,7 @@ describe the type checking done by the compiler.
 Type equality
 ~~~~~~~~~~~~~
 Nimrod uses structural type equivalence for most types. Only for objects,
-enumerations and abstract types name equivalence is used. The following
+enumerations and distinct types name equivalence is used. The following
 algorithm determines type equality:
 
 .. code-block:: nimrod
@@ -1800,6 +1808,77 @@ Even more elegant is to use `tuple unpacking`:idx: to access the tuple's fields:
   assert y == 3
 
 
+Multi-methods
+~~~~~~~~~~~~~
+
+Procedures always use static dispatch. Dynamic dispatch is achieved by
+`multi-methods`:idx:. 
+
+.. code-block:: nimrod
+  type
+    TExpr = object ## abstract base class for an expression
+    TLiteral = object of TExpr
+      x: int
+    TPlusExpr = object of TExpr
+      a, b: ref TExpr
+      
+  method eval(e: ref TExpr): int =
+    # override this base method
+    quit "to override!"
+  
+  method eval(e: ref TLiteral): int = return e.x
+
+  method eval(e: ref TPlusExpr): int =
+    # watch out: relies on dynamic binding
+    return eval(e.a) + eval(e.b)
+  
+  proc newLit(x: int): ref TLiteral =
+    new(result)
+    result.x = x
+    
+  proc newPlus(a, b: ref TExpr): ref TPlusExpr =
+    new(result)
+    result.a = a
+    result.b = b
+  
+  echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))
+  
+In the example the constructors ``newLit`` and ``newPlus`` are procs
+because they should use static binding, but ``eval`` is a method because it
+requires dynamic binding.
+
+In a multi-method all parameters that have an object type are used for the
+dispatching:
+
+.. code-block:: nimrod
+  type
+    TThing = object
+    TUnit = object of TThing
+      x: int
+      
+  method collide(a, b: TThing) {.inline.} =
+    quit "to override!"
+    
+  method collide(a: TThing, b: TUnit) {.inline.} =
+    echo "1"
+  
+  method collide(a: TUnit, b: TThing) {.inline.} =
+    echo "2"
+  
+  var
+    a, b: TUnit
+  collide(a, b) # output: 2
+
+
+Invokation of a multi-method cannot be ambiguous: Collide 2 is prefered over 
+collide 1 because the resolution works from left to right. 
+Thus ``TUnit, TThing`` is prefered over ``TThing, TUnit``.
+
+**Perfomance note**: Nimrod 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.
+
 
 Iterators and the for statement
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2275,6 +2354,12 @@ error to mark a proc/iterator to have no side effect if the compiler cannot
 verify this.
 
 
+procvar pragma
+--------------
+The `procvar`:idx: pragma is used to mark a proc that it can be passed to a 
+procedural variable. 
+
+
 compileTime pragma
 ------------------
 The `compileTime`:idx: pragma is used to mark a proc to be used at compile