user1019517
user1019517

Reputation:

Why does Go allow compilation of unused function parameters?

One of the more notable aspects of Go when coming from C is that the compiler will not build your program if there is an unused variable declared inside of it. So why, then, is this program building if there is an unused parameter declared in a function?

func main() {
    print(computron(3, -3));
}


func computron(param_a int, param_b int) int {
    return 3 * param_a;
}

Upvotes: 20

Views: 12748

Answers (2)

icza
icza

Reputation: 418137

The main reason is to be able to implement interfaces that dictate specific methods with specific parameters, even if you don't use all of them in your implementation. This is detailed in @Jsor's answer.

Another good reason is that unused (local) variables are often the result of a bug or the use of a language feature (e.g. use of short variable declaration := in a block, unintentionally shadowing an "outer" variable) while unused function parameters never (or very rarely) are the result of a bug.

Another reason can be to provide forward compatibility. If you release a library, you can't change or extend the parameter list without breaking backward compatibility (and in Go there is no function overloading: if you want 2 variants with different parameters, their names must be different too).

You may provide an exported function or method and add extra - not yet used - or optional parameters (e.g. hints) to it in the spirit that you may use them in a future version / release of your library.

Doing so early will give you the benefit that others using your library won't have to change anything in their code.

Let's see an example:

You want to create a formatting function:

// FormatSize formats the specified size (bytes) to a string.
func FormatSize(size int) string {
    return fmt.Sprintf("%d bytes", size)
}

You may as well add an extra parameter right away:

// FormatSize formats the specified size (bytes) to a string.
// flags can be used to alter the output format. Not yet used.
func FormatSize(size int, flags int) string {
    return fmt.Sprintf("%d bytes", size)
}

Then later you may improve your library and your FormatSize() function to support the following formatting flags:

const (
    FlagAutoUnit      = 1 << iota // Automatically format as KB, MB, GB etc.
    FlagSI                        // Use SI conversion (1000 instead of 1024)
    FlagGroupDecimals             // Format number using decimal grouping
)

// FormatSize formats the specified size (bytes) to a string.
// flags can be used to alter the output format.
func FormatSize(size int, flags int) string {
    var s string

    // Check flags and format accordingly
    // ...

    return s
}

Upvotes: 4

Linear
Linear

Reputation: 22216

There's no official reason, but the reason given on golang-nuts is:

Unused variables are always a programming error, whereas it is common to write a function that doesn't use all of its arguments.

One could leave those arguments unnamed (using _), but then that might confuse with functions like

func foo(_ string, _ int) // what's this supposed to do?

The names, even if they're unused, provide important documentation.

Andrew

https://groups.google.com/forum/#!topic/golang-nuts/q09H61oxwWw

Sometimes having unused parameters is important for satisfying interfaces, one example might be a function that operates on a weighted graph. If you want to implement a graph with a uniform cost across all edges, it's useless to consider the nodes:

func (graph *MyGraph) Distance(node1,node2 Node) int {
    return 1
}

As that thread notes, there is a valid argument to only allow parameters named as _ if they're unused (e.g. Distance(_,_ Node)), but at this point it's too late due to the Go 1 future-compatibility guarantee. As also mentioned, a possible objection to that anyway is that parameters, even if unused, can implicitly provide documentation.

In short: there's no concrete, specific answer, other than that they simply made an ultimately arbitrary (but still educated) determination that unused parameters are more important and useful than unused local variables and imports. If there was once a strong design reason, it's not documented anywhere.

Upvotes: 30

Related Questions