FAQ
When expressing nested recursive functions, it is useful to be able refer
to the name of the function you are defining. During the tour of Go it
became obvious that nested functions cannot be recursive without being
fairly verbose.

My first attempt was as follows:

// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
func inner(t *tree.Tree, ch chan int) {
if t.Left != nil {
inner(t.Left, ch)
}
ch <- t.Value
if t.Right != nil {
inner(t.Right, ch)
}
}(t, ch)

close(ch)
}

That generates the syntax error :

prog.go:9: syntax error: nested func not allowed

Okay fine, lets have an anonymous function that is assigned to a variable "inner":
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
inner := func (t *tree.Tree, ch chan int) {
if t.Left != nil {
inner(t.Left, ch)
}
ch <- t.Value
if t.Right != nil {
inner(t.Right, ch)
}
}

inner(t, ch)

close(ch)
}

In this case inner is not defined prior to closing over the previous scope, so it doesn't compile and the following errors are generated:

prog.go:11: undefined: inner
prog.go:15: undefined: inner


Fair enough, so we have to define the function pointer inner prior to the
anonymous definition:
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
var inner func(t *tree.Tree, ch chan int)
inner = func(t *tree.Tree, ch chan int) {
if t.Left != nil {
inner(t.Left, ch)
}
ch <- t.Value
if t.Right != nil {
inner(t.Right, ch)
}
}

inner(t, ch)
close(ch)
}

Okay, that works, but now we have a doubly verbose version, having to
explicitly instance a function pointer, its full prototype, and then have
the anonymous function have the same prototype. So my question is, why not
just support nested named functions? My last form is functionally
equivalent to my first form, but the first form has less redundancy. Is
recursion with nested functions that rare that other people have not run
into this problem?

Thanks for your time.



--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • David Symonds at Mar 1, 2013 at 6:06 am
    Unless I'm mistaken, your inner func does not close over anything, so
    just make it a top-level function instead of an anonymous closure and
    you'll avoid this problem entirely.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Litghost at Mar 1, 2013 at 6:11 am
    In this particular example you are correct. However in general that would
    not be true.
    On Thursday, February 28, 2013 10:06:52 PM UTC-8, David Symonds wrote:

    Unless I'm mistaken, your inner func does not close over anything, so
    just make it a top-level function instead of an anonymous closure and
    you'll avoid this problem entirely.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Ian Lance Taylor at Mar 1, 2013 at 6:12 am

    On Thu, Feb 28, 2013 at 10:00 PM, wrote:
    Okay, that works, but now we have a doubly verbose version, having to
    explicitly instance a function pointer, its full prototype, and then have
    the anonymous function have the same prototype. So my question is, why not
    just support nested named functions? My last form is functionally
    equivalent to my first form, but the first form has less redundancy. Is
    recursion with nested functions that rare that other people have not run
    into this problem?
    If we allow single recursion we should allow multiple recursion--where
    f1 calls f2 calls f1. But scoping within a function starts after the
    variable declaration is complete, so we would have to change that.
    Now we are introducing additional language complexity for a feature
    that is rarely used and that can, as you've observed, be implemented
    today albeit more verbosely.

    Ian

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Litghost at Mar 1, 2013 at 7:04 am
    Fair enough.
    On Thursday, February 28, 2013 10:12:48 PM UTC-8, Ian Lance Taylor wrote:

    On Thu, Feb 28, 2013 at 10:00 PM, <litg...@softhome.net <javascript:>>
    wrote:
    Okay, that works, but now we have a doubly verbose version, having to
    explicitly instance a function pointer, its full prototype, and then have
    the anonymous function have the same prototype. So my question is, why not
    just support nested named functions? My last form is functionally
    equivalent to my first form, but the first form has less redundancy. Is
    recursion with nested functions that rare that other people have not run
    into this problem?
    If we allow single recursion we should allow multiple recursion--where
    f1 calls f2 calls f1. But scoping within a function starts after the
    variable declaration is complete, so we would have to change that.
    Now we are introducing additional language complexity for a feature
    that is rarely used and that can, as you've observed, be implemented
    today albeit more verbosely.

    Ian
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedMar 1, '13 at 6:03a
activeMar 1, '13 at 7:04a
posts5
users3
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase