Re: [go-nuts] What happens when you call another method within a method set at the end of a method

2019-04-06 Thread Robert Engels
You are correct, but I think an explicit stack is faster than most function 
calls, but it depends on number of parameters needed, etc.  but maybe not...:)

> On Apr 6, 2019, at 12:20 PM, Ian Denhardt  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.

-- 
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.


Re: [go-nuts] What happens when you call another method within a method set at the end of a method

2019-04-06 Thread Michael Jones
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  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 *

-- 
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.


Re: [go-nuts] What happens when you call another method within a method set at the end of a method

2019-04-06 Thread Ian Denhardt
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.


Re: [go-nuts] What happens when you call another method within a method set at the end of a method

2019-04-06 Thread Robert Engels
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. 

> On Apr 6, 2019, at 5:21 AM, Jan Mercl <0xj...@gmail.com> wrote:
> 
> On Sat, Apr 6, 2019 at 9:34 AM Louki Sumirniy 
>  wrote:
> 
> A tail call is in the first approximation just what it says:
> 
> call foo
> ret
> 
> Nothing other is really that much special about it.
> 
> -- 
> 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.

-- 
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.


Re: [go-nuts] What happens when you call another method within a method set at the end of a method

2019-04-06 Thread Jan Mercl
On Sat, Apr 6, 2019 at 9:34 AM Louki Sumirniy <
louki.sumirniy.stal...@gmail.com> wrote:

A tail call is in the first approximation just what it says:

call foo
ret

Nothing other is really that much special about it.

-- 
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.


[go-nuts] What happens when you call another method within a method set at the end of a method

2019-04-06 Thread Louki Sumirniy
I have become quite interested in tail-call optimisation and more distantly 
in code that assembles trees of closures all tied to the same scope through 
parameters to reduce stack management for complex but not always 
predictable input.

As I have learned from some reading, tail call optimisation is a fairly 
frequently requested feature that is not planned to go into Go 2, so I am 
just wondering what actually happens when you end functions with a call, 
especially that shares the same receiver as the calling function.

I figure it changes the procedure a little compared to calling before, 
since the compiler knows no more variables in the caller are going to be 
changed except the return value. I also figure that it reduces the rate at 
which the stack expands since the first function does not need to save its 
state to resume.

Does or can it have a performance impact? What I'm thinking is that it 
works like a trampoline, in that it means the stack doesn't grow so even if 
you change nothing else when using a recursive algorithm, moving it to tail 
calls - does it reduce the stack growth rate, and if so, how can this be 
exploited to reduce overhead?

-- 
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.