[swift-evolution] [Proposal] Random Unification

Xiaodi Wu xiaodi.wu at gmail.com
Thu Nov 23 00:39:09 CST 2017

On Wed, Nov 22, 2017 at 22:55 Alejandro Alonso <aalonso128 at outlook.com>

> I pushed some updates to the proposal with a reflected API, but I do not
> agree that we should rid the API of T.random just because some users will
> misuse it. I think the correct solution here is to include T.random(in:)
> (which does not return an optional making it not a second typing of (min
> ... max).random). Like Jonathon said, autocomplete will display both of
> these and users will be able to select random(in:). I also disagree that
> T.random is _always_ followed by modulo because if we look at arc4random()
> it’s range is the whole domain of UInt32. Users don’t put a modulo here
> because they know the correct way to do it is through arc4random_uniform(),
> either through online tutorials, or by reading documentation. If we did get
> rid of T.random, users who want a random byte for instance would have to
> write UInt8.random(in: 0 … 255) every time. Developers will make wrappers
> over this. I believe the correct solution is to keep T.random for those who
> won’t misuse it and T.random(in:) for those who need to a random value
> within a range.

This is an exceedingly rare use case. Do you think it will be common that a
developer will want a single random byte? There will be much better ways to
request multiple bytes (through Data, for instance). And if a user wants
something like a value between 0...255 specifically, such as in the case of
elements of an RGB tuple, then (0...255).random is clearly a superior
spelling as compared to UInt8.random.

Quite simply, having seen how it is used in other languages, T.random is
vastly more likely to be misused than profitably used, by which I mean used
in a situation where an alternative spelling is clearly not good enough. It
should not be the simplest API offered, as its correct use is anything but

On Nov 17, 2017, 5:09 PM -0600, Xiaodi Wu <xiaodi.wu at gmail.com>, wrote:
> On Fri, Nov 17, 2017 at 10:10 AM, Gwendal Roué via swift-evolution <
> swift-evolution at swift.org> wrote:
>> > Le 17 nov. 2017 à 16:04, Alejandro Alonso via swift-evolution <
>> swift-evolution at swift.org> a écrit :
>> >
>> > If we go back to your example, you never call FixedWidthInteger.random
>> either, you call range.random. Does this mean integer types shouldn’t have
>> .random? No, because it means get a random number from it’s internal range
>> (alias to (min ... max).random). I think we can all agree that
>> Integer.random is a nicer api than making a range of its bounds. The same
>> goes for Date.random and Color.random.
>> >
>> > - Alejandro
>> Hello,
>> I'm not random expert, but it has never happened in my developer life
>> (backend & frontend app developer) that I have used a pure random value
>> from the full domain of the random type. In this life:
>> - Int.random is _always_ followed by % modulo. Unless the better
>> arc4random_uniform(max) is used.
>> - Color.random is _never_ used, because random colors look bad.
>> - Date.random is _never_ used, because time is a physical unit, and
>> random points in time do not match any physical use case.
>> This does not mean that random values from the full domain are useless.
>> Of course not: math apps, fuzzers, etc. need them.
>> Yet a range-based API would be much welcomed by regular app developers.
>> And also Array.randomElement(), Array.shuffled(), etc, because there are
>> plenty naive and bad algorithms for those simple tasks.
> Certainly it's hard to defend Date.random (and yes, it might be useful for
> a fuzzer, but that's a very niche use case--and in that case the fuzzer
> should probably also generate invalid/non-existent dates, which surely
> Date.random should not do). But actually, Int.random followed by % is the
> much bigger issue and a very good cautionary tale for why T.random is not a
> good idea. Swift should help users do the correct thing, and getting a
> random value across the full domain and computing an integer modulus is
> never the correct thing to do because of modulo bias, yet it's a very
> common error to make. We are much better off eliminating this API and
> encouraging use of the correct API, thereby reducing the likelihood of
> users making this category of error.
> If (and I agree with this) the range-based notation is less intuitive
> (0..<10.random is certainly less discoverable than Int.random), then we
> ought to offer an API in the form of `Int.random(in:)` but not
> `Int.random`. This does not preclude a `Collection.random` API as Alejandro
> proposes, of course, and that has independent value as Gwendal says.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171123/2941cad1/attachment.html>

More information about the swift-evolution mailing list