Although not traditionally considered loops, the @goto
and @label
macros can be used for more advanced control flow. One use case is when the failure of one part should lead to the retry of an entire function, often useful in input validation:
function getsequence()
local a, b
@label start
print("Input an integer: ")
try
a = parse(Int, readline())
catch
println("Sorry, that's not an integer.")
@goto start
end
print("Input a decimal: ")
try
b = parse(Float64, readline())
catch
println("Sorry, that doesn't look numeric.")
@goto start
end
a, b
end
However, this use case is often more clear using recursion:
function getsequence()
local a, b
print("Input an integer: ")
try
a = parse(Int, readline())
catch
println("Sorry, that's not an integer.")
return getsequence()
end
print("Input a decimal: ")
try
b = parse(Float64, readline())
catch
println("Sorry, that doesn't look numeric.")
return getsequence()
end
a, b
end
Although both examples do the same thing, the second is easier to understand. However, the first one is more performant (because it avoids the recursive call). In most cases, the cost of the call does not matter; but in limited situations, the first form is acceptable.