I am willing to give `.random()`. However I still wish to preserve 
`.random(in:)` and `.random()` on Bool.

Sent from my iPhone

On Jan 11, 2018, at 21:28, Xiaodi Wu 
<xiaodi...@gmail.com<mailto:xiaodi...@gmail.com>> wrote:

On Thu, Jan 11, 2018 at 9:17 PM, Alejandro Alonso via swift-evolution 
<swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:
Sorry it takes me forever to respond! I finally got around to writing this! 
School really takes all my time x)

I have a few ideas on where we can go with this:

1. I agree, we should ditch `Randomizable` as something like that should belong 
in a separate library or written by the user.

2. I also agree we should ditch the associated type on `RandomNumberGenerator`. 
I think we can sacrifice 32 bit generators using 64 bit ints to conform to the 
core team’s general use policy. This also makes default arguments for rngs 
possible which is a +1 for me!

I start to drift off from your design because `.random()` being an exception to 
ranges in that it’s inconsistent with other collection facilities and 
collection `.random()`. You make a few emails in the past that reference this 
as well. I think the right move is to have the static functions utilize the 
ranges to provide non optional types.

You wrote:

“
I see a couple points in favor of these static methods (or initializers) on the 
numeric types:

1) The collection method will need to return an optional to match the semantics 
of existing methods (like min()). If this is the only method available, every 
time someone needs a random value in the range 1...10, they’ll need to unwrap 
the result (with either force unwrapping, which people will complain about, or 
some kind of conditional binding, which is its own problem). Even if the 
semantics are the same (trapping on an empty range), the user experience of 
using a non-optional method will be better.



2) Floating-point ranges won’t get the collection method, so either we’ll have 
inconsistent APIs (random FP value is non-optional, random integer is optional) 
or we’ll make the FP API optional just to match. Both of those seem bad.
”

I believe this is the direction we need to go to keep consistency with 
collection based methods by justifying `.random(in:)` on the numeric types. 
With that in mind, Ben made a comment a long while ago saying, “The one 
downside is that you’d have to write 0..<Int.max. This might be a justification 
for a static property on one of the Integer protocols as shorthand for that.” I 
believe this makes it perfectly justifiable for `.random()` on numeric types. 
This also creates a consistency with `Bool.random()` making it justifiable for 
this as well.

We can do all of this without `Randomizable` as well! Add extension methods on 
`FixedWidthInteger`, `BinaryFloatingPoint`, and `Bool`. These will be the 
methods that crash on an empty range, but we can precondition here to provide 
helpful debugging for developers. You made reference to users using the range 
based api for a safe alternative if they needed optionals.

```
// Here you can use something more runtime oriented (such as an array count)
guard let x = (0 ..< 5).random() else {
 fatalError(“not going to happen")
}
```

I’m not too sure if you’ve had a change of heart, but I think the following is 
justifiable if we remove `Randomizable`.

Sample Syntax:
```
// Full Int width (shorthand for Int.random(in: .min … .max))
Int.random()

// random int from [0, 10)
Int.random(in: 0 ..< 10)

// random double from [0, 1) (Modulo isn’t an issue here!)
Double.random()

// random double from [0, .pi)
Double.random(in: 0 ..< .pi)

// random boolean
Bool.random()
```

This seems very consistent to me. The only inconsistency is with `Int.random()` 
covering the full width, and `Double.random()` covering only `[0, 1)`, but to 
me this functionality is very precedented in many other languages. Also by 
removing `Randomizable`, other data types like `Data` don’t have to conform to 
a protocol, but can just add a random initializer that fits its needs.

I think now is when people will start saying, “Int.random() bad, modulo bias, 
no no” x)
I see the potential for error here, but logically I’m thinking that so many 
other languages have this feature and I wonder if you think they all did it 
wrong too and shouldn’t have done so.

You will have noted, surely, the evidence given above that in Apple's internal 
code the majority of uses of APIs equivalent to `Int.random()` are erroneous 
due to unintended modulo bias. Yes, what that would imply is that all the other 
languages did it wrong. Why do you feel it is so important to have a shorthand 
that enables no additional behavior in the face of overwhelming evidence that 
it is actively harmful?

Likewise, you acknowledge the inconsistency of Int.random() and 
Double.random(), yet again suggest a shorthand that enables no additional 
behavior in spite of the potential for misunderstanding. What advantage of 
having such an API do you see which could overcome this very glaring drawback?

This type of behavior is found in C, C++, C#, Java, etc. I agree with Jonathon 
in that maybe we could suggest a warning/fixit in Xcode.

tl;dr - Remove `Randomizable`, remove associated type on 
`RandomNumberGenerator`, be consistent with `.random()` with other properties 
and functions with every collection, preserve static `random()` and 
`random(in:)` syntax.

- Alejandro

On Jan 8, 2018, 1:02 PM -0600, Nate Cook via swift-evolution 
<swift-evolution@swift.org<mailto:swift-evolution@swift.org>>, wrote:
I created a playground to explore this question, starting with a minimal subset 
of the proposal’s additions and building from there. The attached playground 
demonstrates what’s possible with this subset on the first page, then uses 
subsequent pages to explore how the main random facilities of the C++ STL work 
under this model. (In my opinion, they work pretty well!)

The subset in the playground has three main differences from the proposal:
 - It doesn't include a Randomizable protocol or a random property on numeric 
types.
 - It doesn't include the static random(in:) methods on numeric types, either.
 - The RandomNumberGenerator protocol doesn't have an associated type. Instead, 
it requires all conforming types to produce UInt64 values.

I’ve tried to include a bit of real-world usage in the playground to 
demonstrate what writing code would look like with these additions. Please take 
a look!

Nate


On Dec 2, 2017, at 9:50 PM, Dave Abrahams via swift-evolution 
<swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:

I don’t have much to say about this other than that I think the discussion 
seems way too narrow, focusing on spelling rather than on functionality and 
composability.  I consider the “generic random number library” design to be a 
mostly-solved problem, in the C++ standard library 
(http://en.cppreference.com/w/cpp/numeric/random).  Whatever goes into the 
Swift standard library does not need to have all those features right away, but 
should support being extended into something having the same general shape. IMO 
the right design strategy is to implement and use a Swift version of C++’s 
facilities and only then consider proposing [perhaps a subset of] that design 
for standardization in Swift.

Sent from my iPad

On Dec 2, 2017, at 5:12 PM, Kyle Murray via swift-evolution 
<swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:


On Dec 2, 2017, at 6:02 PM, Xiaodi Wu via swift-evolution 
<swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:

Instead, we ought to make clear to users both the features and the limitations 
of this API, to encourage use where suitable and to discourage use where 
unsuitable.

I like that you're considering the balance here. I've been lightly following 
this thread and want to add my thoughts on keeping crypto and pseudorandomness 
out of the name of at least one random API intended for general use.

For someone who doesn't know or care about the subtleties of insecure or 
pseudorandom numbers, I'm not sure that the name insecureRandom is effectively 
much different than badRandom, at least in terms of the information it conveys 
to non-experts. To Greg's point, that's the opposite of the signal that the API 
name should suggest because it's what most people should use most of the time. 
As you say, this API is being designed for general use.

There's a cost to adding extra complexity to names, too. I don't think it's 
far-fetched to suspect that people who find insecureRandom in an autocomplete 
listing or search will think "Where's the plain random function?"... and then 
go looking for a community extension that will inevitably provide a trivial 
alias: func random() { return insecureRandom() }. That's the sort of adoption 
I'd expect from something for new programmers, like Swift Playgrounds. 
Someone's introduction to randomness in programming should probably involve no 
more than a straightforward mapping from the elementary definition, rather than 
forcing a teaching moment from more advanced math.

I think there are better places for caveat information than in the API names 
themselves; documentation being one clear destination. This is in contrast with 
Unsafe*Pointer, where the safety element is critical enough to be elevated to 
be more than caveat-level information. You can go really far and create really 
cool things before these caveats start to apply. Using randomness as a black 
box in an intro programming environment seems like a much more common scenario 
than someone attempting to roll their first crypto by only reading API names 
and hoping for the best.

-Kyle
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org<mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org<mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org<mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to