big rename

This commit is contained in:
Araq 2014-08-27 23:42:51 +02:00
commit 11b6958755
98 changed files with 2491 additions and 2341 deletions

File diff suppressed because it is too large Load diff

View file

@ -180,7 +180,7 @@ So it is not necessary to write ``peg" 'abc' "`` in the above example.
Examples
--------
Check if `s` matches Nimrod's "while" keyword:
Check if `s` matches Nim's "while" keyword:
.. code-block:: nimrod
s =~ peg" y'while'"
@ -212,7 +212,7 @@ example ``*`` should not be greedy, so ``\[.*?\]`` should be used instead.
PEG construction
----------------
There are two ways to construct a PEG in Nimrod code:
There are two ways to construct a PEG in Nim code:
(1) Parsing a string into an AST which consists of `TPeg` nodes with the
`peg` proc.
(2) Constructing the AST directly with proc calls. This method does not

View file

@ -1,9 +1,9 @@
========================
Nimrod Tutorial (Part I)
========================
=====================
Nim Tutorial (Part I)
=====================
:Author: Andreas Rumpf
:Version: |nimrodversion|
:Version: |nimversion|
.. contents::
@ -16,7 +16,7 @@ Introduction
</p></blockquote>
This document is a tutorial for the programming language *Nimrod*.
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 but is kept very basic. The `manual
<manual.html>`_ contains many more examples of the advanced language features.
@ -28,7 +28,7 @@ The first program
We start the tour with a modified "hello world" program:
.. code-block:: Nimrod
.. code-block:: Nim
# This is a comment
echo("What's your name? ")
var name: string = readLine(stdin)
@ -37,30 +37,30 @@ We start the tour with a modified "hello world" program:
Save this code to the file "greetings.nim". Now compile and run it::
nimrod compile --run greetings.nim
nim compile --run greetings.nim
With the ``--run`` `switch <nimrodc.html#command-line-switches>`_ Nimrod
With the ``--run`` `switch <nimc.html#command-line-switches>`_ Nim
executes the file automatically after compilation. You can give your program
command line arguments by appending them after the filename::
nimrod compile --run greetings.nim arg1 arg2
nim compile --run greetings.nim arg1 arg2
Commonly used commands and switches have abbreviations, so you can also use::
nimrod c -r greetings.nim
nim c -r greetings.nim
To compile a release version use::
nimrod c -d:release greetings.nim
nim c -d:release greetings.nim
By default the Nimrod compiler generates a large amount of runtime checks
By default the Nim compiler generates a large amount of runtime checks
aiming for your debugging pleasure. With ``-d:release`` these checks are
`turned off and optimizations are turned on
<nimrodc.html#compile-time-symbols>`_.
<nimc.html#compile-time-symbols>`_.
Though it should be pretty obvious what the program does, I will explain the
syntax: statements which are not indented are executed when the program
starts. Indentation is Nimrod's way of grouping statements. Indentation is
starts. Indentation is Nim's way of grouping statements. Indentation is
done with spaces only, tabulators are not allowed.
String literals are enclosed in double quotes. The ``var`` statement declares
@ -70,11 +70,11 @@ compiler knows that `readLine <system.html#readLine,TFile>`_ returns a string,
you can leave out the type in the declaration (this is called `local type
inference`:idx:). So this will work too:
.. code-block:: Nimrod
.. code-block:: Nim
var name = readLine(stdin)
Note that this is basically the only form of type inference that exists in
Nimrod: it is a good compromise between brevity and readability.
Nim: it is a good compromise between brevity and readability.
The "hello world" program contains several identifiers that are already known
to the compiler: ``echo``, `readLine <system.html#readLine,TFile>`_, etc.
@ -85,8 +85,8 @@ imported by any other module.
Lexical elements
================
Let us look at Nimrod's lexical elements in more detail: like other
programming languages Nimrod consists of (string) literals, identifiers,
Let us look at Nim's lexical elements in more detail: like other
programming languages Nim consists of (string) literals, identifiers,
keywords, comments, operators, and other punctuation marks.
@ -97,7 +97,7 @@ String literals are enclosed in double quotes; character literals in single
quotes. Special characters are escaped with ``\``: ``\n`` means newline, ``\t``
means tabulator, etc. There are also *raw* string literals:
.. code-block:: Nimrod
.. code-block:: Nim
r"C:\program files\nim"
In raw literals the backslash is not an escape character.
@ -115,7 +115,7 @@ Comments start anywhere outside a string or character literal with the
hash character ``#``. Documentation comments start with ``##``. Multiline
comments need to be aligned at the same column:
.. code-block:: nimrod
.. code-block:: nim
i = 0 # This is a single comment over multiple lines belonging to the
# assignment statement.
@ -128,7 +128,7 @@ comments need to be aligned at the same column:
The alignment requirement does not hold if the preceding comment piece ends in
a backslash:
.. code-block:: nimrod
.. code-block:: nim
type
TMyObject {.final, pure, acyclic.} = object # comment continues: \
# we have lots of space here to comment 'TMyObject'.
@ -151,15 +151,15 @@ the syntax, watch their indentation:
**Note**: To comment out a large piece of code, it is often better to use a
``when false:`` statement.
.. code-block:: nimrod
.. code-block:: nim
when false:
brokenCode()
Another option is to use the `discard statement`_ together with *long string
literals* to create block comments:
.. code-block:: nimrod
discard """ You can have any Nimrod code text commented
.. code-block:: nim
discard """ You can have any Nim code text commented
out inside this with no indentation restrictions.
yes("May I ask a pointless question?") """
@ -204,7 +204,7 @@ to a storage location:
``=`` is the *assignment operator*. The assignment operator cannot be
overloaded, overwritten or forbidden, but this might change in a future version
of Nimrod. You can declare multiple variables with a single assignment
of Nim. You can declare multiple variables with a single assignment
statement and all the variables will have the same value:
.. code-block::
@ -229,7 +229,7 @@ Constants are symbols which are bound to a value. The constant's value
cannot change. The compiler must be able to evaluate the expression in a
constant declaration at compile time:
.. code-block:: nimrod
.. code-block:: nim
const x = "abc" # the constant x contains the string "abc"
Indentation can be used after the ``const`` keyword to list a whole section of
@ -277,7 +277,7 @@ If statement
The if statement is one way to branch the control flow:
.. code-block:: nimrod
.. code-block:: nim
let name = readLine(stdin)
if name == "":
echo("Poor soul, you lost your name?")
@ -298,7 +298,7 @@ Case statement
Another way to branch is provided by the case statement. A case statement is
a multi-branch:
.. code-block:: nimrod
.. code-block:: nim
let name = readLine(stdin)
case name
of "":
@ -317,7 +317,7 @@ The case statement can deal with integers, other ordinal types and strings.
(What an ordinal type is will be explained soon.)
For integers or other ordinal types value ranges are also possible:
.. code-block:: nimrod
.. code-block:: nim
# this statement will be explained later:
from strutils import parseInt
@ -333,7 +333,7 @@ every value that ``n`` may contain, but the code only handles the values
(though it is possible thanks to the range notation), we fix this by telling
the compiler that for every other value nothing should be done:
.. code-block:: nimrod
.. code-block:: nim
...
case n
of 0..2, 4..7: echo("The number is in the set: {0, 1, 2, 4, 5, 6, 7}")
@ -355,7 +355,7 @@ While statement
The while statement is a simple looping construct:
.. code-block:: nimrod
.. code-block:: nim
echo("What's your name? ")
var name = readLine(stdin)
@ -375,7 +375,7 @@ The ``for`` statement is a construct to loop over any element an *iterator*
provides. The example uses the built-in `countup <system.html#countup>`_
iterator:
.. code-block:: nimrod
.. code-block:: nim
echo("Counting to ten: ")
for i in countup(1, 10):
echo($i)
@ -387,7 +387,7 @@ other types into a string. The variable ``i`` is implicitly declared by the
<system.html#countup>`_ returns. ``i`` runs through the values 1, 2, .., 10.
Each value is ``echo``-ed. This code does the same:
.. code-block:: nimrod
.. code-block:: nim
echo("Counting to 10: ")
var i = 1
while i <= 10:
@ -397,16 +397,16 @@ Each value is ``echo``-ed. This code does the same:
Counting down can be achieved as easily (but is less often needed):
.. code-block:: nimrod
.. code-block:: nim
echo("Counting down from 10 to 1: ")
for i in countdown(10, 1):
echo($i)
# --> Outputs 10 9 8 7 6 5 4 3 2 1 on different lines
Since counting up occurs so often in programs, Nimrod also has a `..
Since counting up occurs so often in programs, Nim also has a `..
<system.html#...i,S,T>`_ iterator that does the same:
.. code-block:: nimrod
.. code-block:: nim
for i in 1..10:
...
@ -417,7 +417,7 @@ 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:
.. code-block:: nimrod
.. code-block:: nim
while false:
var x = "hi"
echo(x) # does not work
@ -426,7 +426,7 @@ A while (for) statement introduces an implicit block. Identifiers
are only visible within the block they have been declared. The ``block``
statement can be used to open a new block explicitly:
.. code-block:: nimrod
.. code-block:: nim
block myblock:
var x = "hi"
echo(x) # does not work either
@ -440,7 +440,7 @@ 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:
.. code-block:: nimrod
.. code-block:: nim
block myblock:
echo("entering block")
while true:
@ -461,7 +461,7 @@ Continue statement
Like in many other programming languages, a ``continue`` statement starts
the next iteration immediately:
.. code-block:: nimrod
.. code-block:: nim
while true:
let x = readLine(stdin)
if x == "": continue
@ -473,7 +473,7 @@ When statement
Example:
.. code-block:: nimrod
.. code-block:: nim
when system.hostOS == "windows":
echo("running on Windows!")
@ -504,17 +504,17 @@ possible.
Statements and indentation
==========================
Now that we covered the basic control flow statements, let's return to Nimrod
Now that we covered the basic control flow statements, let's return to Nim
indentation rules.
In Nimrod there is a distinction between *simple statements* and *complex
In Nim there is a distinction between *simple statements* and *complex
statements*. *Simple statements* cannot contain other statements:
Assignment, procedure calls or the ``return`` statement belong to the simple
statements. *Complex statements* like ``if``, ``when``, ``for``, ``while`` can
contain other statements. To avoid ambiguities, complex statements always have
to be indented, but single simple statements do not:
.. code-block:: nimrod
.. code-block:: nim
# no indentation needed for single assignment statement:
if x: x = false
@ -535,7 +535,7 @@ to be indented, but single simple statements do not:
condition in an if statement is an example for an expression. Expressions can
contain indentation at certain places for better readability:
.. code-block:: nimrod
.. code-block:: nim
if thisIsaLongCondition() and
thisIsAnotherLongCondition(1,
@ -548,7 +548,7 @@ an open parenthesis and after commas.
With parenthesis and semicolons ``(;)`` you can use statements where only
an expression is allowed:
.. code-block:: nimrod
.. code-block:: nim
# computes fac(4) at compile time:
const fac4 = (var x = 1; for i in 1..4: x *= i; x)
@ -558,10 +558,10 @@ Procedures
To define new commands like `echo <system.html#echo>`_ and `readLine
<system.html#readLine,TFile>`_ in the examples, the concept of a `procedure`
is needed. (Some languages call them *methods* or *functions*.) In Nimrod new
is needed. (Some languages call them *methods* or *functions*.) In Nim new
procedures are defined with the ``proc`` keyword:
.. code-block:: nimrod
.. code-block:: nim
proc yes(question: string): bool =
echo(question, " (y/n)")
while true:
@ -597,7 +597,7 @@ shorthand for ``return result``. The ``result`` value is always returned
automatically at the end a procedure if there is no ``return`` statement at
the exit.
.. code-block:: nimrod
.. code-block:: nim
proc sumTillNegative(x: varargs[int]): int =
for i in x:
if i < 0:
@ -624,7 +624,7 @@ most efficient way. If a mutable variable is needed inside the procedure, it has
to be declared with ``var`` in the procedure body. Shadowing the parameter name
is possible, and actually an idiom:
.. code-block:: nimrod
.. code-block:: nim
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,7 +633,7 @@ is possible, and actually an idiom:
If the procedure needs to modify the argument for the
caller, a ``var`` parameter can be used:
.. code-block:: nimrod
.. code-block:: nim
proc divmod(a, b: int; res, remainder: var int) =
res = a div b # integer division
remainder = a mod b # integer modulo operation
@ -653,17 +653,17 @@ 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 **has** to be used. Nimrod does not
its return value, a ``discard`` statement **has** to be used. Nim does not
allow to silently throw away a return value:
.. code-block:: nimrod
.. code-block:: nim
discard yes("May I ask a pointless question?")
The return value can be ignored implicitly if the called proc/iterator has
been declared with the ``discardable`` pragma:
.. code-block:: nimrod
.. code-block:: nim
proc p(x, y: int): int {.discardable.} =
return x + y
@ -681,7 +681,7 @@ parameters appear. This is especially true for procedures that construct a
complex data type. Therefore the arguments to a procedure can be named, so
that it is clear which argument belongs to which parameter:
.. code-block:: nimrod
.. code-block:: nim
proc createWindow(x, y, width, height: int; title: string;
show: bool): Window =
...
@ -693,7 +693,7 @@ Now that we use named arguments to call ``createWindow`` the argument order
does not matter anymore. Mixing named arguments with ordered arguments is
also possible, but not very readable:
.. code-block:: nimrod
.. code-block:: nim
var w = createWindow(0, 0, title = "My Application",
height = 600, width = 800, true)
@ -706,7 +706,7 @@ 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:
.. code-block:: nimrod
.. code-block:: nim
proc createWindow(x = 0, y = 0, width = 500, height = 700,
title = "unknown",
show = true): Window =
@ -723,9 +723,9 @@ no need to write ``title: string = "unknown"``, for example.
Overloaded procedures
---------------------
Nimrod provides the ability to overload procedures similar to C++:
Nim provides the ability to overload procedures similar to C++:
.. code-block:: nimrod
.. code-block:: nim
proc toString(x: int): string = ...
proc toString(x: bool): string =
if x: result = "true"
@ -735,7 +735,7 @@ Nimrod provides the ability to overload procedures similar to C++:
echo(toString(true)) # calls the toString(x: bool) proc
(Note that ``toString`` is usually the `$ <system.html#$>`_ operator in
Nimrod.) The compiler chooses the most appropriate proc for the ``toString``
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
@ -744,13 +744,13 @@ algorithm. Ambiguous calls are reported as errors.
Operators
---------
The Nimrod library makes heavy use of overloading - one reason for this is that
The Nim library makes heavy use of overloading - one reason for this is that
each operator like ``+`` is a 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.
Postfix operators are not possible, because this would be ambiguous: does
``a @ @ b`` mean ``(a) @ (@b)`` or ``(a@) @ (b)``? It always means
``(a) @ (@b)``, because there are no postfix operators in Nimrod.
``(a) @ (@b)``, because there are no postfix operators in Nim.
Apart from a few built-in keyword operators such as ``and``, ``or``, ``not``,
operators always consist of these characters:
@ -764,7 +764,7 @@ can be found in the manual.
To define a new operator enclose the operator in backticks "``":
.. code-block:: nimrod
.. code-block:: nim
proc `$` (x: myDataType): string = ...
# now the $ operator also works with myDataType, overloading resolution
# ensures that $ works for built-in types just like before
@ -772,7 +772,7 @@ To define a new operator enclose the operator in backticks "``":
The "``" notation can also be used to call an operator just like any other
procedure:
.. code-block:: nimrod
.. code-block:: nim
if `==`( `+`(3, 4), 7): echo("True")
@ -783,7 +783,7 @@ Every variable, procedure, etc. needs to be declared before it can be used.
(The reason for this is compilation efficiency.)
However, this cannot be done for mutually recursive procedures:
.. code-block:: nimrod
.. code-block:: nim
# forward declaration:
proc even(n: int): bool
@ -810,7 +810,7 @@ Iterators
Let's return to the boring counting example:
.. code-block:: nimrod
.. code-block:: nim
echo("Counting to ten: ")
for i in countup(1, 10):
echo($i)
@ -818,7 +818,7 @@ Let's return to the boring counting example:
Can a `countup <system.html#countup>`_ proc be written that supports this
loop? Lets try:
.. code-block:: nimrod
.. code-block:: nim
proc countup(a, b: int): int =
var res = a
while res <= b:
@ -831,7 +831,7 @@ 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 there it is - our first iterator:
.. code-block:: nimrod
.. code-block:: nim
iterator countup(a, b: int): int =
var res = a
while res <= b:
@ -868,7 +868,7 @@ that are available for them in detail.
Booleans
--------
The boolean type is named ``bool`` in Nimrod and consists of the two
The boolean type is named ``bool`` in Nim and consists of the two
pre-defined values ``true`` and ``false``. Conditions in while,
if, elif, when statements need to be of type bool.
@ -876,7 +876,7 @@ The operators ``not, and, or, xor, <, <=, >, >=, !=, ==`` are defined
for the bool type. The ``and`` and ``or`` operators perform short-cut
evaluation. Example:
.. code-block:: nimrod
.. code-block:: nim
while p != nil and p.name != "xyz":
# p.name is not evaluated if p == nil
@ -885,7 +885,7 @@ evaluation. Example:
Characters
----------
The `character type` is named ``char`` in Nimrod. Its size is one byte.
The `character type` is named ``char`` in Nim. Its size is one byte.
Thus it cannot represent an UTF-8 character, but a part of it.
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
@ -900,13 +900,13 @@ Converting from an integer to a ``char`` is done with the ``chr`` proc.
Strings
-------
String variables in Nimrod are **mutable**, so appending to a string
is quite efficient. Strings in Nimrod are both zero-terminated and have a
String variables in Nim are **mutable**, so appending to a string
is quite efficient. Strings in Nim are both zero-terminated and have a
length field. One can retrieve a string's length with the builtin ``len``
procedure; the length never counts the terminating zero. Accessing the
terminating zero is no error and often leads to simpler code:
.. code-block:: nimrod
.. code-block:: nim
if s[i] == 'a' and s[i+1] == 'b':
# no need to check whether ``i < len(s)``!
...
@ -929,14 +929,14 @@ object on the heap, so there is a trade-off to be made here.
Integers
--------
Nimrod has these integer types built-in:
Nim has these integer types built-in:
``int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64``.
The default integer type is ``int``. Integer literals can have a *type suffix*
to mark them to be of another integer type:
.. code-block:: nimrod
.. code-block:: nim
let
x = 0 # x is of type ``int``
y = 0'i8 # y is of type ``int8``
@ -964,7 +964,7 @@ cannot be detected at compile time).
Floats
------
Nimrod has these floating point types built-in: ``float float32 float64``.
Nim has these floating point types built-in: ``float float32 float64``.
The default float type is ``float``. In the current implementation,
``float`` is always 64 bit wide.
@ -972,7 +972,7 @@ The default float type is ``float``. In the current implementation,
Float literals can have a *type suffix* to mark them to be of another float
type:
.. code-block:: nimrod
.. code-block:: nim
var
x = 0.0 # x is of type ``float``
y = 0.0'f32 # y is of type ``float32``
@ -1001,11 +1001,11 @@ having to write its ``$`` operator. You can use then the `repr
graphs with cycles. The following example shows that even for basic types
there is a difference between the ``$`` and ``repr`` outputs:
.. code-block:: nimrod
.. code-block:: nim
var
myBool = true
myCharacter = 'n'
myString = "nimrod"
myString = "nim"
myInteger = 42
myFloat = 3.14
echo($myBool, ":", repr(myBool))
@ -1013,7 +1013,7 @@ there is a difference between the ``$`` and ``repr`` outputs:
echo($myCharacter, ":", repr(myCharacter))
# --> n:'n'
echo($myString, ":", repr(myString))
# --> nimrod:0x10fa8c050"nimrod"
# --> nim:0x10fa8c050"nim"
echo($myInteger, ":", repr(myInteger))
# --> 42:42
echo($myFloat, ":", repr(myFloat))
@ -1023,9 +1023,9 @@ there is a difference between the ``$`` and ``repr`` outputs:
Advanced types
==============
In Nimrod new types can be defined within a ``type`` statement:
In Nim new types can be defined within a ``type`` statement:
.. code-block:: nimrod
.. code-block:: nim
type
biggestInt = int64 # biggest integer type that is available
biggestFloat = float64 # biggest float type that is available
@ -1041,7 +1041,7 @@ limited set. This set consists of ordered symbols. Each symbol is mapped
to an integer value internally. The first symbol is represented
at runtime by 0, the second by 1 and so on. Example:
.. code-block:: nimrod
.. code-block:: nim
type
TDirection = enum
@ -1050,7 +1050,7 @@ at runtime by 0, the second by 1 and so on. Example:
var x = south # `x` is of type `TDirection`; its value is `south`
echo($x) # writes "south" to `stdout`
(To prefix a new type with the letter ``T`` is a convention in Nimrod.)
(To prefix a new type with the letter ``T`` is a convention in Nim.)
All comparison operators can be used with enumeration types.
An enumeration's symbol can be qualified to avoid ambiguities:
@ -1066,7 +1066,7 @@ explicitly given is assigned the value of the previous symbol + 1.
An explicit ordered enum can have *holes*:
.. code-block:: nimrod
.. code-block:: nim
type
TMyEnum = enum
a = 2, b = 4, c = 89
@ -1104,7 +1104,7 @@ Subranges
A subrange type is a range of values from an integer or enumeration type
(the base type). Example:
.. code-block:: nimrod
.. code-block:: nim
type
TSubrange = range[0..5]
@ -1119,7 +1119,7 @@ type as ``range[0..high(int)]`` (`high <system.html#high>`_ returns the
maximal value). Other programming languages mandate the usage of unsigned
integers for natural numbers. This is often **wrong**: you don't want unsigned
arithmetic (which wraps around) just because the numbers cannot be negative.
Nimrod's ``Natural`` type helps to avoid this common programming error.
Nim's ``Natural`` type helps to avoid this common programming error.
Sets
@ -1134,7 +1134,7 @@ the array has the same type. The array's index type can be any ordinal type.
Arrays can be constructed via ``[]``:
.. code-block:: nimrod
.. code-block:: nim
type
TIntArray = array[0..5, int] # an array that is indexed with 0..5
@ -1149,14 +1149,14 @@ Array access is always bounds checked (at compile-time or at runtime). These
checks can be disabled via pragmas or invoking the compiler with the
``--bound_checks:off`` command line switch.
Arrays are value types, like any other Nimrod type. The assignment operator
Arrays are value types, like any other Nim type. The assignment operator
copies the whole array contents.
The built-in `len <system.html#len,TOpenArray>`_ proc returns the array's
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:: nimrod
.. code-block:: nim
type
TDirection = enum
north, east, south, west
@ -1175,13 +1175,13 @@ array `a` and `high(a) <system.html#high>`_ the highest valid index.
The syntax for nested arrays (multidimensional) in other languages is a matter
of appending more brackets because usually each dimension is restricted to the
same index type as the others. In nimrod you can have different dimensions with
same index type as the others. In Nim you can have different dimensions with
different index types, so the nesting syntax is slightly different. Building on
the previous example where a level is defined as an array of enums indexed by
yet another enum, we can add the following lines to add a light tower type
subdivided in height levels accessed through their integer index:
.. code-block:: nimrod
.. code-block:: nim
type
TLightTower = array[1..10, TLevelSetting]
var
@ -1200,14 +1200,14 @@ length. Another way of defining the ``TLightTower`` to show better its
nested nature would be to omit the previous definition of the ``TLevelSetting``
type and instead write it embedded directly as the type of the first dimension:
.. code-block:: nimrod
.. code-block:: nim
type
TLightTower = array[1..10, array[north..west, TBlinkLights]]
It is quite frequent 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:: nimrod
.. code-block:: nim
type
TIntArray = array[0..5, int] # an array that is indexed with 0..5
TQuickArray = array[6, int] # an array that is indexed with 0..5
@ -1239,7 +1239,7 @@ A sequence may be passed to an openarray parameter.
Example:
.. code-block:: nimrod
.. code-block:: nim
var
x: seq[int] # a sequence of integers
@ -1261,7 +1261,7 @@ value. Here the ``for`` statement is looping over the results from the
`pairs() <system.html#pairs.i,seq[T]>`_ iterator from the `system
<system.html>`_ module. Examples:
.. code-block:: nimrod
.. code-block:: nim
for i in @[3, 4, 5]:
echo($i)
# --> 3
@ -1299,7 +1299,7 @@ also a means to implement passing a variable number of
arguments to a procedure. The compiler converts the list of arguments
to an array automatically:
.. code-block:: nimrod
.. code-block:: nim
proc myWriteln(f: TFile, a: varargs[string]) =
for s in items(a):
write(f, s)
@ -1313,7 +1313,7 @@ This transformation is only done if the varargs parameter is the
last parameter in the procedure header. It is also possible to perform
type conversions in this context:
.. code-block:: nimrod
.. code-block:: nim
proc myWriteln(f: TFile, a: varargs[string, `$`]) =
for s in items(a):
write(f, s)
@ -1336,10 +1336,10 @@ context. A slice is just an object of type TSlice which contains two bounds,
`a` and `b`. By itself a slice is not very useful, but other collection types
define operators which accept TSlice objects to define ranges.
.. code-block:: nimrod
.. code-block:: nim
var
a = "Nimrod is a progamming language"
a = "Nim is a progamming language"
b = "Slices are useless."
echo a[10..15] # --> 'a prog'
@ -1366,7 +1366,7 @@ The assignment operator for tuples copies each component. The notation
``t[i]`` to access the ``i``'th field. Here ``i`` needs to be a constant
integer.
.. code-block:: nimrod
.. code-block:: nim
type
TPerson = tuple[name: string, age: int] # type representing a person:
@ -1411,19 +1411,19 @@ use parenthesis around the values you want to assign the unpacking to,
otherwise you will be assigning the same value to all the individual
variables! Example:
.. code-block:: nimrod
.. code-block:: nim
import os
let
path = "usr/local/nimrodc.html"
path = "usr/local/nimc.html"
(dir, name, ext) = splitFile(path)
baddir, badname, badext = splitFile(path)
echo dir # outputs `usr/local`
echo name # outputs `nimrodc`
echo name # outputs `nimc`
echo ext # outputs `.html`
# All the following output the same line:
# `(dir: usr/local, name: nimrodc, ext: .html)`
# `(dir: usr/local, name: nimc, ext: .html)`
echo baddir
echo badname
echo badext
@ -1431,12 +1431,12 @@ variables! Example:
Tuple unpacking **only** works in ``var`` or ``let`` blocks. The following code
won't compile:
.. code-block:: nimrod
.. code-block:: nim
import os
var
path = "usr/local/nimrodc.html"
path = "usr/local/nimc.html"
dir, name, ext = ""
(dir, name, ext) = splitFile(path)
@ -1449,7 +1449,7 @@ 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.
Nimrod distinguishes between `traced`:idx: and `untraced`:idx: references.
Nim distinguishes between `traced`:idx: and `untraced`:idx: references.
Untraced references are also called *pointers*. Traced references point to
objects of a garbage collected heap, untraced references point to
manually allocated objects or to objects somewhere else in memory. Thus
@ -1464,7 +1464,7 @@ meaning to retrieve the item the reference points to. The ``.`` (access a
tuple/object field operator) and ``[]`` (array/string/sequence index operator)
operators perform implicit dereferencing operations for reference types:
.. code-block:: nimrod
.. code-block:: nim
type
PNode = ref TNode
@ -1489,12 +1489,12 @@ 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.
Nimrod uses procedural types to achieve `functional`:idx: programming
Nim uses procedural types to achieve `functional`:idx: programming
techniques.
Example:
.. code-block:: nimrod
.. code-block:: nim
proc echoItem(x: int) = echo(x)
proc forEach(action: proc (x: int)) =
@ -1513,13 +1513,13 @@ listed in the `manual <manual.html>`_.
Modules
=======
Nimrod supports splitting a program into pieces with a module concept.
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 symbols of another
module by the `import`:idx: statement. Only top-level symbols that are marked
with an asterisk (``*``) are exported:
.. code-block:: nimrod
.. code-block:: nim
# Module A
var
x*, y: int
@ -1554,7 +1554,7 @@ The algorithm for compiling modules is:
This is best illustrated by an example:
.. code-block:: nimrod
.. code-block:: nim
# Module A
type
T1* = int # Module A exports the type ``T1``
@ -1565,7 +1565,7 @@ This is best illustrated by an example:
main()
.. code-block:: nimrod
.. code-block:: nim
# Module B
import A # A is not parsed here! Only the already known symbols
# of A are imported.
@ -1581,15 +1581,15 @@ the symbol is ambiguous, it even *has* to be qualified. A symbol is ambiguous
if it is defined in two (or more) different modules and both modules are
imported by a third one:
.. code-block:: nimrod
.. code-block:: nim
# Module A
var x*: string
.. code-block:: nimrod
.. code-block:: nim
# Module B
var x*: int
.. code-block:: nimrod
.. code-block:: nim
# Module C
import A, B
write(stdout, x) # error: x is ambiguous
@ -1602,15 +1602,15 @@ imported by a third one:
But this rule does not apply to procedures or iterators. Here the overloading
rules apply:
.. code-block:: nimrod
.. code-block:: nim
# Module A
proc x*(a: int): string = result = $a
.. code-block:: nimrod
.. code-block:: nim
# Module B
proc x*(a: string): string = result = $a
.. code-block:: nimrod
.. code-block:: nim
# Module C
import A, B
write(stdout, x(3)) # no error: A.x is called
@ -1627,7 +1627,7 @@ The normal ``import`` statement will bring in all exported symbols.
These can be limited by naming symbols which should be excluded with
the ``except`` qualifier.
.. code-block:: nimrod
.. code-block:: nim
import mymodule except y
@ -1638,19 +1638,19 @@ We have already seen the simple ``import`` statement that just imports all
exported symbols. An alternative that only imports listed symbols is the
``from import`` statement:
.. code-block:: nimrod
.. code-block:: nim
from mymodule import x, y, z
The ``from`` statement can also force namespace qualification on
symbols, thereby making symbols available, but needing to be qualified
to be used.
.. code-block:: nimrod
.. code-block:: nim
from mymodule import x, y, z
x() # use x without any qualification
.. code-block:: nimrod
.. code-block:: nim
from mymodule import nil
mymodule.x() # must qualify x with the module name as prefix
@ -1660,7 +1660,7 @@ to be used.
Since module names are generally long to be descriptive, you can also
define a shorter alias to use when qualifying symbols.
.. code-block:: nimrod
.. code-block:: nim
from mymodule as m import nil
m.x() # m is aliasing mymodule
@ -1672,7 +1672,7 @@ 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:
.. code-block:: nimrod
.. code-block:: nim
include fileA, fileB, fileC
**Note**: The documentation generator currently does not follow ``include``
@ -1683,7 +1683,7 @@ generated documentation.
Part 2
======
So, now that we are done with the basics, let's see what Nimrod offers apart
So, now that we are done with the basics, let's see what Nim offers apart
from a nice syntax for procedural programming: `Part II <tut2.html>`_

View file

@ -1,9 +1,9 @@
=========================
Nimrod Tutorial (Part II)
=========================
======================
Nim Tutorial (Part II)
======================
:Author: Andreas Rumpf
:Version: |nimrodversion|
:Version: |nimversion|
.. contents::
@ -15,7 +15,7 @@ Introduction
only have originated in California." --Edsger Dijkstra
This document is a tutorial for the advanced constructs of the *Nimrod*
This document is a tutorial for the advanced constructs of the *Nim*
programming language. **Note that this document is somewhat obsolete as the**
`manual <manual.html>`_ **contains many more examples of the advanced language
features.**
@ -24,18 +24,18 @@ features.**
Pragmas
=======
Pragmas are Nimrod's method to give the compiler additional information/
Pragmas are Nim's method to give the compiler additional information/
commands without introducing a massive number of new keywords. Pragmas are
enclosed in the special ``{.`` and ``.}`` curly dot brackets. This tutorial
does not cover pragmas. See the `manual <manual.html#pragmas>`_ or `user guide
<nimrodc.html#additional-features>`_ for a description of the available
<nimc.html#additional-features>`_ for a description of the available
pragmas.
Object Oriented Programming
===========================
While Nimrod's support for object oriented programming (OOP) is minimalistic,
While Nim's support for object oriented programming (OOP) is minimalistic,
powerful OOP technics can be used. OOP is seen as *one* way to design a
program, not *the only* way. Often a procedural approach leads to simpler
and more efficient code. In particular, prefering composition over inheritance
@ -55,7 +55,7 @@ a *constructor*).
Objects have access to their type at runtime. There is an
``of`` operator that can be used to check the object's type:
.. code-block:: nimrod
.. code-block:: nim
type
TPerson = object of TObject
name*: string # the * means that `name` is accessible from other modules
@ -86,20 +86,20 @@ in the GTK wrapper for instance.)
**Note**: Composition (*has-a* relation) is often preferable to inheritance
(*is-a* relation) for simple code reuse. Since objects are value types in
Nimrod, composition is as efficient as inheritance.
Nim, composition is as efficient as inheritance.
Mutually recursive types
------------------------
Objects, tuples and references can model quite complex data structures which
depend on each other; they are *mutually recursive*. In Nimrod
depend on each other; they are *mutually recursive*. In Nim
these types can only be declared within a single type section. (Anything else
would require arbitrary symbol lookahead which slows down compilation.)
Example:
.. code-block:: nimrod
.. code-block:: nim
type
PNode = ref TNode # a traced reference to a TNode
TNode = object
@ -114,7 +114,7 @@ Example:
Type conversions
----------------
Nimrod distinguishes between `type casts`:idx: and `type conversions`:idx:.
Nim distinguishes between `type casts`:idx: and `type conversions`:idx:.
Casts are done with the ``cast`` operator and force the compiler to
interpret a bit pattern to be of another type.
@ -126,7 +126,7 @@ raised.
The syntax for type conversions is ``destination_type(expression_to_convert)``
(like an ordinary call):
.. code-block:: nimrod
.. code-block:: nim
proc getID(x: TPerson): int =
TStudent(x).id
@ -141,9 +141,9 @@ variant types are needed.
An example:
.. code-block:: nimrod
.. code-block:: nim
# This is an example how an abstract syntax tree could be modeled in Nimrod
# This is an example how an abstract syntax tree could be modeled in Nim
type
TNodeKind = enum # the different node types
nkInt, # a leaf with an integer value
@ -183,8 +183,8 @@ bound to a class. This has disadvantages:
* Often it is unclear where the method should belong to: is
``join`` a string method or an array method?
Nimrod avoids these problems by not assigning methods to a class. All methods
in Nimrod are multi-methods. As we will see later, multi-methods are
Nim avoids these problems by not assigning methods to a class. All methods
in Nim are multi-methods. As we will see later, multi-methods are
distinguished from procs only for dynamic binding purposes.
@ -199,7 +199,7 @@ If there are no remaining arguments, the parentheses can be omitted:
This method call syntax is not restricted to objects, it can be used
for any type:
.. code-block:: nimrod
.. code-block:: nim
echo("abc".len) # is the same as echo(len("abc"))
echo("abc".toUpper())
@ -211,7 +211,7 @@ postfix notation.)
So "pure object oriented" code is easy to write:
.. code-block:: nimrod
.. code-block:: nim
import strutils
stdout.writeln("Give a list of numbers (separated by spaces): ")
@ -221,12 +221,12 @@ So "pure object oriented" code is easy to write:
Properties
----------
As the above example shows, Nimrod has no need for *get-properties*:
As the above example shows, Nim has no need for *get-properties*:
Ordinary get-procedures that are called with the *method call syntax* achieve
the same. But setting a value is different; for this a special setter syntax
is needed:
.. code-block:: nimrod
.. code-block:: nim
type
TSocket* = object of TObject
@ -252,7 +252,7 @@ is needed:
The ``[]`` array access operator can be overloaded to provide
`array properties`:idx:\ :
.. code-block:: nimrod
.. code-block:: nim
type
TVector* = object
x, y, z: float
@ -283,7 +283,7 @@ Dynamic dispatch
Procedures always use static dispatch. For dynamic dispatch replace the
``proc`` keyword by ``method``:
.. code-block:: nimrod
.. code-block:: nim
type
PExpr = ref object of TObject ## abstract base class for an expression
PLiteral = ref object of PExpr
@ -311,7 +311,7 @@ requires dynamic binding.
In a multi-method all parameters that have an object type are used for the
dispatching:
.. code-block:: nimrod
.. code-block:: nim
type
TThing = object of TObject
@ -336,7 +336,7 @@ As the example demonstrates, invocation of a multi-method cannot be ambiguous:
Collide 2 is preferred over collide 1 because the resolution works from left to
right. Thus ``TUnit, TThing`` is preferred over ``TThing, TUnit``.
**Perfomance note**: Nimrod does not produce a virtual method table, but
**Perfomance note**: Nim 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.
@ -345,7 +345,7 @@ evaluation or dead code elimination do not work with methods.
Exceptions
==========
In Nimrod exceptions are objects. By convention, exception types are
In Nim exceptions are objects. By convention, exception types are
prefixed with an 'E', not 'T'. The `system <system.html>`_ module defines an
exception hierarchy that you might want to stick to. Exceptions derive from
E_Base, which provides the common interface.
@ -364,7 +364,7 @@ Raise statement
---------------
Raising an exception is done with the ``raise`` statement:
.. code-block:: nimrod
.. code-block:: nim
var
e: ref EOS
new(e)
@ -375,7 +375,7 @@ If the ``raise`` keyword is not followed by an expression, the last exception
is *re-raised*. For the purpose of avoiding repeating this common code pattern,
the template ``newException`` in the ``system`` module can be used:
.. code-block:: nimrod
.. code-block:: nim
raise newException(EOS, "the request to the OS failed")
@ -384,7 +384,7 @@ Try statement
The ``try`` statement handles exceptions:
.. code-block:: nimrod
.. code-block:: nim
# read the first two lines of a text file that should contain numbers
# and tries to add them
var
@ -428,7 +428,7 @@ If you need to *access* the actual exception object or message inside an
<system.html#getCurrentExceptionMsg>`_ procs from the `system <system.html>`_
module. Example:
.. code-block:: nimrod
.. code-block:: nim
try:
doSomethingHere()
except:
@ -460,7 +460,7 @@ instance, if you specify that a proc raises ``EIO``, and at some point it (or
one of the procs it calls) starts raising a new exception the compiler will
prevent that proc from compiling. Usage example:
.. code-block:: nimrod
.. code-block:: nim
proc complexProc() {.raises: [EIO, EArithmetic].} =
...
@ -476,21 +476,21 @@ help you locate the offending code which has changed.
If you want to add the ``{.raises.}`` pragma to existing code, the compiler can
also help you. You can add the ``{.effects.}`` pragma statement to your proc and
the compiler will output all inferred effects up to that point (exception
tracking is part of Nimrod's effect system). Another more roundabout way to
find out the list of exceptions raised by a proc is to use the Nimrod ``doc2``
tracking is part of Nim's effect system). Another more roundabout way to
find out the list of exceptions raised by a proc is to use the Nim ``doc2``
command which generates documentation for a whole module and decorates all
procs with the list of raised exceptions. You can read more about Nimrod's
procs with the list of raised exceptions. You can read more about Nim's
`effect system and related pragmas in the manual <manual.html#effect-system>`_.
Generics
========
Generics are Nimrod's means to parametrize procs, iterators or types
Generics are Nim's means to parametrize procs, iterators or types
with `type parameters`:idx:. They are most useful for efficient type safe
containers:
.. code-block:: nimrod
.. code-block:: nim
type
TBinaryTree[T] = object # TBinaryTree is a generic type with
# with generic param ``T``
@ -557,7 +557,7 @@ is not hidden and is used in the ``preorder`` iterator.
Templates
=========
Templates are a simple substitution mechanism that operates on Nimrod's
Templates are a simple substitution mechanism that operates on Nim's
abstract syntax trees. Templates are processed in the semantic pass of the
compiler. They integrate well with the rest of the language and share none
of C's preprocessor macros flaws.
@ -566,7 +566,7 @@ To *invoke* a template, call it like a procedure.
Example:
.. code-block:: nimrod
.. code-block:: nim
template `!=` (a, b: expr): expr =
# this definition exists in the System module
not (a == b)
@ -585,7 +585,7 @@ for IEEE floating point numbers - NaN breaks basic boolean logic.)
Templates are especially useful for lazy evaluation purposes. Consider a
simple proc for logging:
.. code-block:: nimrod
.. code-block:: nim
const
debug = true
@ -602,7 +602,7 @@ evaluation for procedures is *eager*).
Turning the ``log`` proc into a template solves this problem:
.. code-block:: nimrod
.. code-block:: nim
const
debug = true
@ -618,32 +618,11 @@ The parameters' types can be ordinary types or the meta types ``expr``
(stands for *type description*). If the template has no explicit return type,
``stmt`` is used for consistency with procs and methods.
The template body does not open a new scope. To open a new scope use a ``block``
statement:
.. code-block:: nimrod
template declareInScope(x: expr, t: typeDesc): stmt {.immediate.} =
var x: t
template declareInNewScope(x: expr, t: typeDesc): stmt {.immediate.} =
# open a new scope:
block:
var x: t
declareInScope(a, int)
a = 42 # works, `a` is known here
declareInNewScope(b, int)
b = 42 # does not work, `b` is unknown
(The `manual explains <manual.html#ordinary-vs-immediate-templates>`_ why the
``immediate`` pragma is needed for these templates.)
If there is a ``stmt`` parameter it should be the last in the template
declaration. The reason is that statements can be passed to a template
via a special ``:`` syntax:
.. code-block:: nimrod
.. code-block:: nim
template withFile(f: expr, filename: string, mode: TFileMode,
body: stmt): stmt {.immediate.} =
@ -672,18 +651,18 @@ Macros
======
Macros enable advanced compile-time code transformations, but they cannot
change Nimrod's syntax. However, this is no real restriction because Nimrod's
syntax is flexible enough anyway. Macros have to be implemented in pure Nimrod
change Nim's syntax. However, this is no real restriction because Nim's
syntax is flexible enough anyway. Macros have to be implemented in pure Nim
code if `foreign function interface (FFI)
<manual.html#foreign-function-interface>`_ is not enabled in the compiler, but
other than that restriction (which at some point in the future will go away)
you can write any kind of Nimrod code and the compiler will run it at compile
you can write any kind of Nim code and the compiler will run it at compile
time.
There are two ways to write a macro, either *generating* Nimrod source code and
There are two ways to write a macro, either *generating* Nim source code and
letting the compiler parse it, or creating manually an abstract syntax tree
(AST) which you feed to the compiler. In order to build the AST one needs to
know how the Nimrod concrete syntax is converted to an abstract syntax tree
know how the Nim concrete syntax is converted to an abstract syntax tree
(AST). The AST is documented in the `macros <macros.html>`_ module.
Once your macro is finished, there are two ways to invoke it:
@ -698,13 +677,13 @@ Expression Macros
The following example implements a powerful ``debug`` command that accepts a
variable number of arguments:
.. code-block:: nimrod
# to work with Nimrod syntax trees, we need an API that is defined in the
.. code-block:: nim
# to work with Nim syntax trees, we need an API that is defined in the
# ``macros`` module:
import macros
macro debug(n: varargs[expr]): stmt =
# `n` is a Nimrod AST that contains a list of expressions;
# `n` is a Nim AST that contains a list of expressions;
# this macro returns a list of statements:
result = newNimNode(nnkStmtList, n)
# iterate over any argument that is passed to this macro:
@ -727,7 +706,7 @@ variable number of arguments:
The macro call expands to:
.. code-block:: nimrod
.. code-block:: nim
write(stdout, "a[0]")
write(stdout, ": ")
writeln(stdout, a[0])
@ -751,7 +730,7 @@ invoked by an expression following a colon.
The following example outlines a macro that generates a lexical analyzer from
regular expressions:
.. code-block:: nimrod
.. code-block:: nim
macro case_token(n: stmt): stmt =
# creates a lexical analyzer from regular expressions
@ -784,7 +763,7 @@ To give a footstart to writing macros we will show now how to turn your typical
dynamic code into something that compiles statically. For the exercise we will
use the following snippet of code as the starting point:
.. code-block:: nimrod
.. code-block:: nim
import strutils, tables
@ -848,7 +827,7 @@ time string with the *generated source code*, which we then pass to the
``parseStmt`` proc from the `macros module <macros.html>`_. Here is the
modified source code implementing the macro:
.. code-block:: nimrod
.. code-block:: nim
import macros, strutils
macro readCfgAndBuildSource(cfgFilename: string): stmt =
@ -893,13 +872,13 @@ this limitation by using the ``slurp`` proc from the `system module
``gorge`` which executes an external program and captures its output).
The interesting thing is that our macro does not return a runtime ``TTable``
object. Instead, it builds up Nimrod source code into the ``source`` variable.
object. Instead, it builds up Nim source code into the ``source`` variable.
For each line of the configuration file a ``const`` variable will be generated.
To avoid conflicts we prefix these variables with ``cfg``. In essence, what the
compiler is doing is replacing the line calling the macro with the following
snippet of code:
.. code-block:: nimrod
.. code-block:: nim
const cfgversion= "1.1"
const cfglicenseOwner= "Hyori Lee"
const cfglicenseKey= "M1Tl3PjBWO2CC48m"
@ -919,14 +898,14 @@ Generating AST by hand
++++++++++++++++++++++
To generate an AST we would need to intimately know the structures used by the
Nimrod compiler exposed in the `macros module <macros.html>`_, which at first
Nim compiler exposed in the `macros module <macros.html>`_, which at first
look seems a daunting task. But we can use as helper shortcut the ``dumpTree``
macro, which is used as a statement macro instead of an expression macro.
Since we know that we want to generate a bunch of ``const`` symbols we can
create the following source file and compile it to see what the compiler
*expects* from us:
.. code-block:: nimrod
.. code-block:: nim
import macros
dumpTree:
@ -969,7 +948,7 @@ identifier, optionally a type (can be an *empty* node) and the value. Armed
with this knowledge, let's look at the finished version of the AST building
macro:
.. code-block:: nimrod
.. code-block:: nim
import macros, strutils
macro readCfgAndBuildAST(cfgFilename: string): stmt =