Control structures
Control structures are fundamental elements in programming that allow controlling the execution flow of a program. These structures allow making decisions, repeating code blocks, and handling errors (the latter, with try and catch, is in Errors and exceptions).
In JARU, all control structures, such as if, else, elsif, while, for, etc., must end with the keyword end. This indicates to the compiler that the control structure has ended. Using end is necessary to avoid syntax errors and to maintain a clean and easy-to-understand code structure. The rules for parentheses and then are in Basic syntax.
If-then-else flow
The if-then-else control structure is one of the most basic control structures in programming. It's used to make decisions based on a given condition. The basic syntax is as follows:
if (condition) then
// code to execute if the condition is true
else
// code to execute if the condition is false
end
The elsif clause is an extension of if-then-else that allows evaluating multiple conditions in a single control structure. The code will execute in the first block where the condition is met:
if (condition1) then
// code to execute if condition1 is true
elsif (condition2) then
// code to execute if condition2 is true
else
// code to execute if no previous condition is true
end
Switch-case flow
The switch-case control structure is a way to control program flow by selecting different paths based on a variable or expression. It's similar to using multiple nested if-else structures, but has the advantage of being more readable and easier to maintain.
switch (variable or expression)
case value1:
// instructions
case value2, value3:
// instructions
default:
// instructions
end
The expression is evaluated and compared with each of the case values. If a match is found, the instructions associated with that case are executed. If no match is found, the default instructions are executed.
func dayType(day)
switch (day)
case 1, 2, 3, 4, 5:
return "weekday"
case 6, 7:
return "weekend"
default:
return "does not exist"
end
end
println(dayType(3)) // weekday
println(dayType(7)) // weekend
println(dayType(9)) // does not exist
- There is no fall-through from one
caseto the next. When the block of acaseends, theswitchends: you don't needbreak, and it doesn't work for that either (see break and continue). - A
caseaccepts several values, separated by commas:case "A", "a":. - Values are compared as with
==.1matches1.0, and strings match by their content. A list, a map or an object only matches itself, not another one with the same contents. - The values can be expressions: variables, constants, enumerations (
case State.JUMPING:) or calculations. - The first matching
casewins, in the order they are written.defaultonly runs if none matches, even if it is written before thecases, and there can only be one. - If none matches and there is no
default, nothing runs. - The expression goes in parentheses, and each
caseand thedefaultend in:.
With strings:
var key = "a"
switch (key)
case "A", "a":
println("left")
case "D", "d":
println("right")
default:
println("another key")
end
With switch (true), each case can be a condition, and the first one that holds wins:
var score = 75
switch (true)
case score >= 90:
println("Excellent")
case score >= 50:
println("Pass")
default:
println("Fail")
end
For loop
The for structure in JARU is used to perform a controlled loop. The basic syntax is as follows:
for (initialization; condition; increment)
// loop body
end
The initialization is the expression executed at the beginning of the loop, usually a variable that will be used as a counter. The condition is an expression evaluated on each loop iteration; if the condition is false, the loop ends. The increment is the expression executed at the end of each loop iteration.
for (var i = 1; i <= 10; i++)
println(i)
end
In this example, the initialization is var i = 1, the condition is i <= 10, and the increment is i++. Each time the loop executes, the value of variable i is printed and incremented by 1.
You can create an infinite loop with for using the following syntax:
for (;;)
// loop body
end
Examples of for usage
Iterate a set number of times:
for (var i = 0; i < 10; i++)
println("Iteration ", i)
end
Iterate over a list:
var myList = [1, 2, 3, 4, 5]
for (var i = 0; i < 5; i++)
println("The element at position ", i, " is ", myList[i])
end
Iterate in reverse order:
for (var i = 10; i > 0; i--)
println("Iteration ", i)
end
Extended for
A unique feature of JARU is its extended for control structure, which adds filter functionality and alternative code to provide greater flexibility to programmers.
The extended for declaration in JARU follows this structure:
for (var i = start_value; i < end_value; i = i + increment_value; filter_condition)
// code to execute when the filter condition is true
elfor
// alternative code to execute when the filter condition is false
end
Structure analysis
- Initialization:
var i = start_value;This is where the loop control variable is initialized. - Condition:
i < end_value;This is the condition evaluated before each loop iteration. - Update:
i = i + increment_value;This is the operation performed after each loop iteration. - Filter:
filter_conditionA unique JARU feature that allows setting an additional condition that must be met for the code inside the loop to execute. - Alternative code:
elforAllows specifying an alternative code block that will execute when the filter condition is not met. - Termination:
endMarks the end of theforblock.
Extended for examples
// FOR loop with filter (only prints even numbers)
for (var i = 0; i < 10; i = i + 1; i % 2 == 0)
println(i)
end
// FOR loop with filter and alternative (prints "odd" for odd numbers)
for (var i = 0; i < 10; i = i + 1; i % 2 == 0)
println(i)
elfor
println("odd")
end
Extended for use cases
Processing only certain elements:
var list = [1, 2, 3, 4, 5, 6]
for (var i = 0; i < list.size(); i++; list[i] % 2 == 0)
println(list[i])
end
Handling exceptions or special conditions:
var data = [10, -3, 25]
for (var i = 0; i < data.size(); i++; data[i] >= 0)
println("Processing ", data[i])
elfor
println("Invalid data at index: ", i)
end
Nested loops with extended features:
var users = [
{"name": "Ana", "transactions": [50, 5000]},
{"name": "Luis", "transactions": [20]}
]
for (var i = 0; i < users.size(); i++)
var transactions = users[i]["transactions"]
for (var j = 0; j < transactions.size(); j++; transactions[j] > 1000)
println("Fraudulent transaction detected for user ", users[i]["name"])
elfor
println("Transaction OK: ", transactions[j])
end
end
The extended for is especially useful when you need to process data collections with complex conditions, avoiding the need to nest multiple if structures inside the loop.
Foreach loop
The foreach control structure in JARU is used to iterate through elements of a collection, such as a list, map, or array. The basic syntax is as follows:
foreach (var element in collection)
// code to execute for each element
end
Where element is a temporary variable that takes the value of each element in the collection on each loop iteration. The loop body is executed for each element in the collection.
var list = [1, 2, 3, 4, 5]
foreach (var number in list)
println(number) // Shows 1, 2, 3, 4 and 5
end
In this case, the variable number takes the value of each element in the list on each iteration, and the code inside the foreach block runs for each element.
The loop automatically stops once all elements in the collection have been traversed.
What foreach goes through in each type (lists, maps, arrays and strings) and how to change the elements from inside the loop is in Walking through them with foreach.
While loop
The while control structure in JARU is a loop that executes while a given condition is met. The condition is evaluated at the beginning of each iteration, and if it's true, the loop body executes. If the condition is false, the loop stops and continues with the next line of code.
while (condition)
// Code block to execute
end
If you want an infinite loop with while, all you have to do is make the condition true:
while (true)
// Code block to execute
end
Example:
var i = 0
while (i < 10)
println("Variable i has value ", i)
i += 1
end
In this example, the condition is i < 10, so the loop executes 10 times, printing the value of variable i on each iteration.
It's important to be careful to include a way to stop the loop, either by changing the condition within the loop body or using an additional control structure; otherwise, the loop will run indefinitely.
Until loop
The until loop in JARU is used to repeat a code block until a certain condition is met.
until (condition)
// code block
end
In this code, the condition is a boolean expression that is evaluated before each loop iteration. If the condition is false, the code block inside the loop will execute and then the condition will be evaluated again. This process will continue until the condition is true, at which point the loop will exit.
Example that prints numbers from 1 to 10:
var i = 1
until (i > 10)
println(i)
i++
end
Another example, a countdown from a given number to zero:
var number = 10
until (number == 0)
println(number)
number = number - 1
end
println("Liftoff!")
Difference between while and until
Both until and while are flow control structures used to implement loops. The main difference is in how the exit condition is evaluated:
- In
until, the loop executes until the specified condition is true - In
while, the loop executes while the condition is true
It's important to note that the code block inside the loop must modify the condition in some way to avoid an infinite loop. Otherwise, the loop will run indefinitely.
Leaving a loop: break and continue
breakleaves the loop: the program carries on at the line after itsend.continuejumps to the next round. In afor, it goes through the increment first (i++); inwhileanduntil, it checks the condition again; inforeach, it moves on to the next element.
They work in for (also in the extended for), foreach, while and until.
for (var i = 1; i <= 10; i++)
if (i % 2 == 0) then
continue // skips the even numbers
end
if (i > 7) then
break // and stops after 7
end
print(i, " ")
end
println()
1 3 5 7
To search for something and stop searching as soon as it turns up:
var names = ["Ana", "Luis", "Eva", "Raúl"]
var position = -1
for (var i = 0; i < names.size(); i++)
if (names[i] == "Eva") then
position = i
break
end
end
println("Eva is at position ", position) // Eva is at position 2
- With nested loops, they only affect the inner one: a
breakin the inner loop does not leave the outer one. - Inside a
switch, they affect the loop that contains it.breakdoes not leave theswitch, but the loop:
var orders = ["forward", "turn", "jump", "stop", "forward"]
foreach (var order in orders)
switch (order)
case "stop":
break // leaves the foreach, not just the switch
case "jump":
continue // moves on to the next order
default:
println("Doing: ", order)
end
end
println("Done")
Doing: forward
Doing: turn
Done
- Outside a loop they do not compile, with the error “Cannot use 'break' outside of a loop.”. They don't work in a function called from a loop either: they have to be inside the loop itself. This
switchis not in any loop:
var option = 1
switch (option)
case 1:
println("one")
break // does not compile: there is no loop
end