Rogue is an imperative language and like one it has control flow - a way to make schoice whether to run block of code or to skip or to run another one instead.
In Rogue you have loops (
if expression allows you to run a block of code if some condition is true, and to run another block instead if condition resulted in false.
In this example we've used
block to print
a == true and if a is
false - then
99 is printed. Simple as that, if syntax is:
if is an expression, and like all of them it must end with semicolon. This is also a reason to use it with
b will be assigned a different value depending on the
a expression. But both of the branches in
if must return the same type! Otherwise variable
b will have an option to be of different kind (or undefined) and this is impossible in statically typed language. In compiler terms it's called branch compatibility - both of the branches must return compatible (same) type.
if can be used in-solo - without
But keep in mind that
if expression without
else branch cannot be used in assignment as when condition is not met - alternative branch is not called and variable may be undefined which is, again, impossible.
There're two ways of defining loops in Rogue:
- Conditional loop with
Conditional loop with
while is a way to define loop - expression which will be executed while some condition is true. So simply: code will be run over and over while condition is
true. To implement condition usually an external variable (or counter) is used.
It's worth mentioning that
while is an expression - just like
if is, and it too requires a semicolon afterwards. Generic syntax for while loop is:
while cannot return a value, so variable assignment (like we did with
if expression) is impossible.
To be reliable Rogue must be secure. This is why it obliges you to use all your variables and for the same reason it forbids having unreachable code. As digital assets are programmable, they can be used in code (you'll learn about it in resources chapter), and placing them in unreachable areas may lead to inconvenience and their loss as the result.
This is why unreachable code is such a big issue. Now that is clear, we can proceed.
There is a way to define infinite loops. They're non-conditional and actually infinite (unless you force them to stop). Unfortunately the compiler cannot define whether a loop is infinite (in most of the cases) and cannot stop you from publishing code, execution of which will consume all given resources (in blockchain terms - gas). So it's on you to test your code properly when using them or just switch to conditional
while as it's way more secure.
Infinite loops are defined with keyword
However this is possible (compiler will let you do this):
It's a non-trivial task for the compiler to understand whether a loop is really infinite or not, so for now you and only you can help yourself avoid looping errors. As described above, this can lead to assets loss.
Control loops with
break allow you to skip one round or break iteration respectively. You can use both of them in both types of loops.
For example let's add two conditions into the
i is even, we use
continue to jump to the next iteration without going through code after
break we stop iteration and exit loop.
About semicolons. If
continue are the last keywords in block, you can't put a semicolon after them as any code after won't be executed. Somehow even semi can't be put. See this:
Sometimes you need to abort execution of transaction when some condition has failed. For that case there's keyword
abort allows you to abort execution with an error code which is placed right after.
assert(<condition>, <code>) method already wraps
abort + condition and is accessible anywhere in code:
assert() will abort execution when condition is not met, or it will do nothing in the opposite case.