Conditionals
if / else
There’s your traditional if, else if, else structure. The body should be either a single statement, or a scope.
if (off) turnOn()
if (stressed) {
breatheIn()
breatheOut()
} else if (tired) {
rest()
} else {
allGood()
}
The condition can be of type Bool
or a Pointer, in which case it will evaluate to
true
if it is non-null.
match / case
match
is ooc’s switch
, loosely modelled after Scala’s. In its simplest form, it tests for equality between an expression and several values:
match (numFeets) {
case 1 => "Ouch"
case 2 => "Normal"
case =>
// what?
raise("Too many feet")
}
Each case is a scope of its own - it doesn’t require braces. A case with no expression is a catch-all.
match
also works with any class T that implements the method matches?: func
-> (other: T) -> Bool
. Another way to get complex types to work in matches
is simply to override the ==
operator. Hence, Strings work:
match keyword {
case "if" =>
Keyword IF
case "match" =>
Keyword MATCH
case =>
Keyword UNKNOWN
}
match
is also a good way to avoid explicit casting, by matching an object
against variable declarations, one can use its specific form directly:
result := match (op) {
case plus: Plus =>
plus lhs + plus rhs
case minus: Minus =>
minus lhs - minus rhs
}
A match
is an expression, if every case ends with an expression. Hence, a
match can be used as a return value, or in a function call, on the right hand
side of a declaration-assignment (:=
), as demonstrated above.
Loops
Loops are structures that control the repetition of a body of code.
break / continue
Two particular keywords are of interest when writing loops:
-
break
immediately exits the loop, skipping the rest of the body and not executing any further iteration -
continue
skips over the rest of the body and begins the next iteration immediately
while
Checks the condition - if false, skips the body. If true, runs the body, then checks the condition again, etc.
while (!satisfied) {
buyStuff()
}
for
There is no C-like for
in ooc, only a foreach. It can iterate through
values like ranges:
for (i in 1..10) {
"Counting to #{i}" println()
}
Or more complex data structures:
for (element in list) {
"Element = #{element}" println()
}
For an object to be iterable, it has to implement the
iterator: func <T> -> Iterator<T>
method.
A variant of foreach allows one to get the index of the current element:
for ((i, el) in list) {
"list[#{i}] = #{el}" println()
}