-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
We could rename globalRand to GlobalRand now, and drop the package methods (e.g. rand.ExpFloat64) as part of Go 2.
The benefits I see to making the default instance public are:
-
Maintainers would get a simpler implementation (eventually). The backing code has 83 lines invested in the exposure itself, which we could drop in a stroke at Go 2. And while the tests seem to generally use local
Randinstances, at least one benchmark has decided to use the global function.Before Go 2, the additional maintainer load seems small (a one-off
s/globalRand/GlobalRand/inrand.goand time to write up the godoc comment for the newGlobalRand. -
Users who don't need multiple
Randwould gain the ability to pass the public global instance into functions that took aRandargument and structures that take aRandproperty. Checking in the Go corpus v0.1, shows 163 such functions:go-corpus-0.01 $ (cd src && for DIR in . * github.com/*; do echo -n "${DIR}: "; grep -r '^func .*rand\.Rand' "${DIR}" | wc -l; done) | grep -v ' 0$' .: 163 github.com: 146 go.uber.org: 1 golang.org: 8 google.golang.org: 1 k8s.io: 7 github.com/CodisLabs: 1 github.com/attic-labs: 19 github.com/aws: 1 github.com/boltdb: 2 github.com/coreos: 1 github.com/cznic: 1 github.com/docker: 5 github.com/dropbox: 1 github.com/ethereum: 18 github.com/gonum: 26 github.com/gravitational: 1 github.com/hashicorp: 1 github.com/hyperledger: 7 github.com/influxdata: 2 github.com/kelseyhightower: 1 github.com/miekg: 2 github.com/onsi: 2 github.com/openshift: 13 github.com/openzipkin: 1 github.com/oschwald: 1 github.com/pingcap: 15 github.com/prometheus: 6 github.com/streadway: 2 github.com/syndtr: 13 github.com/yudai: 4
-
Everyone gets a simpler API once we hit Go 2 and can drop the package-level methods. Currently the math/rand docs are a longer read than they need to be because each
Randmethod is documented in two places.
Potential drawbacks include:
-
Increased exposure for folks who miss the need to seed their generator if they want different values (lots of discussion in math/rand: Deterministic random by default is dangerousย #11871), because they would be able to stuff an unseeded global
Randinto functions and structures that called for aRand. I think this is mitigated by the current math/rand docs that recommend seeding and point at crypto/rand for security-sensitive work. -
A few extra characters (e.g.
rand.Intn->rand.GlobalRand.Intn) for folks calling the global in Go 2+.
Personally I think the "simpler API" arguments are fairly strong. The "user convenience" argument is weaker, because calling rand.New(rand.NewSource(yourSeed())) is not much more difficult than using rand.GlobalRand after having previously called rand.GlobalRand.Seed(yourSeed()). But I don't think the arguments against are very strong either, so on the whole I come out in favor of the global. I'm not a maintainer though, and I may be missing things.
I also wouldn't be surprised if this had been proposed before, but I have been unable to turn up references to it (either in this repo's issues or in the golang-dev@ logs). The current private globalRand dates back to 3342574 (2009-10-15). The commit message has OCL and CL tags, which may be related to external review (like the modern Reviewed-on), but if so, I'm not sure where that review is stored.