Re: [go-nuts] What happens when you call another method within a method set at the end of a method
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
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
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
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
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
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.