functiongolanguage-implementation

Are function declarations and function expressions implemented differently in Go? If yes, why?


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:


Solution

  • 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).