I just got into programming again with Go (with no experience whatsoever in low-level languages), and I noticed that function expressions are not treated the same as function declarations (go1.18.5 linux/amd64
).
For instance, this works (obviously):
package main
import "fmt"
func main() {
fmt.Println("Do stuff")
}
But this outputs an error:
package main
import "fmt"
var main = func() {
fmt.Println("Do stuff")
}
./prog.go:3:8: imported and not used: "fmt"
./prog.go:5:5: cannot declare main - must be func
Go build failed.
Even specifying the type as in var main func() = func() {}
does nothing for the end result. Go seems to, first of all, evaluate if the main
identifier is being used in any declaration, ignoring the type. Meanwhile, Javascript folks seem to choose what is more readable, like there's no underlying difference between them.
Questions:
From the spec:
The main package must [...] declare a function
main
that takes no arguments and returns no value.
The moment you write var main
you prevent the above requirement from being met, because what you are creating is a variable storing a reference to a function literal as opposed to being a function declaration.
A function declaration binds an identifier, the function name, to a function.
A function literal represents an anonymous function.
So:
Are function declarations and function expressions implemented differently under the hood?
Yes.
Is Go somewhat better in any way for doing it the way it does?
Generally, no. It comes with the territory of being a typed language, which has all sorts of pros and cons depending on use.
If yes, is the difference between these implementations critical?
By what standard? As an example, a variable referencing a function literal could be nil
, which isn't usually something you'd like to call. The same cannot happen with function declarations (assuming package unsafe
is not used).