Re: goto



On 2009-07-06, Ben C <spamspam@xxxxxxxxx> wrote:
On 2009-07-06, Richard Tobin <richard@xxxxxxxxxxxxxxx> wrote:
In article <lnprcd3buf.fsf@xxxxxxxxxxxxxxx>,
Keith Thompson <kst-u@xxxxxxx> wrote:

IMHO, most legitimate uses of gotos are substitutes for missing
language features, most commonly either exception handling or
multi-level break. Note that both of these uses require only
forward-branching gotos.

One missing language feature that is naturally simulated with a
backward branch is tail recursion optimisation.

But who needs tail recursion when you've got loops?

Sufficiently advanced tail recursion can work across functions, and even across
compilation units. Looping is confined to a block of code.

But still I am intrigued, what are you doing here, basically just
goto-ing the top of the function again in order to "recurse"?

Under tail recursion, you are making a call which cannot return. Therefore, the
caller's local variables have no next use, and their memory can be purged prior
to the call.

A straightforward tail recursion to the same function is basically equivalent
to /assigning/ new values to the parameters, and branching backwards.

So for instance a the loop for (i = 0; i < 100; i++) stmt; goes something like:

void forloop(int i, int n)
{
if (i < n) { // guard
stmt;
forloop(i + 1, n); // increment and branch backwards
}
}

// ...

forloop(0, 100);

This can be turned into the code:

void forloop(int i, int n)
{
label:
if (i < n) { // guard
stmt;

i = i + 1; // set up the new parameters
n = n; // <- likely optimized away
goto label; // pass the control
}
}

In Lisp, I have experimented with parametrized goto, which then became portable
tail recursion. (Search the comp.lang.lisp archives for "argtags").

The idea is this. Suppose that goto labels could have parameters: the names of
existing variables. And supose that goto could supply argument values. Then you
could write the above like this:

label(i, n): // all names in brackets must be declared variables
// ...
goto label(i + 1, n);

And perhaps the need for the goto could disappear into the syntax also:

label(i, n):
// ...
label(i + 1, n);

Now this simple syntactic sugar almost looks like function calls.

It's a useful extra discipline in the goto. The problem with many uses of goto
is that they don't make it clear what state changes are relevant. It's the
assignments that are the problem. We are puzzled by a backward goto because we
don't know what is different the second and subsequent time around the same
block. Above we know that what is different is that i is incrementing by one.

Suppose that, further, we take on the discipline that we will avoid assignments
in the code. Suppose that all assignments are disguised using the the
label(arg, ...) syntax. Then the gotos become much easier to understand.

You know which variables are pertinent to a basic block headed by a label, and
whow they change. Each parametrized goto explicitly spells out values for every
single one of those variables used in that basic block, even the ones that
don't change, like n above. All of the arguments are required, so you can't
miss anything; you must specify what happens to every darn thing. Moreover, you
can quickly scan a block of code to see whether it depends on any variables
that are not mentioned in its preceding label; they can be added to the label,
and then you can reason about all of the goto places which reach that label:
how should they compute the value of that variable? Which ones should leave the
variable alone, and which ones should change it? So you're not left wondering
``what is the purpose of this i = 42 assignment here, and how does it affect
the previous code after some backward branch is taken''.

Arguably, it's the state change in imperative programming which is the real
cuprit, not goto. Eliminate the assignment and it all starts to look
functional.
.



Relevant Pages

  • Re: goto
    ... But who needs tail recursion when you've got loops? ... goto label; // pass the control ... In Lisp, I have experimented with parametrized goto, which then became portable ... It's the assignments that are the problem. ...
    (comp.lang.c)
  • Tail recursion syntactic sugar faked with TAGBODY-based construct?
    ... and provide a GOTO that takes argument expressions. ... in which a a label parameter is shadowed, ... (let (labels forms thunks thunk-gensyms) ... vars gensyms)) ...
    (comp.lang.lisp)
  • Re: On Local Error Goto Somewhere
    ... an EXIT DO or EXIT FOR. ... going if there is no label to show you the destination. ... IMO the GoTo statement has never been "THE" problem. ... ON ERROR GOTO MySubErr Dim lFNbr as long ...
    (microsoft.public.vb.general.discussion)
  • Re: function pointers
    ... The simple goto. ... fixed target label. ... The computed goto, aka switch, select, or caseof, depending ... In C it is the switch. ...
    (comp.lang.c)
  • Re: COBOL aint quite dead - yet !
    ... If you accept a definition of GOTO's as a transfer of control, ... would probably not have said that a goto by any other name would still be a ... label then, in a program that has gotos, it is not possible to know ... the SECTION keyword is an assurance that there will be no down- ...
    (comp.lang.cobol)