summary refs log tree commit diff stats
path: root/doc/tut1.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/tut1.rst')
-rw-r--r--doc/tut1.rst123
1 files changed, 74 insertions, 49 deletions
diff --git a/doc/tut1.rst b/doc/tut1.rst
index be5cd8c11..9e6f1ab3c 100644
--- a/doc/tut1.rst
+++ b/doc/tut1.rst
@@ -30,6 +30,7 @@ The first program
 We start the tour with a modified "hello world" program:
 
 .. code-block:: Nim
+    :test: "nim c $1"
   # This is a comment
   echo "What's your name? "
   var name: string = readLine(stdin)
@@ -72,6 +73,7 @@ you can leave out the type in the declaration (this is called `local type
 inference`:idx:). So this will work too:
 
 .. code-block:: Nim
+    :test: "nim c $1"
   var name = readLine(stdin)
 
 Note that this is basically the only form of type inference that exists in
@@ -116,6 +118,7 @@ Comments start anywhere outside a string or character literal with the
 hash character ``#``. Documentation comments start with ``##``:
 
 .. code-block:: nim
+    :test: "nim c $1"
   # A comment.
 
   var myVariable: int ## a documentation comment
@@ -129,6 +132,7 @@ Multiline comments are started with ``#[`` and terminated with ``]#``.  Multilin
 comments can also be nested.
 
 .. code-block:: nim
+    :test: "nim c $1"
   #[
   You can have any Nim code text commented
   out inside this with no indentation restrictions.
@@ -142,6 +146,7 @@ You can also use the `discard statement <#procedures-discard-statement>`_ togeth
 literals* to create block comments:
 
 .. code-block:: nim
+    :test: "nim c $1"
   discard """ You can have any Nim code text commented
   out inside this with no indentation restrictions.
         yes("May I ask a pointless question?") """
@@ -169,6 +174,7 @@ Indentation can be used after the ``var`` keyword to list a whole section of
 variables:
 
 .. code-block::
+    :test: "nim c $1"
   var
     x, y: int
     # a comment can occur here too
@@ -186,10 +192,11 @@ to a storage location:
   x = "xyz"     # assigns a new value to `x`
 
 ``=`` is the *assignment operator*. The assignment operator can be
-overloaded. You can declare multiple variables with a single assignment 
+overloaded. You can declare multiple variables with a single assignment
 statement and all the variables will have the same value:
 
 .. code-block::
+    :test: "nim c $1"
   var x, y = 3  # assigns 3 to the variables `x` and `y`
   echo "x ", x  # outputs "x 3"
   echo "y ", y  # outputs "y 3"
@@ -212,12 +219,14 @@ cannot change. The compiler must be able to evaluate the expression in a
 constant declaration at compile time:
 
 .. code-block:: nim
+    :test: "nim c $1"
   const x = "abc" # the constant x contains the string "abc"
 
 Indentation can be used after the ``const`` keyword to list a whole section of
 constants:
 
 .. code-block::
+    :test: "nim c $1"
   const
     x = 1
     # a comment can occur here too
@@ -243,6 +252,7 @@ and put it into a data section":
   const input = readLine(stdin) # Error: constant expression expected
 
 .. code-block::
+    :test: "nim c $1"
   let input = readLine(stdin)   # works
 
 
@@ -260,6 +270,7 @@ If statement
 The if statement is one way to branch the control flow:
 
 .. code-block:: nim
+    :test: "nim c $1"
   let name = readLine(stdin)
   if name == "":
     echo "Poor soul, you lost your name?"
@@ -281,6 +292,7 @@ Another way to branch is provided by the case statement. A case statement is
 a multi-branch:
 
 .. code-block:: nim
+    :test: "nim c $1"
   let name = readLine(stdin)
   case name
   of "":
@@ -338,6 +350,7 @@ While statement
 The while statement is a simple looping construct:
 
 .. code-block:: nim
+    :test: "nim c $1"
 
   echo "What's your name? "
   var name = readLine(stdin)
@@ -358,6 +371,7 @@ provides. The example uses the built-in `countup <system.html#countup>`_
 iterator:
 
 .. code-block:: nim
+    :test: "nim c $1"
   echo "Counting to ten: "
   for i in countup(1, 10):
     echo i
@@ -409,6 +423,7 @@ Other useful iterators for collections (like arrays and sequences) are
 * ``pairs`` and ``mpairs`` which provides the element and an index number (immutable and mutable respectively)
 
 .. code-block:: nim
+    :test: "nim c $1"
   for index, item in ["a","b"].pairs:
     echo item, " at index ", index
   # => a at index 0
@@ -421,6 +436,8 @@ new scope. This means that in the following example, ``x`` is not accessible
 outside the loop:
 
 .. code-block:: nim
+    :test: "nim c $1"
+    :status: 1
   while false:
     var x = "hi"
   echo x # does not work
@@ -430,6 +447,8 @@ are only visible within the block they have been declared. The ``block``
 statement can be used to open a new block explicitly:
 
 .. code-block:: nim
+    :test: "nim c $1"
+    :status: 1
   block myblock:
     var x = "hi"
   echo x # does not work either
@@ -444,6 +463,7 @@ can leave a ``while``, ``for``, or a ``block`` statement. It leaves the
 innermost construct, unless a label of a block is given:
 
 .. code-block:: nim
+    :test: "nim c $1"
   block myblock:
     echo "entering block"
     while true:
@@ -465,6 +485,7 @@ Like in many other programming languages, a ``continue`` statement starts
 the next iteration immediately:
 
 .. code-block:: nim
+    :test: "nim c $1"
   while true:
     let x = readLine(stdin)
     if x == "": continue
@@ -477,6 +498,7 @@ When statement
 Example:
 
 .. code-block:: nim
+    :test: "nim c $1"
 
   when system.hostOS == "windows":
     echo "running on Windows!"
@@ -549,6 +571,7 @@ an expression is allowed:
 
 .. code-block:: nim
   # computes fac(4) at compile time:
+    :test: "nim c $1"
   const fac4 = (var x = 1; for i in 1..4: x *= i; x)
 
 
@@ -561,6 +584,7 @@ is needed. (Some languages call them *methods* or *functions*.) In Nim new
 procedures are defined with the ``proc`` keyword:
 
 .. code-block:: nim
+    :test: "nim c $1"
   proc yes(question: string): bool =
     echo question, " (y/n)"
     while true:
@@ -597,6 +621,7 @@ automatically at the end of a procedure if there is no ``return`` statement at
 the exit.
 
 .. code-block:: nim
+    :test: "nim c $1"
   proc sumTillNegative(x: varargs[int]): int =
     for i in x:
       if i < 0:
@@ -624,6 +649,7 @@ to be declared with ``var`` in the procedure body. Shadowing the parameter name
 is possible, and actually an idiom:
 
 .. code-block:: nim
+    :test: "nim c $1"
   proc printSeq(s: seq, nprinted: int = -1) =
     var nprinted = if nprinted == -1: s.len else: min(nprinted, s.len)
     for i in 0 .. <nprinted:
@@ -633,6 +659,7 @@ If the procedure needs to modify the argument for the
 caller, a ``var`` parameter can be used:
 
 .. code-block:: nim
+    :test: "nim c $1"
   proc divmod(a, b: int; res, remainder: var int) =
     res = a div b        # integer division
     remainder = a mod b  # integer modulo operation
@@ -663,6 +690,7 @@ The return value can be ignored implicitly if the called proc/iterator has
 been declared with the ``discardable`` pragma:
 
 .. code-block:: nim
+    :test: "nim c $1"
   proc p(x, y: int): int {.discardable.} =
     return x + y
 
@@ -772,6 +800,7 @@ The "``" notation can also be used to call an operator just like any other
 procedure:
 
 .. code-block:: nim
+    :test: "nim c $1"
   if `==`( `+`(3, 4), 7): echo "True"
 
 
@@ -819,6 +848,7 @@ Iterators
 Let's return to the simple counting example:
 
 .. code-block:: nim
+    :test: "nim c $1"
   echo "Counting to ten: "
   for i in countup(1, 10):
     echo i
@@ -840,6 +870,7 @@ the only thing left to do is to replace the ``proc`` keyword by ``iterator``
 and here it is - our first iterator:
 
 .. code-block:: nim
+    :test: "nim c $1"
   iterator countup(a, b: int): int =
     var res = a
     while res <= b:
@@ -894,7 +925,8 @@ evaluation. For example:
 Characters
 ----------
 The `character type` is called ``char``. Its size is always one byte, so
-it cannot represent most UTF-8 characters; but it *can* represent one of the bytes that makes up a multi-byte UTF-8 character.
+it cannot represent most UTF-8 characters; but it *can* represent one of the bytes
+that makes up a multi-byte UTF-8 character.
 The reason for this is efficiency: for the overwhelming majority of use-cases,
 the resulting programs will still handle UTF-8 properly as UTF-8 was specially
 designed for this.
@@ -945,6 +977,7 @@ to specify a non-default integer type:
 
 
 .. code-block:: nim
+    :test: "nim c $1"
   let
     x = 0     # x is of type ``int``
     y = 0'i8  # y is of type ``int8``
@@ -981,6 +1014,7 @@ Float literals can have a *type suffix* to specify a non-default float
 type:
 
 .. code-block:: nim
+    :test: "nim c $1"
   var
     x = 0.0      # x is of type ``float``
     y = 0.0'f32  # y is of type ``float32``
@@ -1002,6 +1036,7 @@ Conversion between basic types is performed by using the
 type as a function:
 
 .. code-block:: nim
+    :test: "nim c $1"
   var
     x: int32 = 1.int32   # same as calling int32(1)
     y: int8  = int8('a') # 'a' == 97'i8
@@ -1023,6 +1058,7 @@ graphs with cycles. The following example shows that even for basic types
 there is a difference between the ``$`` and ``repr`` outputs:
 
 .. code-block:: nim
+    :test: "nim c $1"
   var
     myBool = true
     myCharacter = 'n'
@@ -1047,6 +1083,7 @@ Advanced types
 In Nim new types can be defined within a ``type`` statement:
 
 .. code-block:: nim
+    :test: "nim c $1"
   type
     biggestInt = int64      # biggest integer type that is available
     biggestFloat = float64  # biggest float type that is available
@@ -1063,6 +1100,7 @@ to an integer value internally. The first symbol is represented
 at runtime by 0, the second by 1 and so on. For example:
 
 .. code-block:: nim
+    :test: "nim c $1"
 
   type
     Direction = enum
@@ -1087,6 +1125,7 @@ explicitly given is assigned the value of the previous symbol + 1.
 An explicit ordered enum can have *holes*:
 
 .. code-block:: nim
+    :test: "nim c $1"
   type
     MyEnum = enum
       a = 2, b = 4, c = 89
@@ -1125,6 +1164,7 @@ A subrange type is a range of values from an integer or enumeration type
 (the base type). Example:
 
 .. code-block:: nim
+    :test: "nim c $1"
   type
     MySubrange = range[0..5]
 
@@ -1155,6 +1195,7 @@ an array has the same type. The array's index type can be any ordinal type.
 Arrays can be constructed using ``[]``:
 
 .. code-block:: nim
+    :test: "nim c $1"
 
   type
     IntArray = array[0..5, int] # an array that is indexed with 0..5
@@ -1177,6 +1218,7 @@ length. `low(a) <system.html#low>`_ returns the lowest valid index for the
 array `a` and `high(a) <system.html#high>`_ the highest valid index.
 
 .. code-block:: nim
+    :test: "nim c $1"
   type
     Direction = enum
       north, east, south, west
@@ -1228,6 +1270,7 @@ It is quite common to have arrays start at zero, so there's a shortcut syntax
 to specify a range from zero to the specified index minus one:
 
 .. code-block:: nim
+    :test: "nim c $1"
   type
     IntArray = array[0..5, int] # an array that is indexed with 0..5
     QuickArray = array[6, int]  # an array that is indexed with 0..5
@@ -1260,6 +1303,7 @@ A sequence may be passed to an openarray parameter.
 Example:
 
 .. code-block:: nim
+    :test: "nim c $1"
 
   var
     x: seq[int] # a reference to a sequence of integers
@@ -1282,6 +1326,7 @@ value. Here the ``for`` statement is looping over the results from the
 <system.html>`_ module.  Examples:
 
 .. code-block:: nim
+    :test: "nim c $1"
   for value in @[3, 4, 5]:
     echo value
   # --> 3
@@ -1308,6 +1353,7 @@ with a compatible base type can be passed to an openarray parameter, the index
 type does not matter.
 
 .. code-block:: nim
+    :test: "nim c $1"
   var
     fruits:   seq[string]       # reference to a sequence of strings that is initialized with 'nil'
     capitals: array[3, string]  # array of strings with a fixed size
@@ -1337,6 +1383,7 @@ arguments to a procedure. The compiler converts the list of arguments
 to an array automatically:
 
 .. code-block:: nim
+    :test: "nim c $1"
   proc myWriteln(f: File, a: varargs[string]) =
     for s in items(a):
       write(f, s)
@@ -1351,6 +1398,7 @@ last parameter in the procedure header. It is also possible to perform
 type conversions in this context:
 
 .. code-block:: nim
+    :test: "nim c $1"
   proc myWriteln(f: File, a: varargs[string, `$`]) =
     for s in items(a):
       write(f, s)
@@ -1374,6 +1422,7 @@ context. A slice is just an object of type Slice which contains two bounds,
 define operators which accept Slice objects to define ranges.
 
 .. code-block:: nim
+    :test: "nim c $1"
 
   var
     a = "Nim is a progamming language"
@@ -1388,27 +1437,31 @@ slice's bounds can hold any value supported by
 their type, but it is the proc using the slice object which defines what values
 are accepted.
 
- To understand some of the different ways of specifying the indices of strings, arrays, sequences, etc.,
- it must be remembered that Nim uses zero-based indices.
+To understand some of the different ways of specifying the indices of
+strings, arrays, sequences, etc., it must be remembered that Nim uses
+zero-based indices.
 
- So the string ``b`` is of length 19, and two different ways of specifying the indices are
+So the string ``b`` is of length 19, and two different ways of specifying the
+indices are
 
- .. code-block:: nim
+.. code-block:: nim
 
   "Slices are useless."
    |          |     |
    0         11    17   using indices
   ^19        ^8    ^2   using ^ syntax
 
- where ``b[0..^1]`` is equivalent to ``b[0..b.len-1]`` and ``b[0..<b.len]``, and it can be seen that the ``^1`` provides a short-hand way of specifying the ``b.len-1``
+where ``b[0..^1]`` is equivalent to ``b[0..b.len-1]`` and ``b[0..<b.len]``, and it
+can be seen that the ``^1`` provides a short-hand way of specifying the ``b.len-1``.
 
- In the above example, because the string ends in a period, to get the portion of the string that is "useless" and replace it with "useful"
+In the above example, because the string ends in a period, to get the portion of the
+string that is "useless" and replace it with "useful".
 
- ``b[11..^2]`` is the portion "useless", and
- ``b[11..^2] = "useful"`` replaces the "useless" portion with "useful",
- giving the result "Slices are useful."
+``b[11..^2]`` is the portion "useless", and ``b[11..^2] = "useful"`` replaces the
+"useless" portion with "useful", giving the result "Slices are useful."
 
- Note: alternate ways of writing this are ``b[^8..^2] = "useful"`` or as ``b[11..b.len-2] = "useful"`` or as ``b[11..<b.len-1] = "useful"`` or as ....
+Note: alternate ways of writing this are ``b[^8..^2] = "useful"`` or
+as ``b[11..b.len-2] = "useful"`` or as ``b[11..<b.len-1] = "useful"``.
 
 Tuples
 ------
@@ -1425,6 +1478,7 @@ The assignment operator for tuples copies each component. The notation
 integer.
 
 .. code-block:: nim
+    :test: "nim c $1"
 
   type
     Person = tuple[name: string, age: int] # type representing a person:
@@ -1470,6 +1524,7 @@ otherwise you will be assigning the same value to all the individual
 variables! For example:
 
 .. code-block:: nim
+    :test: "nim c $1"
 
   import os
 
@@ -1509,10 +1564,10 @@ tuple/object field operator) and ``[]`` (array/string/sequence index operator)
 operators perform implicit dereferencing operations for reference types:
 
 .. code-block:: nim
+    :test: "nim c $1"
 
   type
-    Node = ref NodeObj
-    NodeObj = object
+    Node = ref object
       le, ri: Node
       data: int
   var
@@ -1539,6 +1594,7 @@ techniques.
 Example:
 
 .. code-block:: nim
+    :test: "nim c $1"
   proc echoItem(x: int) = echo x
 
   proc forEach(action: proc (x: int)) =
@@ -1556,9 +1612,11 @@ listed in the `manual <manual.html#types-procedural-type>`_.
 
 Distinct type
 -------------
-A Distinct type allows for the creation of new type that "does not imply a subtype relationship between it and its base type".
+A Distinct type allows for the creation of new type that "does not imply a
+subtype relationship between it and its base type".
 You must **explicitly** define all behaviour for the distinct type.
-To help with this, both the distinct type and its base type can cast from one type to the other.
+To help with this, both the distinct type and its base type can cast from one
+type to the other.
 Examples are provided in the `manual <manual.html#types-distinct-type>`_.
 
 Modules
@@ -1593,39 +1651,6 @@ Each module has a special magic constant ``isMainModule`` that is true if the
 module is compiled as the main file. This is very useful to embed tests within
 the module as shown by the above example.
 
-Modules that depend on each other are possible, but strongly discouraged,
-because then one module cannot be reused without the other.
-
-The algorithm for compiling modules is:
-
-- Compile the whole module as usual, following import statements recursively.
-- If there is a cycle only import the already parsed symbols (that are
-  exported); if an unknown identifier occurs then abort.
-
-This is best illustrated by an example:
-
-.. code-block:: nim
-  # Module A
-  type
-    T1* = int  # Module A exports the type ``T1``
-  import B     # the compiler starts parsing B
-
-  proc main() =
-    var i = p(3) # works because B has been parsed completely here
-
-  main()
-
-.. code-block:: nim
-  # Module B
-  import A  # A is not parsed here! Only the already known symbols
-            # of A are imported.
-
-  proc p*(x: A.T1): A.T1 =
-    # this works because the compiler has already
-    # added T1 to A's interface symbol table
-    result = x + 1
-
-
 A symbol of a module *can* be *qualified* with the ``module.symbol`` syntax. And if
 a symbol is ambiguous, it *must* be qualified. A symbol is ambiguous
 if it is defined in two (or more) different modules and both modules are