summary refs log tree commit diff stats
path: root/doc/tutorial.txt
blob: 795fc0d90da348de2064d23dd6b4facad77790b9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
===========================================
Tutorial of the Nimrod Programming Language
===========================================

:Author: Andreas Rumpf

Motivation
==========

Why yet another programming language?

Look at the trends behind all the new programming languages:

* They try to be dynamic: Dynamic typing, dynamic method binding, etc.
  In my opinion the most things the dynamic features buy could be achieved
  with static means in a more efficient and *understandable* way. 

* They depend on big runtime environments which you need to
  ship with your program as each new version of these may break compability
  in subtle ways or you use recently added features - thus forcing your
  users to update their runtime environment. Compiled programs where the
  executable contains all needed code are simply the better solution. 

* They are unsuitable for systems programming: Do you really want to
  write an operating system, a device driver or an interpreter in a language
  that is just-in-time compiled (or interpreted)?


So what lacks are *good* systems programming languages. Nimrod is such a
language. It offers the following features:

* It is readable: It reads from left to right (unlike the C-syntax
  languages).
* It is strongly and statically typed: This enables the compiler to find
  more errors. Static typing also makes programs more *readable*.
* It is compiled. (Currently this is done via compilation to C.)
* It is garbage collected. Big systems need garbage collection. Manuell
  memory management is also supported through *untraced pointers*.
* It scales because high level features are also available: It has built-in
  bit sets, strings, enumerations, objects, arrays and dynamically resizeable
  arrays (called *sequences*).
* It has high performance: The current implementation compiles to C
  and uses a Deutsch-Bobrow garbage collector together with Christoper's
  partial mark-sweep garbage collector leading to excellent execution
  speed and a small memory footprint.
* It has real modules with proper interfaces and supports separate
  compilation.
* It is portable: It compiles to C and platform specific features have
  been separated and documented. So even if your platform is not supported
  porting should be easy.
* It is flexible: Although primilarily a procedural language, generic,
  functional and object-oriented programming is also supported.
* It is easy to learn, easy to use and leads to elegant programs.
* You can link an embedded debugger to your program (ENDB). ENDB is
  very easy to use - there is no need to clutter your code with
  ``echo`` statements for proper debugging.


Introduction
============

This document is a tutorial for the programming language *Nimrod*. It should
be a readable quick tour through the language instead of a dry specification
(which can be found `here <manual.html>`_). This tutorial assumes that
the reader already knows some other programming language such as Pascal. Thus
it is detailed in cases where Nimrod differs from other programming languages
and kept short where Nimrod is more or less the same.


A quick tour through the language
=================================

The first program
-----------------

We start the tour with a modified "hallo world" program:

.. code-block:: Nimrod
  # This is a comment
  # Standard IO-routines are always accessible
  write(stdout, "What's your name? ")
  var name: string = readLine(stdin)
  write(stdout, "Hi, " & name & "!\n")


Save this code to the file "greeting.nim". Now compile and run it::

  nimrod compile --run greeting.nim

As you see, with the ``--run`` switch Nimrod executes the file automatically
after compilation. You can even give your program command line arguments by
appending them after the filename that is to be compiled and run::

  nimrod compile --run greeting.nim arg1 arg2

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. String literals
are enclosed in double quotes. The ``var`` statement declares a new variable
named ``name`` of type ``string`` with the value that is returned by the
``readline`` procedure. Since the compiler knows that ``readline`` returns
a string, you can leave out the type in the declaration. So this will work too:

.. code-block:: Nimrod
  var name = readline(stdin)

Note that this is the only form of type inference that exists in Nimrod:
This is because it yields a good compromise between brevity and readability.

The ``&`` operator concates strings together. ``\n`` stands for the
new line character(s). On several operating systems ``\n`` is represented by
*two* characters: Linefeed and Carriage Return. That is why
*character literals* cannot contain ``\n``. But since Nimrod handles strings
so well, this is a nonissue.

The "hallo world" program contains several identifiers that are already
known to the compiler: ``write``, ``stdout``, ``readLine``, etc. These
built-in items are declared in the system_ module which is implicitly
imported by any other module.


Lexical elements
----------------

Let us look into Nimrod's lexical elements in more detail: Like other
programming languages Nimrod consists of identifiers, keywords, comments,
operators, and other punctation marks. Case is *insignificant* in Nimrod and
even underscores are ignored: ``This_is_an_identifier`` and this is the same
identifier ``ThisIsAnIdentifier``. This feature enables one to use other
peoples code without bothering about a naming convention that one does not
like.

String literals are enclosed in double quotes, character literals in single
quotes. There exist also *raw* string and character literals:

.. code-block:: Nimrod
  r"C:\program files\nim"

In raw literals the backslash is not an escape character, so they fit
the principle *what you see is what you get*. *Long string literals*
are also available (``""" ... """``); they can span over multiple lines
and the ``\`` is not an escape character either. They are very useful
for embedding SQL code templates for example.

Comments start with ``#`` and run till the end of the line. (Well this is not
quite true, but you should read the manual for a proper explanation.)

... XXX number literals


The usual statements - if, while, for, case
-------------------------------------------

In Nimrod indentation is used to group statements.
An example showing the most common statement types:

.. code-block:: Nimrod
  var name = readLine(stdin)

  if name == "Andreas":
    echo("What a nice name!")
  elif name == "":
    echo("Don't you have a name?")
  else:
    echo("Boring name...")

  for i in 0..length(name)-1:
    if name[i] == 'm':
      echo("hey, there is an *m* in your name!")

  echo("Please give your password: \n")
  var pw = readLine(stdin)

  while pw != "12345":
    echo("Wrong password! Next try: \n")
    pw = readLine(stdin)

  echo("""Login complete!
  What do you want to do?
  delete-everything
  restart-computer
  go-for-a-walk
  """)

  case readline(stdin)
  of "delete-everything", "restart-computer":
    echo("permission denied")
  of "go-for-a-walk":     echo("please yourself")
  else:                   echo("unknown command")


..
  Types
  -----
  
  Nimrod has a rich type system. This tutorial only gives a few examples. Read
  the `manual <manual.html>`_ for further information:
  
  .. code-block:: Nimrod
    type
      TMyRecord = object
        x, y: int
  
  
  Procedures
  ----------
  
  Procedures are subroutines. They are declared in this way:
  
  .. code-block:: Nimrod
    proc findSubStr(sub: string,


.. _strutils: strutils.html
.. _system: system.html