summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorMiran <narimiran@disroot.org>2021-05-05 07:44:33 +0200
committerGitHub <noreply@github.com>2021-05-05 07:44:33 +0200
commit94c4c01d9c2a8f78d63533c147afd42f05b21627 (patch)
treebe9b1725c884c5c30131f849887608de628d6256
parent15d95669526ea0b93f9d773773c444f66b8a788a (diff)
downloadNim-94c4c01d9c2a8f78d63533c147afd42f05b21627.tar.gz
small improvements for tut1.rst (#17935)
* small improvements for tut1.rst
* remove unneeded paragraph
* Update doc/tut1.rst

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
-rw-r--r--doc/sets_fragment.txt3
-rw-r--r--doc/tut1.rst177
2 files changed, 101 insertions, 79 deletions
diff --git a/doc/sets_fragment.txt b/doc/sets_fragment.txt
index 84e2fe8c1..d2e1f96f6 100644
--- a/doc/sets_fragment.txt
+++ b/doc/sets_fragment.txt
@@ -17,6 +17,9 @@ Attempting to declare a set with a larger type will result in an error:
 
   var s: set[int64] # Error: set is too large
 
+**Note:** Nim also offers `hash sets <sets.html>`_ (which you need to import
+with `import sets`), which have no such restrictions.
+
 Sets can be constructed via the set constructor: `{}` is the empty set. The
 empty set is type compatible with any concrete set type. The constructor
 can also be used to include elements (and ranges of elements):
diff --git a/doc/tut1.rst b/doc/tut1.rst
index 8d80a0520..2f19ae173 100644
--- a/doc/tut1.rst
+++ b/doc/tut1.rst
@@ -22,10 +22,14 @@ This document is a tutorial for the programming language *Nim*.
 
 This tutorial assumes that you are familiar with basic programming concepts
 like variables, types, or statements.
-If you would like to have a gentle introduction of those concepts, we recommend
-`Nim Basics tutorial <https://narimiran.github.io/nim-basics/>`_.
-On the other hand, the `manual <manual.html>`_ contains many more examples of
-the advanced language features.
+
+Here are several other resources for learning Nim:
+
+* `Nim Basics tutorial <https://narimiran.github.io/nim-basics/>`_ - a gentle 
+  introduction of the concepts mentioned above
+* `Learn Nim in 5 minutes <https://learnxinyminutes.com/docs/nim/>`_ - quick,
+  five-minute introduction to Nim
+* `The Nim manual <manual.html>`_ - many more examples of the advanced language features
 
 All code examples in this tutorial, as well as the ones found in the rest of
 Nim's documentation, follow the `Nim style guide <nep1.html>`_.
@@ -58,6 +62,7 @@ Commonly used commands and switches have abbreviations, so you can also use::
 
   nim c -r greetings.nim
 
+This is a **debug version**.
 To compile a release version use::
 
   nim c -d:release greetings.nim
@@ -119,7 +124,7 @@ In raw literals, the backslash is not an escape character.
 
 The third and last way to write string literals is *long-string literals*.
 They are written with three quotes: `""" ... """`; they can span over
-multiple lines and the ``\\`` is not an escape character either. They are very
+multiple lines and the ``\`` is not an escape character either. They are very
 useful for embedding HTML code templates for example.
 
 
@@ -184,37 +189,6 @@ variables:
     a, b, c: string
 
 
-The assignment statement
-========================
-
-The assignment statement assigns a new value to a variable or more generally
-to a storage location:
-
-.. code-block::
-  var x = "abc" # introduces a new variable `x` and assigns a value to it
-  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
-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"
-  x = 42        # changes `x` to 42 without changing `y`
-  echo "x ", x  # outputs "x 42"
-  echo "y ", y  # outputs "y 3"
-
-Note that declaring multiple variables with a single assignment that calls a
-procedure can have unexpected results: the compiler will *unroll* the
-assignments and end up calling the procedure several times. If the result of
-the procedure depends on side effects, your variables may end up having
-different values! For safety use side-effect-free procedures if making multiple
-assignments.
-
-
 Constants
 =========
 
@@ -260,6 +234,30 @@ and put it into a data section":
   let input = readLine(stdin)   # works
 
 
+The assignment statement
+========================
+
+The assignment statement assigns a new value to a variable or more generally
+to a storage location:
+
+.. code-block::
+  var x = "abc" # introduces a new variable `x` and assigns a value to it
+  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
+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"
+  x = 42        # changes `x` to 42 without changing `y`
+  echo "x ", x  # outputs "x 42"
+  echo "y ", y  # outputs "y 3"
+
+
 Control flow statements
 =======================
 
@@ -325,7 +323,7 @@ For integers or other ordinal types value ranges are also possible:
   of 0..2, 4..7: echo "The number is in the set: {0, 1, 2, 4, 5, 6, 7}"
   of 3, 8: echo "The number is 3 or 8"
 
-However, the above code does not compile: the reason is that you have to cover
+However, the above code **does not compile**: the reason is that you have to cover
 every value that `n` may contain, but the code only handles the values
 `0..8`. Since it is not very practical to list every other possible integer
 (though it is possible thanks to the range notation), we fix this by telling
@@ -361,8 +359,7 @@ The while statement is a simple looping construct:
   var name = readLine(stdin)
   while name == "":
     echo "Please tell me your name: "
-    name = readLine(stdin)
-    # no `var`, because we do not declare a new variable here
+    name = readLine(stdin) # no `var`, because we do not declare a new variable here
 
 The example uses a while loop to keep asking the users for their name, as long
 as the user types in nothing (only presses RETURN).
@@ -392,9 +389,16 @@ The variable `i` is implicitly declared by the
   var i = 1
   while i <= 10:
     echo i
-    inc(i) # increment i by 1
+    inc i # increment i by 1
   # --> Outputs 1 2 3 4 5 6 7 8 9 10 on different lines
 
+Since counting up occurs so often in programs, Nim also has a `..
+<system.html#...i,T,T>`_ iterator that does the same:
+
+.. code-block:: nim
+  for i in 1 .. 10:
+    ...
+
 Counting down can be achieved as easily (but is less often needed):
 
 .. code-block:: nim
@@ -403,20 +407,13 @@ Counting down can be achieved as easily (but is less often needed):
     echo i
   # --> Outputs 10 9 8 7 6 5 4 3 2 1 on different lines
 
-Since counting up occurs so often in programs, Nim also has a `..
-<system.html#...i,T,T>`_ iterator that does the same:
-
-.. code-block:: nim
-  for i in 1 .. 10:
-    ...
-
 Zero-indexed counting has two shortcuts `..<` and `.. ^1`
 (`backward index operator <system.html#^.t%2Cint>`_) to simplify
 counting to one less than the higher index:
 
 .. code-block:: nim
   for i in 0 ..< 10:
-    ...  # 0 .. 9
+    ...  # the same as 0 .. 9
 
 or
 
@@ -430,7 +427,7 @@ or
 .. code-block:: nim
   var s = "some string"
   for idx, c in s[0 .. ^1]:
-    ...
+    ... # ^1 is the last element, ^2 would be one before it, and so on
 
 Other useful iterators for collections (like arrays and sequences) are
 * `items` and `mitems`, which provides immutable and mutable elements respectively, and
@@ -445,6 +442,7 @@ Other useful iterators for collections (like arrays and sequences) are
 
 Scopes and the block statement
 ------------------------------
+
 Control flow statements have a feature not covered yet: they open a
 new scope. This means that in the following example, `x` is not accessible
 outside the loop:
@@ -472,6 +470,7 @@ The block's *label* (`myblock` in the example) is optional.
 
 Break statement
 ---------------
+
 A block can be left prematurely with a `break` statement. The break statement
 can leave a `while`, `for`, or a `block` statement. It leaves the
 innermost construct, unless a label of a block is given:
@@ -497,15 +496,15 @@ innermost construct, unless a label of a block is given:
 
 Continue statement
 ------------------
+
 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
-    echo x
+  for i in 1 .. 5:
+    if i <= 3: continue
+    echo i # will only print 4 and 5
 
 
 When statement
@@ -630,6 +629,7 @@ Some terminology: in the example `question` is called a (formal) *parameter*,
 
 Result variable
 ---------------
+
 A procedure that returns a value has an implicit `result` variable declared
 that represents the return value. A `return` statement with no expression is
 shorthand for `return result`. The `result` value is always returned
@@ -644,9 +644,9 @@ the exit.
         return
       result = result + i
 
-  echo sumTillNegative() # echos 0
-  echo sumTillNegative(3, 4, 5) # echos 12
-  echo sumTillNegative(3, 4 , -1 , 6) # echos 7
+  echo sumTillNegative() # echoes 0
+  echo sumTillNegative(3, 4, 5) # echoes 12
+  echo sumTillNegative(3, 4 , -1 , 6) # echoes 7
 
 The `result` variable is already implicitly declared at the start of the
 function, so declaring it again with 'var result', for example, would shadow it
@@ -662,12 +662,13 @@ this procedure
 .. code-block:: nim
     :test: "nim c $1"
   proc helloWorld(): string =
-      "Hello, World!"
+    "Hello, World!"
 
 returns the string "Hello, World!".
 
 Parameters
 ----------
+
 Parameters are immutable in the procedure body. By default, their value cannot be
 changed because this allows the compiler to implement parameter passing in the
 most efficient way. If a mutable variable is needed inside the procedure, it has
@@ -704,6 +705,7 @@ a tuple as a return value instead of using var parameters.
 
 Discard statement
 -----------------
+
 To call a procedure that returns a value just for its side effects and ignoring
 its return value, a `discard` statement **must** be used. Nim does not
 allow silently throwing away a return value:
@@ -752,6 +754,7 @@ The compiler checks that each parameter receives exactly one argument.
 
 Default values
 --------------
+
 To make the `createWindow` proc easier to use it should provide `default
 values`; these are values that are used as arguments if the caller does not
 specify them:
@@ -773,6 +776,7 @@ no need to write `title: string = "unknown"`, for example.
 
 Overloaded procedures
 ---------------------
+
 Nim provides the ability to overload procedures similar to C++:
 
 .. code-block:: nim
@@ -793,14 +797,13 @@ Nim provides the ability to overload procedures similar to C++:
 (Note that `toString` is usually the `$ <dollars.html>`_ operator in
 Nim.) The compiler chooses the most appropriate proc for the `toString`
 calls. How this overloading resolution algorithm works exactly is not
-discussed here (it will be specified in the manual soon).  However, it does
-not lead to nasty surprises and is based on a quite simple unification
-algorithm. Ambiguous calls are reported as errors.
+discussed here -- see the manual for details. Ambiguous calls are reported as errors.
 
 
 Operators
 ---------
-The Nim library makes heavy use of overloading - one reason for this is that
+
+The Nim standard library makes heavy use of overloading - one reason for this is that
 each operator like `+` is just an overloaded proc. The parser lets you
 use operators in *infix notation* (`a + b`) or *prefix notation* (`+ a`).
 An infix operator always receives two arguments, a prefix operator always one.
@@ -816,7 +819,7 @@ User-defined operators are allowed. Nothing stops you from defining your own
 `@!?+~` operator, but doing so may reduce readability.
 
 The operator's precedence is determined by its first character. The details
-can be found in the manual.
+can be `found in the manual <manual.html#syntax-precedence>`_.
 
 To define a new operator enclose the operator in backticks "`":
 
@@ -830,7 +833,7 @@ procedure:
 
 .. code-block:: nim
     :test: "nim c $1"
-  if `==`( `+`(3, 4), 7): echo "True"
+  if `==`( `+`(3, 4), 7): echo "true"
 
 
 Forward declarations
@@ -896,7 +899,7 @@ However, this does not work. The problem is that the procedure should not
 only `return`, but return and **continue** after an iteration has
 finished. This *return and continue* is called a `yield` statement. Now
 the only thing left to do is to replace the `proc` keyword by `iterator`
-and here it is - our first iterator:
+and here it is -- our first iterator:
 
 .. code-block:: nim
     :test: "nim c $1"
@@ -914,10 +917,10 @@ important differences:
   `yield` statement).
 * Iterators have no implicit `result` variable.
 * Iterators do not support recursion.
-* Iterators cannot be forward declared, because the compiler must be able to inline an iterator. (This restriction will be gone in a
-  future version of the compiler.)
+* Iterators cannot be forward declared, because the compiler must be able to inline an iterator.
+  (This restriction will be gone in a future version of the compiler.)
 
-However, you can also use a `closure` iterator to get a different set of
+However, you can also use a closure iterator to get a different set of
 restrictions. See `first-class iterators <manual.html#iterators-and-the-for-statement-firstminusclass-iterators>`_
 for details. Iterators can have the same name and parameters as a proc since
 essentially they have their own namespaces. Therefore it is common practice to
@@ -952,6 +955,7 @@ 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.
@@ -968,6 +972,7 @@ Converting from an integer to a `char` is done with the `chr` proc.
 
 Strings
 -------
+
 String variables are **mutable**, so appending to a string
 is possible, and quite efficient. Strings in Nim are both zero-terminated and have a
 length field. A string's length can be retrieved with the builtin `len`
@@ -989,6 +994,7 @@ A string variable is initialized with the empty string `""`.
 
 Integers
 --------
+
 Nim has these integer types built-in:
 `int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64`.
 
@@ -1001,7 +1007,7 @@ to specify a non-default integer type:
   let
     x = 0     # x is of type `int`
     y = 0'i8  # y is of type `int8`
-    z = 0'i64 # z is of type `int64`
+    z = 0'i32 # z is of type `int32`
     u = 0'u   # u is of type `uint`
 
 Most often integers are used for counting objects that reside in memory, so
@@ -1019,12 +1025,13 @@ errors.
 
 Lossless `Automatic type conversion`:idx: is performed in expressions where different
 kinds of integer types are used. However, if the type conversion
-would cause loss of information, the `EOutOfRange`:idx: exception is raised (if the error
+would cause loss of information, the ``RangeDefect``:idx: is raised (if the error
 cannot be detected at compile time).
 
 
 Floats
 ------
+
 Nim has these floating-point types built-in: `float float32 float64`.
 
 The default float type is `float`. In the current implementation,
@@ -1051,6 +1058,7 @@ versa. Use the `toInt <system.html#toInt,float>`_ and
 
 Type Conversion
 ---------------
+
 Conversion between numerical types is performed by using the
 type as a function:
 
@@ -1093,7 +1101,7 @@ there is a difference between the `$` and `repr` outputs:
   echo myInteger, ":", repr(myInteger)
   # --> 42:42
   echo myFloat, ":", repr(myFloat)
-  # --> 3.1400000000000001e+00:3.1400000000000001e+00
+  # --> 3.14:3.14
 
 
 Advanced types
@@ -1113,6 +1121,7 @@ Enumeration and object types may only be defined within a
 
 Enumerations
 ------------
+
 A variable of an enumeration type can only be assigned one of the enumeration's specified values.
 These values are a set of ordered symbols. Each symbol is mapped
 to an integer value internally. The first symbol is represented
@@ -1126,7 +1135,7 @@ at runtime by 0, the second by 1, and so on. For example:
       north, east, south, west
 
   var x = south     # `x` is of type `Direction`; its value is `south`
-  echo x            # writes "south" to `stdout`
+  echo x            # prints "south"
 
 All the comparison operators can be used with enumeration types.
 
@@ -1143,6 +1152,7 @@ must be in ascending order.
 
 Ordinal types
 -------------
+
 Enumerations, integer types, `char` and `bool` (and
 subranges) are called ordinal types. Ordinal types have quite
 a few special operations:
@@ -1166,12 +1176,13 @@ Operation             Comment
 
 The `inc <system.html#inc,T,int>`_, `dec <system.html#dec,T,int>`_, `succ
 <system.html#succ,T,int>`_ and `pred <system.html#pred,T,int>`_ operations can
-fail by raising an `EOutOfRange` or `EOverflow` exception. (If the code has been
+fail by raising an `RangeDefect` or `OverflowDefect`. (If the code has been
 compiled with the proper runtime checks turned on.)
 
 
 Subranges
 ---------
+
 A subrange type is a range of values from an integer or enumeration type
 (the base type). Example:
 
@@ -1201,6 +1212,7 @@ Sets
 
 Arrays
 ------
+
 An array is a simple fixed-length container. Each element in
 an array has the same type. The array's index type can be any ordinal type.
 
@@ -1214,7 +1226,7 @@ Arrays can be constructed using `[]`:
   var
     x: IntArray
   x = [1, 2, 3, 4, 5, 6]
-  for i in low(x)..high(x):
+  for i in low(x) .. high(x):
     echo x[i]
 
 The notation `x[i]` is used to access the i-th element of `x`.
@@ -1243,7 +1255,7 @@ valid index.
   level[north] = on
   level[south] = slowBlink
   level[east] = fastBlink
-  echo repr(level)  # --> [on, fastBlink, slowBlink, off]
+  echo level        # --> [on, fastBlink, slowBlink, off]
   echo low(level)   # --> north
   echo len(level)   # --> 4
   echo high(level)  # --> west
@@ -1265,7 +1277,7 @@ subdivided into height levels accessed through their integer index:
   tower[1][east] = mediumBlink
   echo len(tower)     # --> 10
   echo len(tower[1])  # --> 4
-  echo repr(tower)    # --> [[slowBlink, mediumBlink, ...more output..
+  echo tower          # --> [[slowBlink, mediumBlink, ...more output..
   # The following lines don't compile due to type mismatch errors
   #tower[north][east] = on
   #tower[0][1] = on
@@ -1292,12 +1304,13 @@ to specify a range from zero to the specified index minus one:
     y: QuickArray
   x = [1, 2, 3, 4, 5, 6]
   y = x
-  for i in low(x)..high(x):
+  for i in low(x) .. high(x):
     echo x[i], y[i]
 
 
 Sequences
 ---------
+
 Sequences are similar to arrays but of dynamic length which may change
 during runtime (like strings). Since sequences are resizable they are always
 allocated on the heap and garbage collected.
@@ -1351,6 +1364,7 @@ value. Here the `for` statement is looping over the results from the
 
 Open arrays
 -----------
+
 **Note**: Openarrays can only be used for parameters.
 
 Often fixed-size arrays turn out to be too inflexible; procedures should be
@@ -1602,7 +1616,7 @@ Even though you don't need to declare a type for a tuple to use it, tuples
 created with different field names will be considered different objects despite
 having the same field types.
 
-Tuples can be *unpacked* during variable assignment (and only then!). This can
+Tuples can be *unpacked* during variable assignment. This can
 be handy to assign directly the fields of the tuples to individually named
 variables. An example of this is the `splitFile <os.html#splitFile,string>`_
 proc from the `os module <os.html>`_ which returns the directory, name, and
@@ -1634,6 +1648,7 @@ marked to be exported, unlike for example fields in an object type.
 
 Reference and pointer types
 ---------------------------
+
 References (similar to pointers in other programming languages) are a
 way to introduce many-to-one relationships. This means different references can
 point to and modify the same location in memory.
@@ -1643,7 +1658,7 @@ Untraced references are also called *pointers*. Traced references point to
 objects in a garbage-collected heap, untraced references point to
 manually allocated objects or objects elsewhere in memory. Thus
 untraced references are *unsafe*. However, for certain low-level operations
-(e.g., accessing the hardware), untraced references are necessary.
+(e.g. accessing the hardware), untraced references are necessary.
 
 Traced references are declared with the **ref** keyword; untraced references
 are declared with the **ptr** keyword.
@@ -1676,6 +1691,7 @@ If a reference points to *nothing*, it has the value `nil`.
 
 Procedural type
 ---------------
+
 A procedural type is a (somewhat abstract) pointer to a procedure.
 `nil` is an allowed value for a variable of a procedural type.
 Nim uses procedural types to achieve `functional`:idx: programming
@@ -1702,6 +1718,7 @@ listed in the `manual <manual.html#types-procedural-type>`_.
 
 Distinct type
 -------------
+
 A Distinct type allows for the creation of a new type that "does not imply a
 subtype relationship between it and its base type".
 You must **explicitly** define all behavior for the distinct type.
@@ -1711,6 +1728,7 @@ Examples are provided in the `manual <manual.html#types-distinct-type>`_.
 
 Modules
 =======
+
 Nim supports splitting a program into pieces with a *module* concept.
 Each module is in its own file. Modules enable `information hiding`:idx: and
 `separate compilation`:idx:. A module may gain access to the symbols of another
@@ -1726,7 +1744,7 @@ with an asterisk (`*`) are exported:
     # allocate a new sequence:
     newSeq(result, len(a))
     # multiply two int sequences:
-    for i in 0..len(a)-1: result[i] = a[i] * b[i]
+    for i in 0 ..< len(a): result[i] = a[i] * b[i]
 
   when isMainModule:
     # test the new `*` operator for sequences:
@@ -1833,6 +1851,7 @@ define a shorter alias to use when qualifying symbols.
 
 Include statement
 -----------------
+
 The `include` statement does something fundamentally different than
 importing a module: it merely includes the contents of a file. The `include`
 statement is useful to split up a large module into several files: