Skip to content

Commit 01445d6

Browse files
committed
Use new forums link
Update other platforms table Fix typo Switch to generic constraints
1 parent d5c0b0f commit 01445d6

File tree

1 file changed

+80
-42
lines changed

1 file changed

+80
-42
lines changed

proposals/nnnn-random-unification.md

Lines changed: 80 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
This proposal's main focus is to create a unified random API, and a secure random API for all platforms.
1212

13-
*This idea has been floating around swift-evolution for a while now, but this is the thread that started this proposal: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039605.html*
13+
*This idea has been floating around swift-evolution for a while now, but this is the thread that started this proposal: https://forums.swift.org/t/proposal-random-unification/6626*
1414

1515
## Motivation
1616

@@ -93,29 +93,17 @@ To kick this off, we will be discussing the rngs that each operating system will
9393

9494
#### Linux Platform
9595

96-
We require that the kernel version be >= 3.17 as this was the release that introduced the `getrandom(2)` system call. We also require that glibc be >= 2.25 because this released exposed the `<sys/random.h>` header.
96+
We require that the kernel version be >= 3.17 as this was the release that introduced the `getrandom(2)` system call. We also require that glibc be >= 2.25 because this release exposed the `<sys/random.h>` header.
9797

9898
| Kernel Version < 3.17 && Glibc Version < 2.25 | Kernel Version >= 3.17 && Glibc Version >= 2.25 |
9999
|:---------------------------------------------:|:-----------------------------------------------:|
100100
| Read from `/dev/urandom` | Use `getrandom(2)` |
101101

102-
#### Android (Bionic) and Cygwin
102+
#### Other Platforms
103103

104-
| Bionic and Cygwin |
105-
|:------------------:|
106-
| Use `getrandom(2)` |
107-
108-
#### Fuchsia
109-
110-
| Fuchsia |
111-
|:-------------------:|
112-
| Use `getentropy(2)` |
113-
114-
#### Windows
115-
116-
| Windows |
117-
|:----------------------:|
118-
| Use `BCryptoGenRandom` |
104+
| Android (Bionic) and Cygwin | Fuchsia | Windows |
105+
|:---------------------------:|:-------------------:|:----------------------:|
106+
| Use `getrandom(2)` | Use `getentropy(2)` | Use `BCryptoGenRandom` |
119107

120108
### Random API
121109

@@ -224,16 +212,21 @@ public struct Random : RandomNumberGenerator {
224212

225213
public protocol Collection {
226214
// Returns a random element from the collection
227-
func random(using generator: RandomNumberGenerator) -> Element?
215+
func random<T: RandomNumberGenerator>(using generator: T) -> Element?
228216
}
229217

230218
// Default implementation
231219
extension Collection {
232-
// Returns a random element from the collection (defaults to using Random.default)
220+
// Returns a random element from the collection
233221
// Can return nil if isEmpty is true
234-
public func random(
235-
using generator: RandomNumberGenerator = Random.default
222+
public func random<T: RandomNumberGenerator>(
223+
using generator: T
236224
) -> Element?
225+
226+
/// Uses the standard library's default rng
227+
public func random() -> Element? {
228+
return random(using: Random.default)
229+
}
237230
}
238231

239232
// We have to add this extension to support syntax like (Int.min ..< Int.max).random()
@@ -242,11 +235,16 @@ extension Collection {
242235
extension Range
243236
where Bound : FixedWidthInteger,
244237
Bound.Magnitude : UnsignedInteger {
245-
// Returns a random element within lowerBound and upperBound (defaults to using Random.default)
238+
// Returns a random element within lowerBound and upperBound
246239
// Can return nil if lowerBound == upperBound
247-
public func random(
248-
using generator: RandomNumberGenerator = Random.default
240+
public func random<T: RandomNumberGenerator>(
241+
using generator: T
249242
) -> Element?
243+
244+
/// Uses the standard library's default rng
245+
public func random() -> Element? {
246+
return random(using: Random.default)
247+
}
250248
}
251249

252250
// We have to add this extension to support syntax like (Int.min ... Int.max).random()
@@ -255,10 +253,15 @@ where Bound : FixedWidthInteger,
255253
extension ClosedRange
256254
where Bound : FixedWidthInteger,
257255
Bound.Magnitude : UnsignedInteger {
258-
// Returns a random element within lowerBound and upperBound (defaults to using Random.default)
259-
public func random(
260-
using generator: RandomNumberGenerator = Random.default
256+
// Returns a random element within lowerBound and upperBound
257+
public func random<T: RandomNumberGenerator>(
258+
using generator: T
261259
) -> Element?
260+
261+
/// Uses the standard library's default rng
262+
public func random() -> Element? {
263+
return random(using: Random.default)
264+
}
262265
}
263266

264267
// Enables developers to use things like Int.random(in: 5 ..< 12) which does not use modulo bias.
@@ -274,15 +277,25 @@ extension FixedWidthInteger
274277
where Self.Stride : SignedInteger,
275278
Self.Magnitude : UnsignedInteger {
276279

277-
public static func random(
280+
public static func random<T: RandomNumberGenerator>(
278281
in range: Range<Self>,
279-
using generator: RandomNumberGenerator = Random.default
282+
using generator: T
280283
) -> Self
281284

282-
public static func random(
285+
/// Uses the standard library's default rng
286+
public static func random(in range: Range<Self>) -> Self {
287+
return Self.random(in: range, using: Random.default)
288+
}
289+
290+
public static func random<T: RandomNumberGenerator>(
283291
in range: ClosedRange<Self>,
284-
using generator: RandomNumberGenerator = Random.default
292+
using generator: T
285293
) -> Self
294+
295+
/// Uses the standard library's default rng
296+
public static func random(in range: ClosedRange<Self>) -> Self {
297+
return Self.random(in: range, using: Random.default)
298+
}
286299
}
287300

288301
// Enables developers to use things like Double.random(in: 5 ..< 12) which does not use modulo bias.
@@ -299,15 +312,25 @@ where Self.RawSignificand : FixedWidthInteger,
299312
Self.RawSignificand.Stride : SignedInteger & FixedWidthInteger,
300313
Self.RawSignificand.Magnitude : UnsignedInteger {
301314

302-
public static func random(
315+
public static func random<T: RandomNumberGenerator>(
303316
in range: Range<Self>,
304-
using generator: RandomNumberGenerator = Random.default
317+
using generator: T
305318
) -> Self
306319

307-
public static func random(
320+
/// Uses the standard library's default rng
321+
public static func random(in range: Range<Self>) -> Self {
322+
return Self.random(in: range, using: Random.default)
323+
}
324+
325+
public static func random<T: RandomNumberGenerator>(
308326
in range: ClosedRange<Self>,
309-
using generator: RandomNumberGenerator = Random.default
327+
using generator: T
310328
) -> Self
329+
330+
/// Uses the standard library's default rng
331+
public static func random(in range: ClosedRange<Self>) -> Self {
332+
return Self.random(in: range, using: Random.default)
333+
}
311334
}
312335

313336
// We add this as a convenience to something like:
@@ -316,25 +339,40 @@ where Self.RawSignificand : FixedWidthInteger,
316339
// understand what is going on. This extension methods helps bring clarity to
317340
// operations like these.
318341
extension Bool {
319-
public static func random(
320-
using generator: RandomNumberGenerator = Random.default
342+
public static func random<T: RandomNumberGenerator>(
343+
using generator: T
321344
) -> Bool
345+
346+
/// Uses the standard library's default rng
347+
public static func random() -> Bool {
348+
return Bool.random(using: Random.default)
349+
}
322350
}
323351

324352
// Shuffle API
325353

326354
// The shuffle API will utilize the Fisher Yates algorithm
327355

328356
extension Sequence {
329-
public func shuffled(
330-
using generator: RandomNumberGenerator = Random.default
357+
public func shuffled<T: RandomNumberGenerator>(
358+
using generator: T
331359
) -> [Element]
360+
361+
/// Uses the standard library's default rng
362+
public func shuffled() -> [Element] {
363+
return shuffled(using: Random.default)
364+
}
332365
}
333366

334367
extension MutableCollection {
335-
public mutating func shuffle(
336-
using generator: RandomNumberGenerator = Random.default
368+
public mutating func shuffle<T: RandomNumberGenerator>(
369+
using generator: T
337370
)
371+
372+
/// Uses the standard library's default rng
373+
public mutating func shuffle() {
374+
shuffle(using: Random.default)
375+
}
338376
}
339377
```
340378

0 commit comments

Comments
 (0)