Hi All,

TL;DR: While you can define types inside of functions (or scopes inside of 
functions), those types can't have methods on them. This limits the 
usability of this feature. I propose that we add the ability to define 
methods on scope-local types.

This came up while discussing the limitations of the sort package 
<https://github.com/golang/go/issues/16721> and how to fix them. In my 
experience, implementing the sort.Interface interface can be very painful. 
Partly this is because of the boilerplate involved, but the particularly 
annoying part is having to clutter the global namespace by adding a global 
type which implements the interface. Since these types are almost always 
meant to be used once in a particular function, they end up getting awkward 
names like "sortableWidgets" or something. This adds a whole set of 
top-level definitions that catch the eye when visually scanning a file 
looking for a particular definition, which makes it that much harder to 
keep working on the same file. Additionally, if the sort.Sort invocation is 
buried in some large function, the definition of the sortable container can 
be far away in terms of text lines, making it hard to jump back and forth 
while working on logically related code. For example, consider the 
following implementations, the first valid Go, and the second not:

type sortableInts []int

func (s sortableInts) Len() int { return len(s) }
func (s sortableInts) Less(i, j int) bool { return s[i] < s[j] }
func (s sortableInts) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

func sortInts(i []int) {
    ints := sortableInts(i)
    sort.Sort(ints)
}

================

func sortInts(i []int) {
    type sortable []int
    func (s sortable) Len() int { return len(s) }
    func (s sortable) Less(i, j int) bool { return s[i] < s[j] }
    func (s sortable) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

    ints := sortable(i)
    sort.Sort(ints)
}

The above disparity gets even worse when any of the methods (Len, Less, 
Swap) are complicated, and can't fit on a single line, or when the function 
in which sort.Sort is called is long, and the sort.Sort call is buried deep 
inside.

I don't believe that this would be a particularly large addition to the 
language, at least from a user's perspective. It would only expand the set 
of legal Go programs, so it abides by the backwards compatibility 
guarantee, it doesn't encourage any significantly different idioms than 
exist now, and it's not at all magic - it's simply extending the set of 
cases in which an already-allowed thing (ie, methods) can be used.

Thoughts?
Cheers,
Josh

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