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
guard
statement is used to transfer program control out of a scope if one or more conditions aren’t met.A
guard
statement has the following form:guard <#condition#> else { <#statements#> }
The value of any condition in a
guard
statement must be of typeBool
or 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
guard
statement condition can be used for the rest of the guard statement’s enclosing scope.The
else
clause of aguard
statement is required, and must either call a function with theNever
return type or transfer program control outside the guard statement’s enclosing scope using one of the following statements:
return
break
continue
throw
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?).