8000 proposal: Go 2: delete init functions · Issue #25885 · golang/go · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

proposal: Go 2: delete init functions #25885

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

Closed
bronze1man opened this issue Jun 14, 2018 · 6 comments
Closed

proposal: Go 2: delete init functions #25885

bronze1man opened this issue Jun 14, 2018 · 6 comments
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal v2 An incompatible library change
Milestone

Comments

@bronze1man
Copy link
Contributor
bronze1man commented Jun 14, 2018

After meeting the same bug google/gopacket#101 3 years later.
The rule that the special init function in a package will be run before main function should be deleted.

example

Following code should be invalid if this proposal is accept:

  • case 1 (func init):
var gVar []byte
func init(){
   gVar = make([]byte,1000*1000);
}
  • case 2 (initialising globals with functions):
var gVar2 = new1MSlice()
func new1MSlice() []byte{
   return make([]byte,1000*1000);
}

Following code should be valid if this proposal is accept:

var gVar1 = []byte(`123`)
var gVar2 = map[string]string{"1":"1"}
const gConst1 = "1233456789"

disadvantage of init functions

It make the code more difficult to read, review and debug:

  • it is hard to find all the code that my process have run. You never know that the package sync have a init function run before your main package. I need to use go tool objdump the binary file to collect all the init functions.

It make the compiler harder:

  • all the variables that the init function is used can not be dead code elimination even if that variables is not referenced from any other place.

It encourage programer to write slow code:

advantage of init functions

The problem after init function is removed:

  • Register something in another package to workaround import circle. Like sync.runtime_registerPoolCleanup in sync package,crypto.RegisterHash in md5 package. This problem can be solved partly by delete those register stuff, and ask caller to use the md5 package.
  • Find the cpu information and store it in a variable to speed up other runtime stuff. Like cpuid

general solution to init problem without init functions:

  • case 1:
var gVar1 []byte
var gVar1Once sync.Once
func getVar1() []byte{
   gVar1Once.Do(func(){
     gVar1 = make([]byte,1000*1000)
   })
return gVar1
}
func main(){
   g:=getVar1()
   g[0] = 1
}
  • case 2:
var gVar1 []byte
var gVar1Once sync.Once
func InitVar1(){
   gVar1Once.Do(func(){
     gVar1 = make([]byte,1000*1000)
   })
}

func main(){
   InitVar1()
   gVar1[0] = 1
}
  • case 3(this case should be easy notice by programer, because this file size is huge):
var gVar1 = []byte{0,0,0,0,0,...,0} // 1M "0," in the source file. you can use another golang program to generate it.
func main(){
   gVar1[0] = 1
}
@gopherbot gopherbot added this to the Proposal milestone Jun 14, 2018
@agnivade agnivade added LanguageChange Suggested changes to the Go language v2 An incompatible library change labels Jun 14, 2018
@mvdan
Copy link
Member
mvdan commented Jun 14, 2018

If I remember correctly, the init function is also used for initialising globals, such as:

var foo = someFunc()

How would these be handled without an init function?

Unless this suggestion is only about the init function that the user can write, not the init function that the compiler can generate.

@bronze1man
Copy link
Contributor Author
bronze1man commented Jun 14, 2018

@mvdan
Thanks.
I add this example to the proposal.
this example should be invalid:

  • it can hidden a lot of memory and cpu cost.
  • I need to use go tool objdump the binary file to collect all this kind of stuff.
  • I can use something like following to use init function:
var _ = someFunc()

@ianlancetaylor
Copy link
Contributor

I don't find your disadvantages to be so bad that it is worth giving up initialization. Yes, one can write bad initialization functions. One can a 8000 lways write bad code. It's not possible for the language to prevent that. If we removed init functions the bad package would switch to using sync.Once, so it would just be bad. In fact, it would be a tiny bit worse since we would add the run time overhead of checking the sync.Once at some function calls.

@bronze1man
Copy link
Contributor Author
bronze1man commented Jun 15, 2018

@ianlancetaylor
Thanks.
I will make It make the code more difficult to read, review and debug to the top of the disadvantages list.
I think It make the code more difficult to read, review and debug is much more worse than sync.Once .

I have found that not easy read code lead to a lots of bugs.
sync.Once only cost 40ns in second run in my mac computer. It is not too bad for me.
You can also call your init function in your main package, if you want no overhead.

@mbyio
Copy link
mbyio commented Jun 20, 2018

This would be a huge change with far reaching ramifications. IMO it needs a much stronger argument for why we should remove it. If a package has an init function that is taking a long time to run, maybe don't use that package? And you mention having trouble finding all the init functions being run - it seems like it would be easy to just write a tool that finds all the init functions used in a program, right?

Your argument would be stronger if you showed a case where there was a library that you could not remove or downgrade and it caused a real world problem that affected users.

@bronze1man
Copy link
Contributor Author
bronze1man commented Jun 20, 2018

Thanks, @mbyio

After all those arguments.
I think it is too difficult to delete init functions from golang, and this action also makes golang difficult to use in some cases.
Because it is a huge change, and I have found some init functions usage case can not be replace by other stuff. It will make write cod 7D87 e much more difficult.

So I think I should close this issue.

@golang golang locked and limited conversation to collaborators Jun 20, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal v2 An incompatible library change
Projects
None yet
Development

No branches or pull requests

6 participants
0