> On Jan 11, 2018, at 9:17 PM, Alejandro Alonso <aalonso...@outlook.com> 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. 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.

I would co-sign all of this except for preserving Int.random() and 
Double.random(), for the reasons I’ve laid out before, those Xiaodi responded 
with, and even the ergonomics of writing and reading code:

- For floating-point values, if someone wants a [0, 1) range, I see no problem 
with having them write `Double.random(in: 0..<1)`. That’s still nice and short, 
and there’s no question about what kind of values are produced.

- For integers, I see a basic breakdown into two use cases. First, there’s the 
case where you need a number in a specific range, for which the range-based 
methods are perfect. When you instead need a full-width integer, you’re 
generally using that integer as data, rather than as a value. The signedness of 
`Int` is a pain in that case, so you could either write `UInt64.random(in: .min 
... .max)` or else access data from whatever generator you’re 
using—`Random.default.next()`.

Also, from a discoverability and documentation perspective, I like having 
static `random` methods on the types that they generate. That feels like an 
easier pattern for a developer to recognize and use.

Nate

> - Alejandro
> 
> On Jan 8, 2018, 1:02 PM -0600, Nate Cook via swift-evolution 
> <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 
>>> <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 
>>>> <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