Thread overview
Statement "goto" between functions
May 25, 2019
Andrey
May 25, 2019
Dennis
May 26, 2019
Andrey
May 26, 2019
Dennis
May 26, 2019
CasparKielwein
May 25, 2019
Hello,
Can anybody say - is it possible to implement in D a statement "goto between functions". Not between random functions but between functions that are currently on the stack. Such "goto" will be something like labeled break in nested loops.
Example of what I mean. Lets imagine call stack:
> int main			
> someFunction1 	
> someFunction2
> ... someFunctionN
and code:
> void someFunction1(T...)(T args)
> {
>     // do some actions...
>     someFunction2(10, true, "hello"); // nested call
>     // do some actions...
>     GOTO_LABEL_EXTRA1:
>     writeln("Exit - GOTO_LABEL_EXTRA1 (or regular exit)");
>     return;
> 
>     GOTO_LABEL_EXTRA2:
>     writeln("Exit - GOTO_LABEL_EXTRA2");
> 
>     // do other actions
> }
> void someFunctionN()
> {
>     // do some actions...
>     if(condition) goto GOTO_LABEL_EXTRA1;
>     // do other actions...
>     if(othercondition) goto GOTO_LABEL_EXTRA2;
>     // do some other actions...
>     return; // regular exit
> }

Inside "main" we call "someFunction1" where we call "someFunction2" where we call "someFunction3" ... where we call "someFunctionN". This looks like nested loops.
When we make some calculations inside "someFunctionN" we exit it. Stack is unrolled and we are again inside "someFunction1". Execution continues from label (if exit was through goto) or through regular flow.
At the moment there are (as I understand) two different and non-overlapping ways to exit from function - usual "return" or exception. Exceptions are expansive and aren't suited for normal flow. Returns are ambiguous. To get rid of ambiguity one can return bool flag and then check it. But it is ugly and why I must check 10 times the same flag when in someFunctionN I know exactly result and currect branch of execution flow? I want just to jump to next instruction (and free stack and heap) without any additional runtime things.

And for loops there are (as I understand) four ways in exit - return, exception, break and goto.

This example we can see from another side - as if we mixin code of someFunction2 .. someFunctionN in someFunction1.

What do you think?
May 25, 2019
On Saturday, 25 May 2019 at 19:29:03 UTC, Andrey wrote:
> is it possible to implement in D a statement "goto between functions". Not between random functions but between functions that are currently on the stack. Such "goto" will be something like labeled break in nested loops.

D being a systems programming language allows basically anything you can do with assembly hacks. Here is a posix-only demo using the C standard library functions setjmp (analogous to try-catch) and longjmp (analogous to throw).

https://run.dlang.io/is/aPlxfQ

As you can see it is still pretty ugly, and it's absolutely not recommended to use this.

> But it is ugly and why I must check 10 times the same flag when in someFunctionN I know exactly result and currect branch of execution flow? I want just to jump to next instruction (and free stack and heap) without any additional runtime things.
> ...
> What do you think?

I think you should either:
- rethink your design
- check return values manually
- still use Exceptions, which is the only way of jumping over functions that is supported by the language.

A long-jump solution is bad because:

- your code's control flow becomes spaghetti
- things like destructors, Exceptions and scope statements won't function properly anymore.
- setjmp/longjmp save/restore all registers, so it's still slower than a goto
- while I can't speak from experience (I haven't used them in practice), I bet they easily break, are hard to debug and are not very portable.

May 26, 2019
On Saturday, 25 May 2019 at 19:29:03 UTC, Andrey wrote:
> Hello,
> Can anybody say - is it possible to implement in D a statement "goto between functions". Not between random functions but between functions that are currently on the stack. Such "goto" will be something like labeled break in nested loops.
> (...)
> What do you think?

If I understand you correctly, you basically want coroutines.
D offers a library implementation called Fibers: https://dlang.org/library/core/thread/fiber.html
They allow switching between arbitrary stack like contexts, which should enable your algorithm.
May 26, 2019
On Saturday, 25 May 2019 at 20:18:23 UTC, Dennis wrote:
> On Saturday, 25 May 2019 at 19:29:03 UTC, Andrey wrote:
>> is it possible to implement in D a statement "goto between

And how to return from deep functions back some function on the surface? Directly without extra checks.
Exceptions are not suitable for it.
May 26, 2019
On Sunday, 26 May 2019 at 17:46:55 UTC, Andrey wrote:
> And how to return from deep functions back some function on the surface? Directly without extra checks.

That's what my longjmp example does. Can you tell me what you're making? I'm curious what you need this for.