The opportunity to optimize yb tail-call elimination comes up in my coding
from time to time. It is generally trivial to do but sometimes less so, and
this example by Ian Denhardt is one I'd never considered and one that would
make doing the rewrite yourself impossible.


Generally though it is very simple. The basic recipe is this:

func name(arg1, arg2, argN) (result) {
    code // first line of body
    :
    x = name(a,b,c) // optional recursive body call of function
    :
    if (j = y) {
        return
    }
    result = name(d, e, f) // tail-call of function
    return
}

becomes

func name(arg1, arg2, argN) (result) {
    *for { // added forever loop head before first line*
        code // first line of body
        :
        x = name(a,b,c) // optional recursive body call of function
        if (j = y) {
           * break // return changes to break*
        }
 *       // result = name(d, e, f) // tail-call of function*
*        arg1, arg2, argN = d, e, f // tail-call becomes simple argument
assignment*
    *} // added forever loop close after last line*
    return
}


On Sat, Apr 6, 2019 at 10:23 AM Ian Denhardt <i...@zenhack.net> wrote:

> Quoting Robert Engels (2019-04-06 08:00:02)
>
> >    But yes, similar to how all recursive functions can be rewritten using
> >    loops, which are more efficient, that is essentially what tail call
> >    optimization does - just that the process it automatic.
>
> Not all recursive functions -- just tail calls. If you do stuff after
> the call then you need to save state, which is what the call stack is
> for.
>
> You *could* use an explicit stack instead of using the call stack, but
> whether this is more or less efficient is highly dependent on your
> language implementation and the stack data structure you're using; I see
> no reason to believe it would necessarily be more efficient in general.
>
> ---
>
> Adding tail calls also has a few gotchas depending on how it interacts
> with other parts of the language. For example, in the case of:
>
>
> ```
>     func foo () {
>         ...
>         defer x.Close()
>         ...
>         return bar()
>     }
> ```
>
> The call to `bar()` is *NOT* a tail call, because `x.Close()` must be
> called before the function actually returns. So this means they interact
> in non-obvious ways with other parts of the language. One of the things
> I like about Go is that most of the features interact in ways that are
> easy to predict.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>


-- 

*Michael T. jonesmichael.jo...@gmail.com <michael.jo...@gmail.com>*

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to