Verse shipped with an if statement / expression, but it’s quickly becomes apparent that the languages often times suffers from the great pyramid of doom phenomenon.
if (...) {
if (...) {
if(...) {
...
}
}
}
Being used to Swift development I fell in love with the guard statement.
Guard Statement
A
guardstatement is used to transfer program control out of a scope if one or more conditions aren’t met.A
guardstatement has the following form:guard <#condition#> else { <#statements#> }The value of any condition in a
guardstatement must be of typeBoolor a type bridged toBool. The condition can also be an optional binding declaration, as discussed in Optional Binding.Any constants or variables assigned a value from an optional binding declaration in a
guardstatement condition can be used for the rest of the guard statement’s enclosing scope.The
elseclause of aguardstatement is required, and must either call a function with theNeverreturn type or transfer program control outside the guard statement’s enclosing scope using one of the following statements:
returnbreakcontinuethrow
The guard statement allows one to inverse some control flow and keep the execution within the same scope level instead of moving into a new then branch.
Here’s a quick example from Swift:
func foo() -> Int? {
if condition {
if let unwrappedInt = someOptionalInt {
if otherCondition {
doSomeWork()
return unwrappedInt
}
}
}
cleanUpWork()
return nil
}
func foo() -> Int? {
guard condition, let unwrappedInt = someOptionalInt, otherCondition else {
cleanUpWork()
return nil
}
// we escaped the if pyramid
doSomeWork()
return unwrappedInt
}
This example is not a question if the code can be restructured to return an int or fail, it’s just a trivial example of a possible if pyramid of doom!
I can partly achieve something similar for some use case in verse, but it’s a bit verbose.
Func(): void = {
Value := if (UnwrappedValue := OptionalValue?) {
UnwrappedValue
} else {
return
}
Something := if (UnwrappedThing := OptionalThing?) {
UnwrappedThing
} else {
return
}
# use `Value` and `Something` from here
}
It would be great if verse gained a native solution for a guard statement (and possibly an expression?).