-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
math/rand: deprecate Seed #56319
Comments
What are the implications of deprecation? Does it simply do nothing? Is it just marked as deprecated so that IDEs/linters can usher users to the suggested usage? |
The latter. The function continues to work like before, but users are warned about it in linting, IDEs, and docs. |
This proposal has been added to the active column of the proposals project |
I disagree with #54880. But i agree that, with that proposal accepted, deprecating the global Seed function is a logical step. |
So it will work into the future, just users will be warned about it? Or it will work in the near-term future, but no promises in the long run?
In scientific simulation, there are lots of cases where it is very useful to be able to produce a deterministic result, especially for debugging purposes. Right now, this is easy to do in Go. The author writes code that calls the math/rand functions, and can get reproducible behavior by setting the seed. This is incredibly useful for debugging code, for example to reliably follow a specific codepath or to check a computation by hand from some known results. It's true that this is inherently fragile, but that's not important, because during debugging I'm not changing all of that code. For working code, I do want the result to be random (and thus subject to that fragility), but for non-working code it's very useful to easily control the randomness. It is true that an alternative is to call rand.NewSource, but this is invasive. This call has to happen near the top of I appreciate the story is different in Go than in other languages because concurrency is so prevalent and this interacts poorly with determinism from a global generator. That said, I've had a lot of success with code that generates the necessary randomness, and then does deterministic concurrent computation given those results. |
I think the implication here is that if you need deterministic behavior, then you need to create a new RNG with It's not really possible to ensure deterministic behavior to the global RNG, because there may be a goroutine started by a library that re-seeds it. I'm not sure if the go team ensures that the RNG will produce the same series for the same seed between go versions, so even if you ensure that there is no competing seed for the global RNG, the series it produces may change in the future. If you need a truly stable deterministic series that will hold up to changes, it should be generated, stored in the project, and read at runtime. That all said, while I believe the intention is that the package will continue behaving as it has, and there's just more emphasis on using it correctly. I don't know what the long term plan for the package is though, so please take my words lightly. |
Personally, the main reason I want to deprecate
It doesn't even have to be a goroutine. It can just be a package you import which uses
Personally, as I have the opposite problem, I tend to have an You can do the same concept, but the other way around: Make an This, of course, only works if all the relevant package are controllled by you, so rogue RNG usage doesn't change your output. But that's already the situation you're in. So, IMO 1. it's not actually invasive, really, if you don't want it to be. And 2. you should probably do the invasive thing anyway, as that's just the right thing to do. |
I think that's a reasonable solution. I do want to say though that this workaround/solution is still implicitly deprecating |
I strongly disagree. On the contrary. It makes them, for most usecases - those which actually want non-deterministic random numbers - usable, as opposed to the current situation, where they are pointless for all usecases.. Currently you can't rely on them to be non-deterministic, because some library might've called If finally no one calls |
In Go, deprecated means only that you should probably not use it anymore. We won't remove it, because compatibility. |
It will remain easy to do. IDEs will just flag that rand.Seed use. Nothing will actually stop you from using it though. |
@btracey You can also put |
The 'var rand = ' trick is also not safe for concurrent use, but if you think you're reproducing an answer, you probably don't have concurrency anyway. |
There were some concerns about existing uses being flagged, but they will keep compiling, and they can be made more robust and avoid the flag by using Are there any remaining objections to accepting this proposal? |
Based on the discussion above, this proposal seems like a likely accept. |
No change in consensus, so accepted. 🎉 |
Change https://go.dev/cl/451375 mentions this issue: |
Does the proposal cover what to do with It's always a bit frustrating when one part of the standard library specifically documents reliance on a feature marked deprecated by the other part.
|
If you want a repeatable shuffle, use |
Thanks @ianlancetaylor. In retrospect I should have RTFM'd harder! I do appreciate your advice. |
…stant See golang/go#56319 Signed-off-by: Andrew Mason <andrew@planetscale.com>
controller-runtime v15 has a min Golang version requirement that breaks the container builds. This change bumps up the Go version used to build the container. Starting 1.21 Golang, go.mod requires the Go version and treats that as min required go version to compile your binary. So, also bump up the Go version for local builds. Additional changes: - As per golang/go#56319 and golang/go#54880, global rand is automatically, randomly seeded. So we don't need to call `Seed` anymore. - Package ioutil has been deprecated. Port the code to use replacement methods.
controller-runtime v15 has a min Golang version requirement that breaks the container builds. This change bumps up the Go version used to build the container. Starting 1.21 Golang, go.mod requires the Go version and treats that as min required go version to compile your binary. So, also bump up the Go version for local builds. Additional changes: - As per golang/go#56319 and golang/go#54880, global rand is automatically, randomly seeded. So we don't need to call `Seed` anymore. - Package ioutil has been deprecated. Port the code to use replacement methods.
Determinstic random generator should not be set by rand.Seed https://pkg.go.dev/math/rand#Seed golang/go#56319
Determinstic random generator should not be set by rand.Seed https://pkg.go.dev/math/rand#Seed golang/go#56319
Determinstic random generator should not be set by rand.Seed https://pkg.go.dev/math/rand#Seed golang/go#56319
Determinstic random generator should not be set by rand.Seed https://pkg.go.dev/math/rand#Seed golang/go#56319
Determinstic random generator should not be set by rand.Seed https://pkg.go.dev/math/rand#Seed golang/go#56319
Proposal #54880, accepted last week, seeds math/rand randomly at startup. Part of the rationale is that programs that expect a specific determinstic sequence from the global rand functions (like rand.Int) are inherently fragile, since any package can change the number of times it calls those functions, which changes the results from all future calls by other packages. So programs should not depend on any kind of determinism from them.
For the same reason, I suggest we deprecate math/rand.Seed (the global seeder). Programs that need a specific deterministic sequence can do that more reliably using NewRand(NewSource(seed)), which they can be sure no other packages are consuming values from.
The text was updated successfully, but these errors were encountered: