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:
- Are function declarations and function expressions implemented differently under the hood, or is this behavior just hard-coded?
- If yes, is the difference between these implementations critical?
- Is Go somewhat better in any way for doing it the way it does?
From the spec:
The moment you write
var mainyou 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.So:
Yes.
Generally, no. It comes with the territory of being a typed language, which has all sorts of pros and cons depending on use.
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 packageunsafeis not used).