Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: make the variable a func literal is assigned to available inside the function #46037

Closed
opennota opened this issue May 7, 2021 · 3 comments

Comments

@opennota
Copy link

@opennota opennota commented May 7, 2021

This doesn't compile (undefined: f):

f := func() { f() }

I don't see why it shouldn't.

This compiles:

var f func()
f = func() { f() }

This doesn't, again:

var f = func() { f() }
@nilsocket
Copy link

@nilsocket nilsocket commented May 7, 2021

Because it's undeclared.

First one needs to declare a variable to define something.

a := 5     // declared and defined
b := a + 5 // RHS is evaluated, then `b` is declared and defined, `b` can be used from next line
c := c + 5 // RHS is evaluated, undeclared variable `c`, and `c` is undefined

A variable is declared only at the end of it's expression inside a function.
i.e., f() is declared and defined only after whole expression of f() is evaluated, (i.e., after RHS evaluation is completed).

See Point 5: https://golang.org/ref/spec#Declarations_and_scope

If you try the same in package block, you will get into invalid initialization cycle.
https://golang.org/ref/spec#Package_initialization

var a = a + 5 // invalid initialization cycle

https://pkg.go.dev/golang.org/x/tools/internal/typesinternal#InvalidInitCycle

This one is valid since it's declared and then defined.

var f func()       // f is declared
f = func() { f() } // f is defined

Loading

@opennota
Copy link
Author

@opennota opennota commented May 8, 2021

Closures are different. Assigning an undeclared variable (c = c + 5) doesn't work in Python and Javascript (c is not defined), but these do:

Python:

f = lambda: f()

Javascript:

let f = function() { f() }

By the time the Go compiler gets to the function body, it already knows the type of the variable f.

Loading

@seankhliao
Copy link
Contributor

@seankhliao seankhliao commented May 8, 2021

Duplicate of #33167

Loading

@seankhliao seankhliao marked this as a duplicate of #33167 May 8, 2021
@seankhliao seankhliao closed this May 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants