To throw an idea out into the wild: How about a protocol to define the default
source fo random on a given platform, with per-platform extensions to provide
default implementations?
This would allow any eventual proposal to have default arguments for functions—
or to use within `var`s— without implicitly annotating one (CS)PRNG as the
de-facto RNG for Swift on all platforms, as well as remove the requirement for
providing a `shared` singleton on every (CS)PRNG.
I’m imagining something like this (names taken from, or inspired by, Félix’s
design for consistency within this discussion, I’m not strongly attached to any
of them):
```swift
protocol StandardRandomSource {
static var generator: RandomSource { get }
}
extension StandardRandomSource {
static var generator: RandomSource {
#if os(Linux)
// /dev/random chosen naively
return DeviceRandom.shared
#elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
// SecCopyRandomBytes-based, also chosen naively
return SecRandomSource()
#else
fatalError("Standard source of randomness not provided on
current platform")
#endif
}
}
```
and this new protocol could be used like this (largely copied from Félix’s
design):
```swift
extension Randomizable {
public static var random: Self {
return random(using: StandardRandomSource.generator)
}
}
extension FixedWidthInteger: {
public static func random(using source: RandomSource =
StandardRandomSource.generator) -> Self {
return (0 ..< Self.max).random(using: source)
}
}
```
On a more meta level, introducing this protocol lets us (Swift Evolution) kick
the question of “What (CS)PRNG gets implemented for a given OS as the default
provider?” further down the road instead of potentially blocking discussion for
a long time.
Another possible upside that I can think of is: We could let per-platform
implementations of this protocol could happen outside of the Swift Evolution
process. Hopefully this means it would be easier to amend or fix in the future,
as new platforms are added and new best practices arise.
A downside to this idea is that we’d be adding a protocol to the stdlib that
isn’t intended for people to implement, although there’s no possible harm if
anyone does so.
One other idea I also explored, but ultimately decided against was having
per-platform `typealias`es instead of a protocol with a default implementation.
Without a way to get an instance of a random number generator, I fell back to
requiring `var shared: Self` to stay in `RandomSource`, which didn’t seem as
necessary.
-z
> On Sep 25, 2017, at 9:57 PM, Alejandro Alonso via swift-evolution
> <[email protected]> wrote:
>
> Hello evolution,
>
> I am very thankful for all the feedback, and I’ve been working on a design
> that tries to utilize everybody’s ideas. The link to what I have so far is
> here: https://gist.github.com/Azoy/15f0518df38df9b722d4cb17bafea4c1. Please
> keep in mind this is just a design, no actual implementation as I would most
> likely need assistance in doing. The default source for randomness will use
> the OS’s unseeded CSPRNG. This current setup exposes developers to an API
> that lets them create their own RandomSources on the fly. I want to make the
> distinction that any existing or new sources of randomness that conform to
> UnsafeRandomSource are to be considered non cryptographically secure.
>
> I would love to get this discussion flowing again, and I would love input on
> the design. A few things I came across with this design is that some may want
> to use ranges as an argument for the numeric types, RandomAccessCollection
> returning an optional when getting a random, and how to incorporate an API
> that allows distributions. I wanted to get input on how you feel about each
> of these topics as I’m indifferent about them all. I’m in no way saying this
> is the design we should go for, but I’m simply providing something I think we
> should build on or talk about.
>
> - Alejandro
>
>> On Sep 8, 2017, 11:52 AM -0500, Alejandro Alonso via swift-evolution
>> <[email protected]>, wrote:
>> Hello swift evolution, I would like to propose a unified approach to
>> `random()` in Swift. I have a simple implementation here
>> https://gist.github.com/Azoy/5d294148c8b97d20b96ee64f434bb4f5. This
>> implementation is a simple wrapper over existing random functions so
>> existing code bases will not be affected. Also, this approach introduces a
>> new random feature for Linux users that give them access to upper bounds, as
>> well as a lower bound for both Glibc and Darwin users. This change would be
>> implemented within Foundation.
>>
>> I believe this simple change could have a very positive impact on new
>> developers learning Swift and experienced developers being able to write
>> single random declarations.
>>
>> I’d like to hear about your ideas on this proposal, or any implementation
>> changes if need be.
>>
>> - Alejando
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution