Dear all,
I want to know how to use @label and @goto. Can you give me an example to use them?
Many thanks.
Dear all,
I want to know how to use @label and @goto. Can you give me an example to use them?
Many thanks.
The Julia docs probably should have an example.
The function below is horrendous, it is defined only for the purpose of this example, it could be rewritten to be much better but then it would not serve the purpose of illustrating @goto
/@label
.
The only motive I think it is reasonable to use @goto
is to break out of multiple loops at once. Other languages allow the keyword break
to be accompanied by a number indicating how many nested loops the break
is affecting (from the inner to outer). Julia does not have this feature so, for this specific use case, @goto
is more elegant than adding a lot of flags and if
s to achieve the same effect.
julia> function has_zero(A)
i, j = 0, 0
for outer i in 1:size(A, 1)
for outer j in 1:size(A, 2)
if iszero(A[i, j])
@goto after_loop
end
end
end
@label after_loop
if iszero(A[i, j])
return i, j
end
return false
end
has_zero (generic function with 1 method)
julia> A = [1 2 3; 4 5 6]
2×3 Array{Int64,2}:
1 2 3
4 5 6
julia> has_zero(A)
false
julia> A = [1 2 3; 0 5 6]
2×3 Array{Int64,2}:
1 2 3
0 5 6
julia> has_zero(A)
(2, 1)
What is the advantage of @goto
and @label
? In your example, Why not directly write the codes as below?
function has_zero(A)
i, j = 0, 0
for outer i in 1:size(A, 1)
for outer j in 1:size(A, 2)
if iszero(A[i, j])
return i, j
end
end
end
return false
end
julia> using Multibreak
julia> @multibreak function has_zero(A)
i, j = 0, 0
for outer i in 1:size(A, 1)
for outer j in 1:size(A, 2)
if iszero(A[i, j])
break; break
end
end
end
if iszero(A[i, j])
return i, j
end
return false
end
has_zero (generic function with 1 method)
The @multibreak
macro rewrites the double break
to exactly the same @goto
and @label
construction, of course.
You have the answer above:
@Henrique_Becker @GunnarFarneback Thanks for both of your help.
GOTO was routinely written in older programming languages, but it was mostly abandoned decades ago in favor of structured programming, like for-loops, methods, try-catch-finally. The structures are effectively ways to write the more maintainable GOTO patterns, so GOTO stills show up in the lowered and compiled code that the compiler makes from the structures.
Julia’s @goto
and @label
has such niche uses that the only application people can immediately think of is multi-level breaks from nested loops, yet it’s been demonstrated in this thread that specific purpose could be written with improved syntax enabled by @multibreak
. Unlike historical GOTO, Julia’s @goto
’s ability to jump around the code is limited somewhat, but it can still easily make a program much harder to follow than typical structures. Treat it as a relic of the past, a last resort to dust off if you run into a surprising case where the typical structures would be harder to follow than the equivalent @goto
version.
Thanks so much.