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 iterationcontinue
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()
}