At the moment, avalon provides two means of controlling the flow of a program, namely if the
if conditional and the
In the future, the
switch conditional and the
for loop will be added.
Conditional statements control the flow of the program allowing the program to choose which path the execution is to take depending on the whether a specific condition is fulfilled.
At the moment, only the
if conditional is implemented. It allows execution branching based on comparison between values
and based on whether values match through pattern matching.
if conditional is made of the main branch introduced by
if, optional multiple
and an optional
Let us first demonstrate how an
if statement can be used to perform branching using comparison.
import io -- we create a user global variable var user = ( name = "John Doe", age = 32 ) -- the program entry point def __main__ = (val args : [string]) -> void: -- we perform branching depending on the age of the user if user.age < 18: Io.println(user.name + " is a minor.") elif user.age >= 18 and user.age < 65: Io.println(user.name + " is an adult in education, employment or training.") elif user.age >= 65 and user.age < 120: Io.println(user.name + " is a senior retiring or retired.") else: Io.println(user.name + ", may you live another 120 years!")
As mentionned before, the
if statement can also be used to do pattern matching. We are going to adapt the previous example
to one that work with pattern matching using a user defined type.
import io -- our user type type user = (): User( name : string, age : int, alive: bool ) -- the program entry point def __main__ = (val args : [string]) -> void: var u = User( name = "John Doe", age = 32, alive = True ) -- we begin by matching against the user so we get the user details if u === User( name = n:string, -- the type instance must occur when capturing values age = a:int, alive = _ -- we use the underscore to let the compiler know that we are not interested in the <alive> field ): -- now we can use the capture values if a < 18: Io.println(n + " is a minor.") elif a >= 18 and a < 65: Io.println(n + " is an adult in education, employment or training.") elif a >= 65 and a < 120: Io.println(n + " is a senior retiring or retired.") else: Io.println(n + ", may you live another 120 years!") else: -- this branch will never execute because the type only has one value constructor and we are matching against it Io.println("We didn't get a valid user!")
That is pretty much all there is to the
if conditional statement.
Loop statements allow us to execute the same code multiple times until we decide to stop loop using either a
return statement if the condition is not met already.
while loop is currently implemented but the
for loop is in the works as well to allow range based looping.
while loop allows the looping to continue until the condition is no longer met or the loop is stopped using a
break or a
Pattern matching expressions can also figure as condition to loops and this will be demonstrated with a search example at the end of this section.
For the moment, let us see how to implement FizzBuzz.
import io def __main__ = (val args : [string]) -> void: -- the buzz counter var buzzer = 1 -- we keep looping so long as the buzzer is less than 101 while buzzer < 101: -- We print "Fizz" or "Buzz" or "FizzBuzz" or the number depending on our divisor if buzzer % 15 == 0: Io.println("FizzBuzz") elif buzzer % 3 == 0: Io.println("Fizz") elif buzzer % 5 == 0: Io.println("Buzz") else: Io.println(string(buzzer)) -- we don't forget to increment the buzzer else we end up with infinite loop buzzer = buzzer + 1 -- we end execution return
Example that combines conditional statements and loops¶
We are going to implement a generic linear search that uses comparison based conditional and pattern matching looping. The function itself is not complicated but combines different elements of what features in the documentation so if you are having trouble understanding the code, look in the reference.
import io -[ search Performs a linear search of the needle inside the given list. :params - list : [a*] A generic list of elements to search. - needle : a* A generic element to search. :returns - index : maybe(a*) `Just(i)` where `i` is the index where the needle was found, `None` if no element was found. ]- def search : a = (val list : [a], val needle : a) -> maybe(int): -- the current index and the element at that index var index = 0, current = list[index] -- perform the search -- notice how we are using pattern matching in the while loop itself while current === Just(value:a): if needle == value: return Just(index) else: index = index + 1 current = list[index] -- if we reach here, the needle wasn't found return None:maybe(int) -[ main The main entry point. :params - args : [string] A list of strings that were passed to the program as commandline arguments. :returns - nothing : void ]- def __main__ = (val args : [string]) -> void: -- search data val list = [1, 2, 3, 4], needle = 2 -- we perform the search var result = search(list, needle) -- we use pattern matching to see if we found the value and print the index where is was found if result === Just(index:int): Io.println("Found element <" + string(needle) + "> at index <" + string(index) + ">.") else: Io.println("Element <" + string(needle) + "> not found.") -- we are done return