The accepted proposal to add Random API to the standard library defines a single random source in the standard library. Users can create their own random sources by writing types that conform to the RandomNumberGenerator
protocol. For convenience, the proposal includes a single generator as part of the standard library. The type is a struct currently named Random
. The initializer is private, so all usage of the Random
stdlib generator from clients must access the instance via a static property: Random.default
.
I am recommending an amendment to the proposal which provides a better name for this stdlib type. I propose that the stdlib generator should be called DefaultRandomNumberGenerator
. This name makes it plain that it is a default implementation of the RandomNumberGenerator
protocol. Random
is far too generic and does not allude to the fact that other sources of randomness can (and should) exist. The name DefaultRandomNumberGenerator
also indicates that it is merely the system default, and developers should consider whether other generators would be more appropriate for their particular case.
This naming pattern has precedence in other standard library API. A default implementation of a Collection.Indices
uses a type called DefaultIndices
, for example.
This proposed name-change would also require a change to the static property to prevent duplication of words. I propose DefaultRandomNumberGenerator.shared
.
Note that whilst DefaultRandomNumberGenerator.shared
as a term is significantly longer than Random.default
, the number of times an average user will type this is low. It is customary for random element accessors to provide two forms; one that includes an argument to supply a generator and another that implicitly uses the default stdlib generator. At an actual call site, a user of Swift will rarely actually include a definition of DefaultRandomNumberGenerator
in their code.
The main impact this change will have is on how the standard library defines its extensions, and what Swift programmers digging around in autocomplete will see.
For example, this code in the standard library:
extension Collection {
public func randomElement<T: RandomNumberGenerator>(
using generator: inout T
) -> Element?
public func randomElement() -> Element? {
return randomElement(using: &Random.default)
}
}
will become:
extension Collection {
public func randomElement<T: RandomNumberGenerator>(
using generator: inout T
) -> Element?
public func randomElement() -> Element? {
return randomElement(using: &DefaultRandomNumberGenerator.shared)
}
}
For most users of the API, there is unlikely to be any impact. People will still call collection.randomElement()
and collection.randomElement(using: otherRNG)
without ever paying the penalty of the extra characters, as the use of the stdlib generator is implicit and will rarely be typed explicitly.
However, in the times when the name of the type does appear, like in autocomplete lists, the intent of the DefaultRandomNumberGenerator
type is much clearer than the originally proposed, opaque, Random
name.
What do others think about this amendment?
(This commentary was previously brought up in the original proposal's review thread. A formal decision on the naming was overlooked. Per Ben Cohen's request, I am proposing the change as an amendment to the accepted proposal.)