With the recent approval of the become keyword letting us explictly perform tail-call optimizations in Rust, I wonder: does rust have an alternative for all the valid uses of goto? What would be missing, otherwise? It seems named blocks, loops, continue, break and become are good alternatives to goto.
Couple with your looping construct of choice if you want "backwards goto" -- it's intentional the you can't go "backwards" without a loop construct in Rust.
Thank you Jules! I'm a bit new to this, so I was wondering, with the become, continue, break, named loops and named blocks, all the use cases of goto should be covered, from my understanding. I was wondering if this is the case. If this is not the right forum, let me know.
I believe that the specific case of computed goto is one Rust (even with become) doesn't fully serve, although I'm not super familiar with the details. Using a match on a temporary theoretically should be control-flow equivalent, but there are significant cases where LLVM fails to optimize such as well as it does a more direct expression of the control flow with computed goto.
My gut feeling thinks this may also have some to do with match exhaustiveness, fallback cases, and Rust telling LLVM to ud2 in impossible scenarios more often then clang does, but that's just vibe based guesswork without any real merit.
Yes, the analogy to computed gotos is a tailcall on a function pointer, in Rust a become on a function reference.
A typical example seems to be dispatch tables to implement interpreters, I looked into this blogpost for an example and quickly implemented it. In contrast to the example in the documentation, I did not use a match.
The whole point of a dispatch table is to avoid match/switch/if-else or similar. Perhaps the dispatch table example in the Rust documentation brought you to the conclusion that you need a match for dispatch tables? Then the example should be changed, so it does no longer use a match.
EDIT: Sorry, but computed gotos are rarely used in praxis. I think the main reason become will be added to Rust is that there are a lot of use cases for normal tailcalls. But not so many uses for tailcalls on function pointers. That said, I am not a Rust developer.