# Programmatic goto

**URL:** <https://discourse.julialang.org/t/programmatic-goto/69271>\
**Category:** General Usage\
**Created:** [October 5, 2021, 11:18pm UTC](https://discourse.julialang.org/t/programmatic-goto/69271 "2021-10-05T23:18:46Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![cscherrer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cscherrer/32/7631_2.png) [@cscherrer](https://discourse.julialang.org/u/cscherrer)\
**Post date:** [October 5, 2021, 11:18pm UTC](https://discourse.julialang.org/t/programmatic-goto/69271/1 "2021-10-05T23:18:47Z")

</div>

For probabilistic programming work, I was exploring the idea of adding `@goto` and `@label` statements in the code for a model, and then calling to an outside “driver” function to see where to go next. Prototyping this idea, I need the driver to return a `Command`, with `Goto` as one option. So something like

```julia
abstract type Command end

struct Goto <: Command
    target::Symbol
end

```

Since `@goto` is implemented as

```julia
macro goto(name::Symbol)
    return esc(Expr(:symbolicgoto, name))
end

```

I thought I could do something like

```julia
macro maygoto(ex)
    quote
        command = $ex
        result = if command isa Goto
            target = command.target
            esc(Expr(:symbolicgoto, target))
        else
            nothing
        end
        result
    end
end

```

But a test run doesn’t work:

```julia
julia> function f()
           println("start")
           @maygoto Goto(:blah)
           println("skip this")
           @label blah
           println("done")
       end
f (generic function with 1 method)

julia> f()
start
skip this
done

```

Am I making a silly mistake here? Or maybe just a very serious mistake? Help please 🙂

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 5, 2021, 11:37pm UTC](https://discourse.julialang.org/t/programmatic-goto/69271/2 "2021-10-05T23:37:13Z")

</div>

I don’t think you can truly test for `if command is a Goto` inside macro since type is a run-time concept but macro only sees source code:

```julia
julia> macro maygoto(ex)
           command = ex.args[1]
           if command == :Goto
               return esc(Expr(:symbolicgoto, ex.args[2].value))
           else
               return nothing
           end
       end
@maygoto (macro with 1 method)

julia> function f()
           println("start")
           @maygoto Goto(:blah)
           println("skip this")
           @label blah
           println("done")
       end
f (generic function with 1 method)

julia> f()
start
done

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 5, 2021, 11:43pm UTC](https://discourse.julialang.org/t/programmatic-goto/69271/3 "2021-10-05T23:43:11Z")

</div>

your original macro is doing the technically correctthing as far as `isa Goto` concerns:

```julia

julia> @macroexpand function f()
                  println("start")
                  @maygoto Goto(:blah)
                  println("skip this")
                  @label blah
                  println("done")
              end
:(function f()
      #= REPL[4]:1 =#
      #= REPL[4]:2 =#
      println("start")
      #= REPL[4]:3 =#
      begin
          #= REPL[3]:3 =#
          var"#16#command" = Main.Goto(:blah)
          #= REPL[3]:4 =#
          var"#17#result" = if var"#16#command" isa Main.Goto
                  #= REPL[3]:5 =#
                  var"#18#target" = (var"#16#command").target
                  #= REPL[3]:6 =#
                  Main.esc(Main.Expr(:symbolicgoto, var"#18#target"))
              else
                  #= REPL[3]:8 =#
                  Main.nothing
              end
          #= REPL[3]:10 =#
          var"#17#result"
      end
      #= REPL[4]:4 =#
      println("skip this")
      #= REPL[4]:5 =#
      $(Expr(:symboliclabel, :blah))
      #= REPL[4]:6 =#
      println("done")
  end)

```

---

<div class="post-metadata">

**Author:** ![cscherrer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cscherrer/32/7631_2.png) [@cscherrer](https://discourse.julialang.org/u/cscherrer)\
**Post date:** [October 5, 2021, 11:44pm UTC](https://discourse.julialang.org/t/programmatic-goto/69271/4 "2021-10-05T23:44:07Z")

</div>

> [@jling](#):
>
> I don’t think you can truly test for `if command is a Goto` inside macro since type is a run-time concept but macro only sees source code:

Right, but the test is in the `quote`, so

```julia
julia> macro maygoto(ex)
           quote
               command = $ex
               result = if command isa Goto
                   println("It's a goto!")
                   target = command.target
                   esc(Expr(:symbolicgoto, target))
               else
                   nothing
               end
               result
           end
       end
@maygoto (macro with 1 method)

julia> function f()
           println("start")
           target = :blah
           @maygoto Goto(:blah)
           println("skip this")
           @label blah
           println("done")
       end
f (generic function with 1 method)

julia> f()
start
It's a goto!
skip this
done

```

Things like this are always weird:

```julia
julia> @macroexpand @goto blah
:($(Expr(:symbolicgoto, :blah)))

```

Is there even a way to write that directly in code, without the macro?

---

<div class="post-metadata">

**Author:** ![cscherrer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cscherrer/32/7631_2.png) [@cscherrer](https://discourse.julialang.org/u/cscherrer)\
**Post date:** [October 5, 2021, 11:45pm UTC](https://discourse.julialang.org/t/programmatic-goto/69271/5 "2021-10-05T23:45:34Z")

</div>

YOU CAN MACROEXPAND A FUNCTION?!?!

I had no idea, that’s really nice 😃

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 5, 2021, 11:46pm UTC](https://discourse.julialang.org/t/programmatic-goto/69271/6 "2021-10-05T23:46:17Z")

</div>

> [@cscherrer](#):
>
> but the test is in the `quote`

right, thus the whole `quote end` is the result of expansion and you get a perfectly correct `isa Goto` at run-time but the returned `Expr()` is “useless” now that it’s run-time

> [@cscherrer](#):
>
> YOU CAN MACROEXPAND A FUNCTION?!?!

haha, isn’t that nice?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [October 5, 2021, 11:49pm UTC](https://discourse.julialang.org/t/programmatic-goto/69271/7 "2021-10-05T23:49:39Z")

</div>

`MacroTools.@macroexpand(@mymacro ...) |> MacroTools.prettify` is really really nice.

---

<div class="post-metadata">

**Author:** ![cscherrer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cscherrer/32/7631_2.png) [@cscherrer](https://discourse.julialang.org/u/cscherrer)\
**Post date:** [October 5, 2021, 11:56pm UTC](https://discourse.julialang.org/t/programmatic-goto/69271/8 "2021-10-05T23:56:36Z")

</div>

When I was learning macros, someone pointed out that they don’t give you any new capabilities, but just let you write things with fewer keystrokes. That made a lot of sense, and really helped me get more comfortable with them.

But things like this still seem magical:

```julia
julia> @macroexpand @goto blah
:($(Expr(:symbolicgoto, :blah)))

```

I know there are some “magical” macros, but for `@goto`, the code is right there in Julia.

So… is that only mostly right? Is there no way to write `@goto blah` inline without using a macro?

I mean, I want to use a macro, but I think I first need to understand what’s actually going on here.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 6, 2021, 12:00am UTC](https://discourse.julialang.org/t/programmatic-goto/69271/9 "2021-10-06T00:00:02Z")

</div>

`goto` is a really low-level thing if you think about it, it literally marks a location to jump to on stack. So the reason it’s a macro is that it simply leaves an expression for the compiler to figure out what is the “location” on the stack to jump to once it compiles the function into binary (before then, you can only talk about “label” because you don’t know how much big the binary blob of function ends up becoming).

Looking back, even in C++ the label/goto has weird syntax, because they kind of stay location markers until the last step (asm):

```cpp
label:
    ...

goto label;

```

---

<div class="post-metadata">

**Author:** ![cscherrer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cscherrer/32/7631_2.png) [@cscherrer](https://discourse.julialang.org/u/cscherrer)\
**Post date:** [October 6, 2021, 12:09am UTC](https://discourse.julialang.org/t/programmatic-goto/69271/10 "2021-10-06T00:09:57Z")

</div>

Good point. I guess this would need to be at the IR level - for higher-level code I’d probably need to go with continuations or something similar
