So far everything we've typed in was executed exactly once, but there are far more useful behaviours than that. In this section we'll write programs that make decisions and that repeat steps.
if
statements
>>>> if 31*31 < 1000 {
.... print("Less\n")
.... } else {
.... print("More\n")
.... }
Less
This statement contains two print
statements, but only the
first one is executed, because 31*31
is 961 which
is less than 1000. If you change it to 32*32
then the second one will be executed instead.
The word if
is a keyword. The expression after it is called the condition. It's a separable part, and we can type it in on its own:
>>>> 31*31 < 1000
true: bool
Note that the type is bool
; the condition has to be a boolean expression.
Next comes a block of statements, enclosed in {
and }
. In general, there can be zero or more statements here. There's exactly one statememt in our example. It's a separable piece, and we can type it in on its own:
>>>> print("Less\n")
Less
Note that the {
and }
are part of the if
statement; you have to omit them when you pull the print
statement out. Note also that we indented the print
statement when it was inside the if
statement; you don't have to do this, but it's helpful for people reading the code. Statements in Welly are sometimes nested quite deeply, and without the indentation it can be difficult to tell what's inside what.
The word else
is another keyword. After that comes a second block of statements. You can omit everything from else
onwards; if you do, it means the same thing as leaving the second block empty.
You probably noticed that the if
example runs onto five lines.
You can actually write it all on one line if you prefer:
>>>> if 31*31 < 1000 { print("Less\n") } else { print("More\n") }
Less
If you do use the five-line version, nothing happens until you press "Enter" for the fifth time. Before that, Welly just prints ....
instead of the usual >>>>
to let you know that it's waiting for more input.
If you make a mistake while typing in a long statement, make sure you get the >>>>
prompt back before trying again. If you don't, Welly will probably think you're just continuing on from where you got to. A good trick for telling Welly not to wait for more input is to type lots of close bracket characters; that usually gives a harmless error:
>>>> if 31*31 < 1000 {
....
....
.... )))))))))))))
ASTError: Unmatched "{"
at line 13, col 17
if 31*31 < 1000 {
^
Read more about newlines.
If you've ever used C-family programming language such as C, C++, C#, Java or Javascript, the if
syntax is probably quite familiar. There are three slight differences:
{
and }
, even if there is only one statement inside. Omitting the braces has proved to cause bugs in other languages, so it's forbidden in Welly.else
. If you do, Welly has no way of knowing whether you plan on typing else
next. In this situation it makes a guess that you're going to omit the else
clause.while
statements>>>> var x = 20; >>>> while x*x < 1000 { .... print("Less\n") .... x += 1 .... } else { .... print("More\n") .... }
Less Less Less Less Less Less Less Less Less Less Less Less More>>>> x
32: int
The syntax of a while
statement is the same as that of an if
statement apart from the initial keyword. The meaning is the same, except that if the condition is true, after executing the first block of statements Welly repeats the entire while
statement. The optional else
clause is executed when the condition is false.
In this example, the while
statement is executed thirteen times: once for each value of x
from 20 to 32 inclusive. The first twelve times, the condition is true, so the first block is executed and the loop repeats. The last time, the condition is false so the second block is executed and the loop exits.
The statement x += 1
is an abbreviation for x = x + 1
. This is the line which changes the value of x
on each iteration, such that the loop eventually terminates.
break
and continue
>>>> const n = 2047
>>>> var x = 3
>>>> while x*x < n {
.... if n % x == 0 {
.... print("Composite\n")
.... x
.... break
.... }
.... x += 1
.... } else {
.... print("Prime\n")
.... }
Composite
23: int
The above code tries to find a number that divides exactly into 2047. It finds one: 23.
The control flow is similar to the previous example. x
starts at 3, and increases by one on each iteration of the loop. If ever x
were to become large enough (46*46
exceeds 2047) the loop would exit and the word "Prime" would be printed. However, x
never gets that big, because of the break
statement.
When x
reaches 23, the condition of the if
statement is true (2047 % 23
computes the remainder when 2047 is divided by 23). As usual, you can verify it:
>>>> 2047 % 23
0: int
At that moment, Welly executes the block of statements inside the if
statement. It prints the word "Composite". The next line, x
, is an expression, so it prints its value and type. Then it executes break
, which terminates the loop immediately without executing the else
clause.
The continue
statement is similar; it modifies the control flow of the enclosing loop. Whereas break
causes the entire loop to terminate, continue
only causes the current iteration to terminate. Welly executes the next iteration as normal.
>>>> var x = 0
>>>> while x < 20 {
.... x += 1
.... if x % 3 == 0 { print("Fizz\n"); continue }
.... if x % 7 == 0 { print("Buzz\n"); continue }
.... x
.... }
1: int
2: int
Fizz
4: int
5: int
Fizz
Buzz
8: int
Fizz
10: int
11: int
Fizz
13: int
Buzz
Fizz
16: int
17: int
Fizz
19: int
20: int
The above code prints out all numbers up to 20 that are not divisible by 3 or 7. Numbers that are divisible by 3 are replace by "Fizz", and those that are divisible by 7 are replaced by "Buzz".
Note that we've moved the increment operation to the beginning of the loop. If we hadn't, the loop would run for ever. Try it.
Each of the if
statements in this example has two statements inside it, written on a single line. We have to separate the statements with a semicolon (;
).