doc: misc proofread
[nit.git] / doc / manual / structure.md
1 # Control Structures
2
3 Traditional procedural control structures exist in Nit. They
4 also often exist in two versions: a one-liner and a block version.
5
6 ## Control Flow
7
8 Control structures dictate the control flow of the
9 program. Nit heavily refers to the control flow in its specification:
10
11 -   No unreachable statement;
12
13 -   No usage of undefined variables;
14
15 -   No function without a `return` with a value;
16
17 -   Adaptive typing.
18
19 Some structures alter the control flow, but are not described in this
20 section: `and`, `or`, `not`, `or else` and `return`.
21
22 Note that the control flow is determined only from the position, the
23 order and the nesting of the control structures. The real value of the
24 expressions used has no effect on the control flow analyses.
25
26 ~~~nitish
27 if true then
28     return
29 else
30     return
31 end
32 print 1 # Compile error: unreachable statement
33 ~~~
34
35 ~~~
36 if true then
37     return
38 end
39 print 1 # OK, but never executed
40 ~~~
41
42 ## if
43
44 ~~~
45 var exp = true
46 # ...
47 if exp then print 1
48 if exp then print 2 else print 2
49 if exp then
50     print 1
51     print 2
52 end
53
54 if exp then
55     print 1
56     print 2
57 else if exp then
58     print 10
59     print 20
60 else
61     print 100
62     print 200
63 end
64 ~~~
65
66 Note that the following example is invalid since the first line is
67 syntactically complete thus the newline terminate the whole `if`
68 structure; then an error is signaled since a statement cannot begin with
69 `else`.
70
71 ~~~nitish
72 if exp then print 1 # OK: complete 'if' structure
73 else print 2 # Syntax error: unexpected 'else'
74 ~~~
75
76 ## while
77
78 ~~~
79 var x = 0
80 while x < 10 do x += 1
81 print x # outputs 10
82
83 while x < 20 do
84     print x # outputs 10 11 ... 19
85     x += 1
86 end
87 ~~~
88
89 ## for
90
91 `for` declares an automatic variable used to iterates on `Collection` (`Array` and `Range` are both `Collection`).
92
93 ~~~
94 for i in [1..5] do print i # outputs 1 2 3 4 5
95 for i in [1, 4, 6] do
96     print i # outputs 1 4 6
97 end
98 ~~~
99
100 `for` can also be used with reversed ranges to iterate in reverse order.
101
102 Step can also be used to specify the size of each increment at the end of a for cycle.
103
104 ~~~
105 for i in [9 .. 4].step(-1) do print i # outputs 9 8 7 6 5 4
106 for i in [9 .. 4[.step(-2) do print i # outputs 9 7 5
107 ~~~
108
109 ## loop
110
111 Infinite loops are mainly used with breaks. They are useful to implement *until* loops or to simulate the *exit when* control of Ada.
112
113 ~~~
114 loop
115     print 1
116     if exp then break
117     print 2
118 end
119 ~~~
120
121 Note that `loop` is different from `while true` because the control flow does not consider the values of expressions.
122
123 ## do
124
125 Single `do` are used to create scoped variables or to be attached with labeled breaks.
126
127 ~~~
128 do
129     var j = 5
130     print j
131 end
132 # j is not defined here
133 ~~~
134
135 ## break, continue and label
136
137 Unlabeled `break` exits the current `for`, `while`, `loop`, Unlabeled `continue` skips the current `for`, `while`, `loop`.
138
139 `label` can be used with `break` or `continue` to act on a specific control structure (not necessary the current one). The corresponding `label` must be defined after the `end` keyword of the designated control structure.
140
141 ~~~
142 for i in [0..10[ do
143     for j in [0..10[ do
144         if i + j > 15 then break label outer_loop
145         print "{i},{j}"
146         # The 'break' breaks the 'for i' loop
147     end
148 end label outer_loop
149 ~~~
150
151 `label` can also be used with `break` and single `do` structures.
152
153 ~~~
154 do
155     print 1 # printed
156     if exp then break label block
157     print 2 # not printed because exp is true
158 end label block
159 ~~~
160
161 ## abort
162
163 `abort` stops the program with a fatal error and prints a stack trace. Since there is currently no exception nor run-time-errors, abort is somewhat used to simulate them.
164
165 ## assert
166
167 `assert` verifies that a given Boolean expression is true, or else it aborts. An optional label can be precised, it will be displayed on the error message. An optional `else` can also be added and will be executed before the abort.
168
169 ~~~
170 assert bla: exp else
171     # `bla` is the label
172     # `exp` is the expression to verify
173     print "Fatal error in module blablabla."
174     print "Please contact the customer service."
175 end
176 ~~~