summary refs log tree commit diff stats
path: root/doc/manual
diff options
context:
space:
mode:
Diffstat (limited to 'doc/manual')
-rw-r--r--doc/manual/exceptions.txt2
-rw-r--r--doc/manual/ffi.txt30
-rw-r--r--doc/manual/generics.txt12
-rw-r--r--doc/manual/lexing.txt2
-rw-r--r--doc/manual/locking.txt6
-rw-r--r--doc/manual/pragmas.txt44
-rw-r--r--doc/manual/procs.txt10
-rw-r--r--doc/manual/special_ops.txt3
-rw-r--r--doc/manual/stmts.txt3
-rw-r--r--doc/manual/syntax.txt50
-rw-r--r--doc/manual/templates.txt26
-rw-r--r--doc/manual/trmacros.txt18
-rw-r--r--doc/manual/type_rel.txt54
-rw-r--r--doc/manual/typedesc.txt32
-rw-r--r--doc/manual/types.txt20
15 files changed, 164 insertions, 148 deletions
diff --git a/doc/manual/exceptions.txt b/doc/manual/exceptions.txt
index e7af65386..d06c13df4 100644
--- a/doc/manual/exceptions.txt
+++ b/doc/manual/exceptions.txt
@@ -155,4 +155,4 @@ Exception hierarchy
 
 The exception tree is defined in the `system <system.html>`_ module:
 
-.. include:: exception_hierarchy_fragment.txt
+.. include:: ../exception_hierarchy_fragment.txt
diff --git a/doc/manual/ffi.txt b/doc/manual/ffi.txt
index f08be6ad3..d7d9596d2 100644
--- a/doc/manual/ffi.txt
+++ b/doc/manual/ffi.txt
@@ -16,11 +16,19 @@ spelled*:
 .. code-block::
   proc printf(formatstr: cstring) {.header: "<stdio.h>", importc: "printf", varargs.}
 
-Note that this pragma is somewhat of a misnomer: Other backends will provide
+Note that this pragma is somewhat of a misnomer: Other backends do provide
 the same feature under the same name. Also, if one is interfacing with C++
-the `ImportCpp pragma <nimc.html#importcpp-pragma>`_ and
+the `ImportCpp pragma <manual.html#implementation-specific-pragmas-importcpp-pragma>`_ and
 interfacing with Objective-C the `ImportObjC pragma
-<nimc.html#importobjc-pragma>`_ can be used.
+<manual.html#implementation-specific-pragmas-importobjc-pragma>`_ can be used.
+
+The string literal passed to ``importc`` can be a format string:
+
+.. code-block:: Nim
+  proc p(s: cstring) {.importc: "prefix$1".}
+
+In the example the external name of ``p`` is set to ``prefixp``. Only ``$1``
+is available and a literal dollar sign must be written as ``$$``.
 
 
 Exportc pragma
@@ -33,9 +41,19 @@ name is the Nim identifier *exactly as spelled*:
 .. code-block:: Nim
   proc callme(formatstr: cstring) {.exportc: "callMe", varargs.}
 
-Note that this pragma is somewhat of a misnomer: Other backends will provide
+Note that this pragma is somewhat of a misnomer: Other backends do provide
 the same feature under the same name.
 
+The string literal passed to ``exportc`` can be a format string:
+
+.. code-block:: Nim
+  proc p(s: string) {.exportc: "prefix$1".} =
+    echo s
+
+In the example the external name of ``p`` is set to ``prefixp``. Only ``$1``
+is available and a literal dollar sign must be written as ``$$``.
+
+
 
 Extern pragma
 -------------
@@ -46,7 +64,9 @@ mangling. The string literal passed to ``extern`` can be a format string:
   proc p(s: string) {.extern: "prefix$1".} =
     echo s
 
-In the example the external name of ``p`` is set to ``prefixp``.
+In the example the external name of ``p`` is set to ``prefixp``. Only ``$1``
+is available and a literal dollar sign must be written as ``$$``.
+
 
 
 Bycopy pragma
diff --git a/doc/manual/generics.txt b/doc/manual/generics.txt
index 07d98b289..c1c6467e7 100644
--- a/doc/manual/generics.txt
+++ b/doc/manual/generics.txt
@@ -232,16 +232,6 @@ type signatures of the required operations, but since type inference and
 default parameters are still applied in the provided block, it's also possible
 to encode usage protocols that do not reveal implementation details.
 
-As a special rule providing further convenience when writing concepts, any
-type value appearing in a callable expression will be treated as a variable of
-the designated type for overload resolution purposes, unless the type value was
-passed in its explicit ``typedesc[T]`` form:
-
-.. code-block:: nim
-  type
-    OutputStream = concept s
-      write(var s, string)
-
 Much like generics, concepts are instantiated exactly
 once for each tested type and any static code included within them is also
 executed once.
@@ -303,7 +293,7 @@ definition):
   var
     lastId = 0
 
-  template genId*: expr =
+  template genId*: untyped =
     bind lastId
     inc(lastId)
     lastId
diff --git a/doc/manual/lexing.txt b/doc/manual/lexing.txt
index 4187a60a4..4d03023c3 100644
--- a/doc/manual/lexing.txt
+++ b/doc/manual/lexing.txt
@@ -116,7 +116,7 @@ operator characters instead.
 The following keywords are reserved and cannot be used as identifiers:
 
 .. code-block:: nim
-   :file: keywords.txt
+   :file: ../keywords.txt
 
 Some keywords are unused; they are reserved for future developments of the
 language.
diff --git a/doc/manual/locking.txt b/doc/manual/locking.txt
index b14c98636..c00efdd91 100644
--- a/doc/manual/locking.txt
+++ b/doc/manual/locking.txt
@@ -48,7 +48,7 @@ semantics and should not be used directly! It should only be used in templates
 that also implement some form of locking at runtime:
 
 .. code-block:: nim
-  template lock(a: TLock; body: stmt) =
+  template lock(a: TLock; body: untyped) =
     pthread_mutex_lock(a)
     {.locks: [a].}:
       try:
@@ -64,7 +64,7 @@ model low level lockfree mechanisms:
   var dummyLock {.compileTime.}: int
   var atomicCounter {.guard: dummyLock.}: int
 
-  template atomicRead(x): expr =
+  template atomicRead(x): untyped =
     {.locks: [dummyLock].}:
       memoryReadBarrier()
       x
@@ -167,7 +167,7 @@ the runtime check is required to ensure a global ordering for two locks ``a``
 and ``b`` of the same lock level:
 
 .. code-block:: nim
-  template multilock(a, b: ptr TLock; body: stmt) =
+  template multilock(a, b: ptr TLock; body: untyped) =
     if cast[ByteAddress](a) < cast[ByteAddress](b):
       pthread_mutex_lock(a)
       pthread_mutex_lock(b)
diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt
index f89194c9a..70fc4a914 100644
--- a/doc/manual/pragmas.txt
+++ b/doc/manual/pragmas.txt
@@ -55,7 +55,7 @@ destructor pragma
 -----------------
 
 The ``destructor`` pragma is used to mark a proc to act as a type destructor.
-Its usage is deprecated, See `type bound operations`_ instead.
+Its usage is deprecated, see `type bound operations`_ instead.
 
 override pragma
 ---------------
@@ -213,7 +213,7 @@ statement as seen in stack backtraces:
 
 .. code-block:: nim
 
-  template myassert*(cond: expr, msg = "") =
+  template myassert*(cond: untyped, msg = "") =
     if not cond:
       # change run-time line information of the 'raise' statement:
       {.line: InstantiationInfo().}:
@@ -518,11 +518,16 @@ Example:
 
 .. code-block:: nim
   {.experimental.}
+  type
+    FooId = distinct int
+    BarId = distinct int
+  using
+    foo: FooId
+    bar: BarId
 
-  proc useUsing(dest: var string) =
-    using dest
-    add "foo"
-    add "bar"
+  proc useUsing(bar, foo) =
+    echo "bar is of type BarId"
+    echo "foo is of type FooId"
 
 
 Implementation Specific Pragmas
@@ -1006,3 +1011,30 @@ debugging:
 
   # ... complex code here that produces crashes ...
 
+compile time define pragmas
+---------------------------
+
+The pragmas listed here can be used to optionally accept values from
+the -d/--define option at compile time.
+
+The implementation currently provides the following possible options (various
+others may be added later).
+
+===============  ============================================
+pragma           description
+===============  ============================================
+intdefine        Reads in a build-time define as an integer
+strdefine        Reads in a build-time define as a string
+===============  ============================================
+
+.. code-block:: nim
+   const FooBar {.intdefine.}: int = 5
+   echo FooBar
+
+.. code-block:: bash
+   nim c -d:FooBar=42 foobar.c
+
+In the above example, providing the -d flag causes the symbol
+``FooBar`` to be overwritten at compile time, printing out 42. If the
+``-d:FooBar=42`` were to be omitted, the default value of 5 would be
+used.
diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt
index 9ce92de0d..ea6866845 100644
--- a/doc/manual/procs.txt
+++ b/doc/manual/procs.txt
@@ -215,6 +215,12 @@ the closure and its enclosing scope (i.e. any modifications made to them are
 visible in both places). The closure environment may be allocated on the heap
 or on the stack if the compiler determines that this would be safe.
 
+Creating closures in loops
+~~~~~~~~~~~~~~~~
+
+Since closures capture local variables by reference it is often not wanted
+behavior inside loop bodies. See `closureScope <system.html#closureScope>`_
+for details on how to change this behavior.
 
 Anonymous Procs
 ---------------
@@ -223,7 +229,7 @@ Procs can also be treated as expressions, in which case it's allowed to omit
 the proc's name.
 
 .. code-block:: nim
-  var cities = @["Frankfurt", "Tokyo", "New York"]
+  var cities = @["Frankfurt", "Tokyo", "New York", "Kyiv"]
 
   cities.sort(proc (x,y: string): int =
       cmp(x.len, y.len))
@@ -619,7 +625,7 @@ Note that ``system.finished`` is error prone to use because it only returns
   3
   0
 
-Instead this code has be used:
+Instead this code has to be used:
 
 .. code-block:: nim
   var c = mycount # instantiate the iterator
diff --git a/doc/manual/special_ops.txt b/doc/manual/special_ops.txt
index 702693423..1c7136bec 100644
--- a/doc/manual/special_ops.txt
+++ b/doc/manual/special_ops.txt
@@ -4,6 +4,9 @@ Special Operators
 dot operators
 -------------
 
+**Note**: Dot operators are still experimental and so need to be enabled
+via ``{.experimental.}``.
+
 Nim offers a special family of dot operators that can be used to
 intercept and rewrite proc call and field access attempts, referring
 to previously undeclared symbol names. They can be used to provide a
diff --git a/doc/manual/stmts.txt b/doc/manual/stmts.txt
index 65c810cf7..318738063 100644
--- a/doc/manual/stmts.txt
+++ b/doc/manual/stmts.txt
@@ -577,6 +577,9 @@ name ``c`` should default to type ``Context``, ``n`` should default to
 The ``using`` section uses the same indentation based grouping syntax as
 a ``var`` or ``let`` section.
 
+Note that ``using`` is not applied for ``template`` since untyped template
+parameters default to the type ``system.untyped``.
+
 
 If expression
 -------------
diff --git a/doc/manual/syntax.txt b/doc/manual/syntax.txt
index ca3b582ca..89f8ca707 100644
--- a/doc/manual/syntax.txt
+++ b/doc/manual/syntax.txt
@@ -19,10 +19,8 @@ other binary operators are left-associative.
   proc `^/`(x, y: float): float =
     # a right-associative division operator
     result = x / y
-  echo 12 ^/ 4 ^/ 8 # 24.0 (4 / 8 = 0.5, then
-                           12 / 0.5 = 24.0)
-  echo 12  / 4  / 8 # 0.375 (12 / 4 = 3.0, then
-                              3 / 8 = 0.375)
+  echo 12 ^/ 4 ^/ 8 # 24.0 (4 / 8 = 0.5, then 12 / 0.5 = 24.0)
+  echo 12  / 4  / 8 # 0.375 (12 / 4 = 3.0, then 3 / 8 = 0.375)
 
 Precedence
 ----------
@@ -72,53 +70,11 @@ Whether an operator is used a prefix operator is also affected by preceeding whi
   echo($foo)
 
 
-Strong spaces
--------------
-
-The number of spaces preceding a non-keyword operator affects precedence
-if the experimental parser directive ``#?strongSpaces`` is used. Indentation
-is not used to determine the number of spaces. If 2 or more operators have the
-same number of preceding spaces the precedence table applies, so ``1 + 3 * 4``
-is still parsed as ``1 + (3 * 4)``, but ``1+3 * 4`` is parsed as ``(1+3) * 4``:
-
-.. code-block:: nim
-  #? strongSpaces
-  if foo+4 * 4 == 8  and  b&c | 9  ++
-      bar:
-    echo ""
-  # is parsed as
-  if ((foo+4)*4 == 8) and (((b&c) | 9) ++ bar): echo ""
-
-
-Furthermore whether an operator is used a prefix operator is affected by the
-number of spaces:
-
-.. code-block:: nim
-  #? strongSpaces
-  echo $foo
-  # is parsed as
-  echo($foo)
-
-This also affects whether ``[]``, ``{}``, ``()`` are parsed as constructors
-or as accessors:
-
-.. code-block:: nim
-  #? strongSpaces
-  echo (1,2)
-  # is parsed as
-  echo((1,2))
-
-Only 0, 1, 2, 4 or 8 spaces are allowed to specify precedence and it is
-enforced that infix operators have the same amount of spaces before and after
-them. This rules does not apply when a newline follows after the operator,
-then only the preceding spaces are considered.
-
-
 Grammar
 -------
 
 The grammar's start symbol is ``module``.
 
-.. include:: grammar.txt
+.. include:: ../grammar.txt
    :literal:
 
diff --git a/doc/manual/templates.txt b/doc/manual/templates.txt
index b60fe632e..be5c6fa18 100644
--- a/doc/manual/templates.txt
+++ b/doc/manual/templates.txt
@@ -57,8 +57,7 @@ A template where every parameter is ``untyped`` is called an `immediate`:idx:
 template. For historical reasons templates can be explicitly annotated with
 an ``immediate`` pragma and then these templates do not take part in
 overloading resolution and the parameters' types are *ignored* by the
-compiler. Explicit immediate templates are about to be deprecated in later
-versions of the compiler.
+compiler. Explicit immediate templates are now deprecated.
 
 **Note**: For historical reasons ``stmt`` is an alias for ``typed`` and
 ``expr`` an alias for ``untyped``, but new code should use the newer,
@@ -159,7 +158,7 @@ bound from the definition scope of the template:
   var
     lastId = 0
 
-  template genId*: expr =
+  template genId*: untyped =
     inc(lastId)
     lastId
 
@@ -181,7 +180,7 @@ In templates identifiers can be constructed with the backticks notation:
 
 .. code-block:: nim
 
-  template typedef(name: expr, typ: typedesc) {.immediate.} =
+  template typedef(name: untyped, typ: typedesc) =
     type
       `T name`* {.inject.} = typ
       `P name`* {.inject.} = ref `T name`
@@ -242,7 +241,7 @@ template cannot be accessed in the instantiation context:
 
 .. code-block:: nim
 
-  template newException*(exceptn: typedesc, message: string): expr =
+  template newException*(exceptn: typedesc, message: string): untyped =
     var
       e: ref exceptn  # e is implicitly gensym'ed here
     new(e)
@@ -264,7 +263,7 @@ is ``gensym`` and for ``proc``, ``iterator``, ``converter``, ``template``,
 template parameter, it is an inject'ed symbol:
 
 .. code-block:: nim
-  template withFile(f, fn, mode: expr, actions: stmt): stmt {.immediate.} =
+  template withFile(f, fn, mode: untyped, actions: untyped): untyped =
     block:
       var f: File  # since 'f' is a template param, it's injected implicitly
       ...
@@ -298,7 +297,7 @@ rewritten to ``f(x)``. Therefore the dot syntax has some limiations when it
 is used to invoke templates/macros:
 
 .. code-block:: nim
-  template declareVar(name: expr): stmt =
+  template declareVar(name: untyped) =
     const name {.inject.} = 45
 
   # Doesn't compile:
@@ -325,8 +324,7 @@ Macros
 ======
 
 A macro is a special kind of low level template. Macros can be used
-to implement `domain specific languages`:idx:. Like templates, macros come in
-the 2 flavors *immediate* and *ordinary*.
+to implement `domain specific languages`:idx:.
 
 While macros enable advanced compile-time code transformations, they
 cannot change Nim's syntax. However, this is no real restriction because
@@ -351,7 +349,7 @@ variable number of arguments:
   # ``macros`` module:
   import macros
 
-  macro debug(n: varargs[expr]): stmt =
+  macro debug(n: varargs[untyped]): untyped =
     # `n` is a Nim AST that contains the whole macro invocation
     # this macro returns a list of statements:
     result = newNimNode(nnkStmtList, n)
@@ -406,7 +404,7 @@ builtin can be used for that:
 .. code-block:: nim
   import macros
 
-  macro debug(n: varargs[expr]): stmt =
+  macro debug(n: varargs[typed]): untyped =
     result = newNimNode(nnkStmtList, n)
     for i in 0..n.len-1:
       # we can bind symbols in scope via 'bindSym':
@@ -454,7 +452,7 @@ regular expressions:
 .. code-block:: nim
   import macros
 
-  macro case_token(n: stmt): stmt =
+  macro case_token(n: untyped): untyped =
     # creates a lexical analyzer from regular expressions
     # ... (implementation is an exercise for the reader :-)
     discard
@@ -486,14 +484,14 @@ Whole routines (procs, iterators etc.) can also be passed to a template or
 a macro via the pragma notation:
 
 .. code-block:: nim
-  template m(s: stmt) = discard
+  template m(s: untyped) = discard
 
   proc p() {.m.} = discard
 
 This is a simple syntactic transformation into:
 
 .. code-block:: nim
-  template m(s: stmt) = discard
+  template m(s: untyped) = discard
 
   m:
     proc p() = discard
diff --git a/doc/manual/trmacros.txt b/doc/manual/trmacros.txt
index 446896e28..0845cebf5 100644
--- a/doc/manual/trmacros.txt
+++ b/doc/manual/trmacros.txt
@@ -135,7 +135,7 @@ The ``|`` operator
 The ``|`` operator if used as infix operator creates an ordered choice:
 
 .. code-block:: nim
-  template t{0|1}(): expr = 3
+  template t{0|1}(): untyped = 3
   let a = 1
   # outputs 3:
   echo a
@@ -144,7 +144,7 @@ The matching is performed after the compiler performed some optimizations like
 constant folding, so the following does not work:
 
 .. code-block:: nim
-  template t{0|1}(): expr = 3
+  template t{0|1}(): untyped = 3
   # outputs 1:
   echo 1
 
@@ -161,7 +161,7 @@ A pattern expression can be bound to a pattern parameter via the ``expr{param}``
 notation:
 
 .. code-block:: nim
-  template t{(0|1|2){x}}(x: expr): expr = x+1
+  template t{(0|1|2){x}}(x: untyped): untyped = x+1
   let a = 1
   # outputs 2:
   echo a
@@ -173,7 +173,7 @@ The ``~`` operator
 The ``~`` operator is the **not** operator in patterns:
 
 .. code-block:: nim
-  template t{x = (~x){y} and (~x){z}}(x, y, z: bool): stmt =
+  template t{x = (~x){y} and (~x){z}}(x, y, z: bool) =
     x = y
     if x: x = z
 
@@ -200,7 +200,7 @@ to ``&(a, b, c)``:
     for i in 1..len(s)-1: result.add s[i]
     inc calls
 
-  template optConc{ `&&` * a }(a: string): expr = &&a
+  template optConc{ `&&` * a }(a: string): untyped = &&a
 
   let space = " "
   echo "my" && (space & "awe" && "some " ) && "concat"
@@ -239,7 +239,7 @@ all the arguments, but also the matched operators in reverse polish notation:
   proc mat21(): Matrix =
     result.dummy = 21
 
-  macro optM{ (`+`|`-`|`*`) ** a }(a: Matrix): expr =
+  macro optM{ (`+`|`-`|`*`) ** a }(a: Matrix): untyped =
     echo treeRepr(a)
     result = newCall(bindSym"mat21")
 
@@ -273,7 +273,7 @@ parameter is of the type ``varargs`` it is treated specially and it can match
   template optWrite{
     write(f, x)
     ((write|writeLine){w})(f, y)
-  }(x, y: varargs[expr], f: File, w: expr) =
+  }(x, y: varargs[untyped], f: File, w: untyped) =
     w(f, x, y)
 
 
@@ -288,8 +288,8 @@ implemented with term rewriting:
   proc p(x, y: int; cond: bool): int =
     result = if cond: x + y else: x - y
 
-  template optP1{p(x, y, true)}(x, y: expr): expr = x + y
-  template optP2{p(x, y, false)}(x, y: expr): expr = x - y
+  template optP1{p(x, y, true)}(x, y: untyped): untyped = x + y
+  template optP2{p(x, y, false)}(x, y: untyped): untyped = x - y
 
 
 Example: Hoisting
diff --git a/doc/manual/type_rel.txt b/doc/manual/type_rel.txt
index d62cf65c3..5b68f73aa 100644
--- a/doc/manual/type_rel.txt
+++ b/doc/manual/type_rel.txt
@@ -313,42 +313,78 @@ matches better than just ``T`` then.
 Automatic dereferencing
 -----------------------
 
-If the `experimental mode <experimental pragma>`_ is active and no other match
+If the `experimental mode <#pragmas-experimental-pragma>`_ is active and no other match
 is found, the first argument ``a`` is dereferenced automatically if it's a
 pointer type and overloading resolution is tried with ``a[]`` instead.
 
+Automatic self insertions
+-------------------------
 
-Lazy type resolution for expr
------------------------------
+Starting with version 0.14 of the language, Nim supports ``field`` as a
+shortcut for ``self.field`` comparable to the `this`:idx: keyword in Java
+or C++. This feature has to be explicitly enabled via a ``{.this: self.}``
+statement pragma. This pragma is active for the rest of the module:
+
+.. code-block:: nim
+  type
+    Parent = object of RootObj
+      parentField: int
+    Child = object of Parent
+      childField: int
+
+  {.this: self.}
+  proc sumFields(self: Child): int =
+    result = parentField + childField
+    # is rewritten to:
+    # result = self.parentField + self.childField
+
+Instead of ``self`` any other identifier can be used too, but
+``{.this: self.}`` will become the default directive for the whole language
+eventually.
+
+In addition to fields, routine applications are also rewritten, but only
+if no other interpretation of the call is possible:
+
+.. code-block:: nim
+  proc test(self: Child) =
+    echo childField, " ", sumFields()
+    # is rewritten to:
+    echo self.childField, " ", sumFields(self)
+    # but NOT rewritten to:
+    echo self, self.childField, " ", sumFields(self)
+
+
+Lazy type resolution for untyped
+--------------------------------
 
 **Note**: An `unresolved`:idx: expression is an expression for which no symbol
 lookups and no type checking have been performed.
 
 Since templates and macros that are not declared as ``immediate`` participate
 in overloading resolution it's essential to have a way to pass unresolved
-expressions to a template or macro. This is what the meta-type ``expr``
+expressions to a template or macro. This is what the meta-type ``untyped``
 accomplishes:
 
 .. code-block:: nim
-  template rem(x: expr) = discard
+  template rem(x: untyped) = discard
 
   rem unresolvedExpression(undeclaredIdentifier)
 
-A parameter of type ``expr`` always matches any argument (as long as there is
+A parameter of type ``untyped`` always matches any argument (as long as there is
 any argument passed to it).
 
 But one has to watch out because other overloads might trigger the
 argument's resolution:
 
 .. code-block:: nim
-  template rem(x: expr) = discard
+  template rem(x: untyped) = discard
   proc rem[T](x: T) = discard
 
   # undeclared identifier: 'unresolvedExpression'
   rem unresolvedExpression(undeclaredIdentifier)
 
-``expr`` is the only metatype that is lazy in this sense, the other
-metatypes ``stmt`` and ``typedesc`` are not lazy.
+``untyped`` and ``varargs[untyped]`` are the only metatype that are lazy in this sense, the other
+metatypes ``typed`` and ``typedesc`` are not lazy.
 
 
 Varargs matching
diff --git a/doc/manual/typedesc.txt b/doc/manual/typedesc.txt
index de1d84d7d..6922d77e4 100644
--- a/doc/manual/typedesc.txt
+++ b/doc/manual/typedesc.txt
@@ -77,38 +77,6 @@ Once bound, typedesc params can appear in the rest of the proc signature:
 
   declareVariableWithType int, 42
 
-When used with macros and .compileTime. procs on the other hand, the compiler
-does not need to instantiate the code multiple times, because types then can be
-manipulated using the unified internal symbol representation. In such context
-typedesc acts as any other type. One can create variables, store typedesc
-values inside containers and so on. For example, here is how one can create
-a type-safe wrapper for the unsafe `printf` function from C:
-
-.. code-block:: nim
-  macro safePrintF(formatString: string{lit}, args: varargs[expr]): expr =
-    var i = 0
-    for c in formatChars(formatString):
-      var expectedType = case c
-        of 'c': char
-        of 'd', 'i', 'x', 'X': int
-        of 'f', 'e', 'E', 'g', 'G': float
-        of 's': string
-        of 'p': pointer
-        else: EOutOfRange
-
-      var actualType = args[i].getType
-      inc i
-
-      if expectedType == EOutOfRange:
-        error c & " is not a valid format character"
-      elif expectedType != actualType:
-        error "type mismatch for argument ", i, ". expected type: ",
-              expectedType.name, ", actual type: ", actualType.name
-
-    # keep the original callsite, but use cprintf instead
-    result = callsite()
-    result[0] = newIdentNode(!"cprintf")
-
 
 Overload resolution can be further influenced by constraining the set of
 types that will match the typedesc param:
diff --git a/doc/manual/types.txt b/doc/manual/types.txt
index a1596bcea..1e2dc857f 100644
--- a/doc/manual/types.txt
+++ b/doc/manual/types.txt
@@ -435,7 +435,9 @@ has the same type. Arrays always have a fixed length which is specified at
 compile time (except for open arrays). They can be indexed by any ordinal type.
 A parameter ``A`` may be an *open array*, in which case it is indexed by
 integers from 0 to ``len(A)-1``. An array expression may be constructed by the
-array constructor ``[]``.
+array constructor ``[]``. The element type of this array expression is
+inferred from the type of the first element. All other elements need to be
+implicitly convertable to this type.
 
 Sequences are similar to arrays but of dynamic length which may change
 during runtime (like strings). Sequences are implemented as growable arrays,
@@ -460,6 +462,8 @@ Example:
   x = [1, 2, 3, 4, 5, 6]  # [] is the array constructor
   y = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence
 
+  let z = [1.0, 2, 3, 4] # the type of z is array[0..3, float]
+
 The lower bound of an array or sequence may be received by the built-in proc
 ``low()``, the higher bound by ``high()``. The length may be
 received by ``len()``. ``low()`` for a sequence or an open array always returns
@@ -539,12 +543,12 @@ not wrapped in another implicit array construction:
   takeV([123, 2, 1]) # takeV's T is "int", not "array of int"
 
 
-``varargs[expr]`` is treated specially: It matches a variable list of arguments
+``varargs[typed]`` is treated specially: It matches a variable list of arguments
 of arbitrary type but *always* constructs an implicit array. This is required
 so that the builtin ``echo`` proc does what is expected:
 
 .. code-block:: nim
-  proc echo*(x: varargs[expr, `$`]) {...}
+  proc echo*(x: varargs[typed, `$`]) {...}
 
   echo @[1, 2, 3]
   # prints "@[1, 2, 3]" and not "123"
@@ -694,7 +698,7 @@ branch switch ``system.reset`` has to be used.
 Set type
 --------
 
-.. include:: sets_fragment.txt
+.. include:: ../sets_fragment.txt
 
 Reference and pointer types
 ---------------------------
@@ -1082,7 +1086,7 @@ But it seems all this boilerplate code needs to be repeated for the ``Euro``
 currency. This can be solved with templates_.
 
 .. code-block:: nim
-  template additive(typ: typedesc): stmt =
+  template additive(typ: typedesc) =
     proc `+` *(x, y: typ): typ {.borrow.}
     proc `-` *(x, y: typ): typ {.borrow.}
 
@@ -1090,18 +1094,18 @@ currency. This can be solved with templates_.
     proc `+` *(x: typ): typ {.borrow.}
     proc `-` *(x: typ): typ {.borrow.}
 
-  template multiplicative(typ, base: typedesc): stmt =
+  template multiplicative(typ, base: typedesc) =
     proc `*` *(x: typ, y: base): typ {.borrow.}
     proc `*` *(x: base, y: typ): typ {.borrow.}
     proc `div` *(x: typ, y: base): typ {.borrow.}
     proc `mod` *(x: typ, y: base): typ {.borrow.}
 
-  template comparable(typ: typedesc): stmt =
+  template comparable(typ: typedesc) =
     proc `<` * (x, y: typ): bool {.borrow.}
     proc `<=` * (x, y: typ): bool {.borrow.}
     proc `==` * (x, y: typ): bool {.borrow.}
 
-  template defineCurrency(typ, base: expr): stmt =
+  template defineCurrency(typ, base: untyped) =
     type
       typ* = distinct base
     additive(typ)