Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Xiaodi Wu via swift-evolution
On Fri, Sep 8, 2017 at 7:50 PM, Stephen Canon  wrote:

> On Sep 8, 2017, at 8:09 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> This topic has been broached on Swift Evolution previously. It's
> interesting to me that Steve Canon is so certain that CSPRNGs are the way
> to go. I wasn't aware that hardware CSPRNGs have come such a long way and
> are so ubiquitous as to be feasible as a basis for Swift random numbers. If
> so, great.
>
> Otherwise, if there is any way that a software, non-cryptographically
> secure PRNG is going to outperform a CSPRNG, then I think it's worthwhile
> to have a (carefully documented) choice between the two. I would imagine
> that for many uses, such as an animation in which you need a plausible
> source of noise to render a flame, whether that is cryptographically secure
> or not is absolutely irrelevant but performance may be key.
>
>
> Let me be precise: it is absolutely possible to outperform CSPRNGs. They
> have simply become fast enough that the performance gap doesn’t matter for
> most uses (let’s say amortized ten cycles per byte or less—whatever you are
> going to do with the random bitstream will be much more expensive than
> getting the bits was).
>
> That said, yes, there should definitely be other options. It should be
> possible for users to get reproducible results from a stdlib random
> interface run-to-run, and also across platforms. That alone requires that
> at least one other option for a generator be present. There may also be a
> place for a very high-throughput generator like xorshiro128+.
>
> All I’m really saying is that the *default* generator should be an
> os-provided unseeded CSPRNG, and we should be very careful about
> documenting any generator options.
>


Agree on all points. Much like Swift's strings are Unicode-correct instead
of the fastest possible way of slicing and dicing sequences of ASCII
characters, Swift's default PRNG should be cryptographically secure.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Explicit Synthetic Behaviour

2017-09-08 Thread Xiaodi Wu via swift-evolution
On Fri, Sep 8, 2017 at 4:00 PM, Itai Ferber via swift-evolution <
swift-evolution@swift.org> wrote:

>
>
> On Sep 8, 2017, at 12:46 AM, Haravikk via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On 7 Sep 2017, at 22:02, Itai Ferber  wrote:
>
> protocol Fooable : Equatable { // Equatable is just a simple example
> var myFoo: Int { get }}
> extension Fooable {
> static func ==(_ lhs: Self, _ rhs: Self) -> Bool {
> return lhs.myFoo == rhs.myFoo
> }}
> struct X : Fooable {
> let myFoo: Int
> let myName: String
> // Whoops, forgot to give an implementation of ==}
> print(X(myFoo: 42, myName: "Alice") == X(myFoo: 42, myName: "Bob")) // true
>
> This property is *necessary*, but not *sufficient* to provide a correct
> implementation. A default implementation might be able to *assume* something
> about the types that it defines, but it does not necessarily know enough.
>
>
> Sorry but that's a bit of a contrived example; in this case the protocol
> should *not* implement the equality operator if more information may be
> required to define equality. It should only be implemented if the protocol
> is absolutely clear that .myFoo is the only part of a Fooable that can or
> should be compared as equatable, e.g- if a Fooable is a database record and
> .myFoo is a primary key, the data could differ but it would still be a
> reference to the same record.
>
> To be clear, I'm not arguing that someone can't create a regular default
> implementation that also makes flawed assumptions, but that
> synthesised/reflective implementations *by their very nature have to*, as
> they cannot under every circumstance guarantee correctness when using parts
> of a concrete type that they know nothing about.
>
> You can’t argue this both ways:
>
>- If you’re arguing this on principle, that in order for synthesized
>implementations to be correct, they *must* be able to — *under every
>circumstance* — guarantee correctness, then you have to apply the same
>reasoning to default protocol implementations. Given a default protocol
>implementation, it is possible to come up with a (no matter how contrived)
>case where the default implementation is wrong. Since you’re arguing this 
> *on
>principle*, you cannot reject contrived examples.
>- If you are arguing this *in practice*, then you’re going to have to
>back up your argument with evidence that synthesized examples are more
>often wrong than default implementations. You can’t declare that
>synthesized implementations are *by nature* incorrect but allow
>default implementations to slide because *in practice*, many
>implementations are allowable. There’s a reason why synthesis passed code
>review and was accepted: in the majority of cases, synthesis was deemed to
>be beneficial, and would provide correct behavior. If you are willing to
>say that yes, sometimes default implementations are wrong but overall
>they’re correct, you’re going to have to provide hard evidence to back up
>the opposite case for synthesized implementations. You stated in a previous
>email that "A synthesised/reflective implementation however may return
>a result that is simply incorrect, because it is based on assumptions made
>by the protocol developer, with no input from the developer of the concrete
>type. In this case the developer must override it in to provide
>*correct* behaviour." — if you can back this up with evidence (say,
>taking a survey of a large number of model types and see if in the majority
>of cases synthesized implementation would be incorrect) to provide a
>compelling argument, then this is something that we should in that case
>reconsider.
>
>
Well put, and I agree with this position 100%. However, to play devil's
advocate here, let me summarize what I think Haravikk is saying:

I think the "synthesized" part of this is a red herring, if I understand
Haravikk's argument correctly. Instead, it is this:

(1) In principle, it is possible to have a default implementation for a
protocol requirement that produces the correct result--though not
necessarily in the most performant way--for all possible conforming types,
where by conforming we mean that the type respects both the syntactic
requirements (enforced by the compiler) and the semantic requirements
(which may not necessarily be enforceable by the compiler) of the protocol
in question.

(2) However, there exist *some* requirements that, by their very nature,
cannot have default implementations which are guaranteed to produce the
correct result for all conforming types. In Haravikk's view, no default
implementations should be provided in these cases. (I don't necessarily
subscribe to this view in absolute terms, but for the sake of argument
let's grant this premise.)

(3) Equatable, Hashable, and Codable requirements are, by their very
nature, such requirements that cannot have 

Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Stephen Canon via swift-evolution
> On Sep 8, 2017, at 8:09 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> This topic has been broached on Swift Evolution previously. It's interesting 
> to me that Steve Canon is so certain that CSPRNGs are the way to go. I wasn't 
> aware that hardware CSPRNGs have come such a long way and are so ubiquitous 
> as to be feasible as a basis for Swift random numbers. If so, great.
> 
> Otherwise, if there is any way that a software, non-cryptographically secure 
> PRNG is going to outperform a CSPRNG, then I think it's worthwhile to have a 
> (carefully documented) choice between the two. I would imagine that for many 
> uses, such as an animation in which you need a plausible source of noise to 
> render a flame, whether that is cryptographically secure or not is absolutely 
> irrelevant but performance may be key.

Let me be precise: it is absolutely possible to outperform CSPRNGs. They have 
simply become fast enough that the performance gap doesn’t matter for most uses 
(let’s say amortized ten cycles per byte or less—whatever you are going to do 
with the random bitstream will be much more expensive than getting the bits 
was).

That said, yes, there should definitely be other options. It should be possible 
for users to get reproducible results from a stdlib random interface 
run-to-run, and also across platforms. That alone requires that at least one 
other option for a generator be present. There may also be a place for a very 
high-throughput generator like xorshiro128+.

All I’m really saying is that the *default* generator should be an os-provided 
unseeded CSPRNG, and we should be very careful about documenting any generator 
options.

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


Re: [swift-evolution] [Pitch] Synthesized static enum property to iterate over cases

2017-09-08 Thread Xiaodi Wu via swift-evolution
On Fri, Sep 8, 2017 at 4:08 PM, Matthew Johnson via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On Sep 8, 2017, at 12:05 PM, Tony Allevato 
> wrote:
>
>
>
> On Fri, Sep 8, 2017 at 9:44 AM Matthew Johnson 
> wrote:
>
>> On Sep 8, 2017, at 11:32 AM, Tony Allevato 
>> wrote:
>>
>>
>>
>> On Fri, Sep 8, 2017 at 8:35 AM Matthew Johnson 
>> wrote:
>>
>>> On Sep 8, 2017, at 9:53 AM, Tony Allevato via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> Thanks for bringing this up, Logan! It's something I've been thinking
>>> about a lot lately after a conversation with some colleagues outside of
>>> this community. Some of my thoughts:
>>>
>>> AFAIK, there are two major use cases here: (1) you need the whole
>>> collection of cases, like in your example, and (2) you just need the number
>>> of cases. The latter seems to occur somewhat commonly when people want to
>>> use an enum to define the sections of, say, a UITableView. They just return
>>> the count from numberOfSections(in:) and then switch over the cases in
>>> their cell-providing methods.
>>>
>>> Because of #2, it would be nice to avoid instantiating the collection
>>> eagerly. (Also because of examples like Jonathan's, where the enum is
>>> large.) If all the user is ever really doing is iterating over them,
>>> there's no need to keep the entire collection in memory. This leads us to
>>> look at Sequence; we could use something like AnySequence to keep the
>>> current case as our state and a transition function to advance to the next
>>> one. If a user needs to instantiate the full array from that sequence they
>>> can do so, but they have to do it explicitly.
>>>
>>> The catch is that Sequence only provides `underestimatedCount`, rather
>>> than `count`. Calling the former would be an awkward API (why is it
>>> underestimated? we know how many cases there are). I suppose we could
>>> create a concrete wrapper for Sequence (PrecountedSequence?) that provides
>>> a `count` property to make that cleaner, and then have
>>> `underestimatedCount` return the same thing if users passed this thing into
>>> a generic operation constrained over Sequence. (The standard library
>>> already has support wrappers like EnumeratedSequence, so maybe this is
>>> appropriate.)
>>>
>>> Another question that would need to be answered is, how should the cases
>>> be ordered? Declaration order seems obvious and straightforward, but if you
>>> have a raw-value enum (say, integers), you could have the declaration order
>>> and the numeric order differ. Maybe that's not a problem. Tying the
>>> iteration order to declaration order also means that the behavior of a
>>> program could change simply by reördering the cases. Maybe that's not a big
>>> problem either, but it's something to call out.
>>>
>>> If I were designing this, I'd start with the following approach. First,
>>> add a new protocol to the standard library:
>>>
>>> ```
>>> public protocol ValueEnumerable {
>>>   associatedtype AllValuesSequence: Sequence where
>>> AllValuesSequence.Iterator.Element == Self
>>>
>>>   static var allValues: AllValuesSequence { get }
>>> }
>>> ```
>>>
>>> Then, for enums that declare conformance to that protocol, synthesize
>>> the body of `allValues` to return an appropriate sequence. If we imagine a
>>> model like AnySequence, then the "state" can be the current case, and the
>>> transition function can be a switch/case that returns it and advances to
>>> the next one (finally returning nil).
>>>
>>> There's an opportunity for optimization that may or may not be worth it:
>>> if the enum is RawRepresentable with RawValue == Int, AND all the raw
>>> values are in a contiguous range, AND declaration order is numerical order
>>> (assuming we kept that constraint), then the synthesized state machine can
>>> just be a simple integer incrementation and call to `init?(rawValue:)`.
>>> When all the cases have been generated, that will return nil on its own.
>>>
>>> So that covers enums without associated values. What about those with
>>> associated values? I would argue that the "number of cases" isn't something
>>> that's very useful here—if we consider that enum cases are really factory
>>> functions for concrete values of the type, then we shouldn't think about
>>> "what are all the cases of this enum" but "what are all the values of this
>>> type". (For enums without associated values, those are synonymous.)
>>>
>>> An enum with associated values can potentially have an infinite number
>>> of values. Here's one:
>>>
>>> ```
>>> enum BinaryTree {
>>>   case subtree(left: BinaryTree, right: BinaryTree)
>>>   case leaf
>>>   case empty
>>> }
>>> ```
>>>
>>> Even without introducing an Element type in the leaf nodes, there are a
>>> countably infinite number of binary trees. So first off, we wouldn't be
>>> able to generate a meaningful `count` property for that. Since 

Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Jonathan Hull via swift-evolution
Here is some Swift 3 code that allows simple repeatable repeatable random 
sequences by conforming to a protocol:
https://gist.github.com/jonhull/3655672529f8cf5b2eb248583d2cafb9
 
I now use a slightly more complicated version of this which allows more complex 
types (like colors) to be added and constrained in more interesting ways than 
just from…to (e.g. Colors with a fixed lightness/brightness, but a range in 
hue). The base is pretty much the same.

I have found that user-facing code often needs the idea of 
repeatable/re-creatable randomness. I originally created it to create a sketchy 
version of lines that had random offsets added to points along the line. If the 
randomness wasn’t reproducible, then the sketchiness of the line would shift 
around randomly every time there was a change.

The code I have provided above is not useful for any sort of 
cryptography/security though.  There are different reasons for randomness. 
Maybe that is something we should consider?

Thanks,
Jon

> On Sep 8, 2017, at 9:52 AM, Alejandro Alonso via swift-evolution 
>  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
> 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


Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Kevin Nattinger via swift-evolution

> On Sep 8, 2017, at 2:46 PM, Jacob Williams via swift-evolution 
>  wrote:
> 
> What if we did it with something like this:
> 
> protocol RandomGenerator {
>   associated type T: Numeric // Since numeric types are the only kinds 
> where we could get a random number?
>   func uniform() -> T
>   // Other random type functions...
> }

I support a protocol, but not one with an associated type; those are an 
enormous pain in the rear to work with. They're quite probably my biggest gripe 
with Swift (and it's not a short list).  I shouldn't have to make an entire 
class generic just so I can have an RNG that I'll probably want to be a private 
field anyway.

> 
> Although if we didn’t constrain T to Numeric then collections could also 
> conform to it, although I’m not sure that collections would want to directly 
> conform to this. There may need to be a separate protocol for types with 
> Numeric indexes?
> 
> I’m no pro and really haven’t thought about this too deeply. Mostly just 
> spitballing/brainstorming.
> 
>> On Sep 8, 2017, at 3:03 PM, Jacob Williams via swift-evolution 
>> > wrote:
>> 
>> Huge +1 to stdlib (or even Foundation) random number generator. I’ve worked 
>> with random numbers on both Linux and macOS/iOS and have found myself 
>> annoyed with the lack of easy random number generators. It seems that 
>> implementing a pure Swift RNG would be an obviously good addition to the 
>> stdlib.
>> 
>> I don’t think that it would be possible to make this work for floating point 
>> numbers. Although admittedly, I know very little about Floating Point 
>> numbers. I think this is still a worthwhile addition to Swift even for just 
>> Integers alone.
>> 
>>> On Sep 8, 2017, at 1:30 PM, Ben Cohen via swift-evolution 
>>> > wrote:
>>> 
>>> Hi Alejandro,
>>> 
>>> I’m really happy to see someone pick this up. We had suggested some kind of 
>>> random support could be a goal for addition to the standard library in 
>>> Swift 4 phase 2 but didn’t manage it, so I definitely think a good proposal 
>>> would be given consideration for Swift 5.
>>> 
>>> Regarding the implementation – I would suggest exploring something along 
>>> the lines of an extension on RandomAccessCollection that adds a property 
>>> for a random element, rather than a pair of free functions. This would have 
>>> a number of benefits:
>>> 
>>>  - a very common use case is picking a random entry from a collection, 
>>> which this would do automatically
>>>  - it gives you a very natural way of expressing a ranged random number 
>>> i.e. (0..<10).randomElement (not necessarily recommending that name btw, 
>>> it’s one of various possibilities)
>>>  - since both kinds of countable ranges are collections, it sidesteps that 
>>> issue :)
>>>  - it allows for multiple different integers without the need for casting 
>>> i.e. in the above, if type context meant the result was a UInt16, that’s 
>>> what it would be
>>> 
>>> The one downside is that you’d have to write (0..>> justification for a static property on one of the Integer protocols as 
>>> shorthand for that.
>>> 
>>> The tricky part (in addition to the cross-platform aspect) is ensuring 
>>> correct distribution across the possible distances. But since this is 
>>> something that people might easily get wrong, that reinforces the idea of 
>>> this being something that’s easy to use correctly in the std lib.
>>> 
>>> I’d also suggest proposing a shuffle implementation for 
>>> RandomAccessCollection+MutableCollection at the same time (probably as a 
>>> separate but linked proposal), since this is also something that is often 
>>> requested, easy to get wrong, and needs a cross-platform source of random 
>>> numbers.
>>> 
>>> Regards,
>>> Ben
>>> 
>>> 
 On Sep 8, 2017, at 10:34 AM, Alejandro Alonso via swift-evolution 
 > wrote:
 
 Range support is something that came up, and I think it’s a great idea as 
 well. My question now is do we support both `CountableRange` and 
 `CountableClosedRange`?
 
 On Sep 8, 2017, 12:08 PM -0500, Shawn Erickson >, wrote:
> It would be nice to leverage range support instead of a start and end 
> value IMHO.
> On Fri, Sep 8, 2017 at 9:52 AM Alejandro Alonso via swift-evolution 
> > 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 
> 

Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Jacob Williams via swift-evolution
What if we did it with something like this:

protocol RandomGenerator {
associated type T: Numeric // Since numeric types are the only kinds 
where we could get a random number?
func uniform() -> T
// Other random type functions...
}

Although if we didn’t constrain T to Numeric then collections could also 
conform to it, although I’m not sure that collections would want to directly 
conform to this. There may need to be a separate protocol for types with 
Numeric indexes?

I’m no pro and really haven’t thought about this too deeply. Mostly just 
spitballing/brainstorming.

> On Sep 8, 2017, at 3:03 PM, Jacob Williams via swift-evolution 
>  wrote:
> 
> Huge +1 to stdlib (or even Foundation) random number generator. I’ve worked 
> with random numbers on both Linux and macOS/iOS and have found myself annoyed 
> with the lack of easy random number generators. It seems that implementing a 
> pure Swift RNG would be an obviously good addition to the stdlib.
> 
> I don’t think that it would be possible to make this work for floating point 
> numbers. Although admittedly, I know very little about Floating Point 
> numbers. I think this is still a worthwhile addition to Swift even for just 
> Integers alone.
> 
>> On Sep 8, 2017, at 1:30 PM, Ben Cohen via swift-evolution 
>> > wrote:
>> 
>> Hi Alejandro,
>> 
>> I’m really happy to see someone pick this up. We had suggested some kind of 
>> random support could be a goal for addition to the standard library in Swift 
>> 4 phase 2 but didn’t manage it, so I definitely think a good proposal would 
>> be given consideration for Swift 5.
>> 
>> Regarding the implementation – I would suggest exploring something along the 
>> lines of an extension on RandomAccessCollection that adds a property for a 
>> random element, rather than a pair of free functions. This would have a 
>> number of benefits:
>> 
>>  - a very common use case is picking a random entry from a collection, which 
>> this would do automatically
>>  - it gives you a very natural way of expressing a ranged random number i.e. 
>> (0..<10).randomElement (not necessarily recommending that name btw, it’s one 
>> of various possibilities)
>>  - since both kinds of countable ranges are collections, it sidesteps that 
>> issue :)
>>  - it allows for multiple different integers without the need for casting 
>> i.e. in the above, if type context meant the result was a UInt16, that’s 
>> what it would be
>> 
>> The one downside is that you’d have to write (0..> justification for a static property on one of the Integer protocols as 
>> shorthand for that.
>> 
>> The tricky part (in addition to the cross-platform aspect) is ensuring 
>> correct distribution across the possible distances. But since this is 
>> something that people might easily get wrong, that reinforces the idea of 
>> this being something that’s easy to use correctly in the std lib.
>> 
>> I’d also suggest proposing a shuffle implementation for 
>> RandomAccessCollection+MutableCollection at the same time (probably as a 
>> separate but linked proposal), since this is also something that is often 
>> requested, easy to get wrong, and needs a cross-platform source of random 
>> numbers.
>> 
>> Regards,
>> Ben
>> 
>> 
>>> On Sep 8, 2017, at 10:34 AM, Alejandro Alonso via swift-evolution 
>>> > wrote:
>>> 
>>> Range support is something that came up, and I think it’s a great idea as 
>>> well. My question now is do we support both `CountableRange` and 
>>> `CountableClosedRange`?
>>> 
>>> On Sep 8, 2017, 12:08 PM -0500, Shawn Erickson >> >, wrote:
 It would be nice to leverage range support instead of a start and end 
 value IMHO.
 On Fri, Sep 8, 2017 at 9:52 AM Alejandro Alonso via swift-evolution 
 > 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 

Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread David Hart via swift-evolution

> On 8 Sep 2017, at 23:01, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
>> On Sep 8, 2017, at 2:30 PM, Ben Cohen via swift-evolution 
>> > wrote:
>> 
>> Hi Alejandro,
>> 
>> I’m really happy to see someone pick this up. We had suggested some kind of 
>> random support could be a goal for addition to the standard library in Swift 
>> 4 phase 2 but didn’t manage it, so I definitely think a good proposal would 
>> be given consideration for Swift 5.
>> 
>> Regarding the implementation – I would suggest exploring something along the 
>> lines of an extension on RandomAccessCollection that adds a property for a 
>> random element, rather than a pair of free functions. This would have a 
>> number of benefits:
>> 
>>  - a very common use case is picking a random entry from a collection, which 
>> this would do automatically
>>  - it gives you a very natural way of expressing a ranged random number i.e. 
>> (0..<10).randomElement (not necessarily recommending that name btw, it’s one 
>> of various possibilities)
>>  - since both kinds of countable ranges are collections, it sidesteps that 
>> issue :)
>>  - it allows for multiple different integers without the need for casting 
>> i.e. in the above, if type context meant the result was a UInt16, that’s 
>> what it would be
>> 
>> The one downside is that you’d have to write (0..> justification for a static property on one of the Integer protocols as 
>> shorthand for that.
>> 
>> The tricky part (in addition to the cross-platform aspect) is ensuring 
>> correct distribution across the possible distances. But since this is 
>> something that people might easily get wrong, that reinforces the idea of 
>> this being something that’s easy to use correctly in the std lib.
>> 
>> I’d also suggest proposing a shuffle implementation for 
>> RandomAccessCollection+MutableCollection at the same time (probably as a 
>> separate but linked proposal), since this is also something that is often 
>> requested, easy to get wrong, and needs a cross-platform source of random 
>> numbers.
> 
> How would this design address the relatively common use case of wanting a 
> random floating point number in the range `0…1` or `0..<1`?  Floating point 
> ranges are not countable.

Perhaps we should special case floating point ranges. Not sure we can 
generalise anything in that case.

>> 
>> Regards,
>> Ben
>> 
>> 
>>> On Sep 8, 2017, at 10:34 AM, Alejandro Alonso via swift-evolution 
>>> > wrote:
>>> 
>>> Range support is something that came up, and I think it’s a great idea as 
>>> well. My question now is do we support both `CountableRange` and 
>>> `CountableClosedRange`?
>>> 
>>> On Sep 8, 2017, 12:08 PM -0500, Shawn Erickson >> >, wrote:
 It would be nice to leverage range support instead of a start and end 
 value IMHO.
 On Fri, Sep 8, 2017 at 9:52 AM Alejandro Alonso via swift-evolution 
 > 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
 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 
>>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution 

Re: [swift-evolution] [Concurrency] async/await + actors

2017-09-08 Thread David Hart via swift-evolution

> On 8 Sep 2017, at 20:34, Kenny Leung via swift-evolution 
>  wrote:
> 
> Hi All.
> 
> A point of clarification in this example:
> 
> func loadWebResource(_ path: String) async -> Resource
> func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image
> func dewarpAndCleanupImage(_ i : Image) async -> Image
> 
> func processImageData1() async -> Image {
> let dataResource  = await loadWebResource("dataprofile.txt")
> let imageResource = await loadWebResource("imagedata.dat")
> let imageTmp  = await decodeImage(dataResource, imageResource)
> let imageResult   = await dewarpAndCleanupImage(imageTmp)
> return imageResult
> }
> 
> Do these:
> 
> await loadWebResource("dataprofile.txt")
> await loadWebResource("imagedata.dat")
> 
> happen in in parallel?

They don’t happen in parallel.

> If so, how can I make the second one wait on the first one? If not, how can I 
> make them go in parallel?
> 
> Thanks!
> 
> -Kenny
> 
> ___
> swift-evolution mailing list
> 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


Re: [swift-evolution] [SE-0155][Discuss] The role of labels in enum case patterns

2017-09-08 Thread Matthew Johnson via swift-evolution

> On Sep 8, 2017, at 4:26 PM, Robert Widmann  wrote:
> 
>> 
>> On Sep 8, 2017, at 2:59 PM, Matthew Johnson > > wrote:
>> 
>>> 
>>> On Sep 8, 2017, at 2:17 PM, Robert Widmann >> > wrote:
>>> 
 
 On Sep 4, 2017, at 11:35 AM, Matthew Johnson via swift-evolution 
 > wrote:
 
 
> On Sep 4, 2017, at 11:47 AM, T.J. Usiyan  > wrote:
> 
> I wasn't arguing for a strictly parallel syntax. I was arguing against 
> being able to omit labels. I don't view those as strictly tied together. 
> How are they?
 
 Like Xiaodi I don’t think it would be productive to rehash the prior 
 discussion so I’m going to try to be brief.  
 
 In the discussion one idea that arose was to support two labels for 
 associated values in a manner similar to parameters.  One would be used 
 during construction and the other during matching.  
 
 The idea behind this was that when creating a value a case is analagous to 
 a factory method and it would be nice to be able provide labels using the 
 same naming guidelines we use for external argument labels.  For example, 
 if an associated value was an index `at` might be used for clarity at the 
 call site.  Labels like this don’t necessarily make as much sense when 
 destructuring the value.  The idea of the “internal” label of a case was 
 that it would be used when matching and could be elided if the bound name 
 was identical.  In the example, `index` might be used.
>>> 
>>> It’s an interesting idea, but I don’t know of too many cases where I 
>>> wouldn’t want the name for destructuring to serve as an API name somehow.  
>>> A function may use labels to aid understanding, flow,  readability, etc. 
>>> but an enum case is not necessarily a function-like value, nor does this 
>>> proposal want them to be (modulo some internal modeling).
>> 
>> An enum case is *exactly* analogous to a static factory method or property 
>> when it is used to construct values.  It obviously plays a different role in 
>> pattern context.
>> 
>>> 
 
 When matching, `let` is interspersed between the label and the name 
 binding.
>>> 
>>> Good thing this works then
>>> 
>>> enum Foo {
>>>   case foo(x: Int, y: String, z: Float)
>>> }
>>> 
>>> func bar(_ x : Foo) {
>>>   switch x {
>>>   case let .foo(x: x, y: y, z: z): break
>>>   }
>>> }
>> 
>> I consider this syntax to be an anti-pattern.  It can be unclear where a new 
>> name is bound and where the value of a pre-existing name is matched.
>> 
>>> 
>>> Even better, John mentioned in the rationale that if the labels ever grow 
>>> to be clumsy we can come up with some kind of “ellipses-like” pattern to 
>>> indicate we intend to match all the labelled values as they are so named, 
>>> etc.  
>> 
>> It sounds like this would introduce name bindings without the name being 
>> explicitly declared.  That works fine where there is a standard pattern such 
>> as `oldValue` in a property observer.  I’m not sure I would like it in this 
>> context though.
>> 
>>> Or, and this is the far easier thing that can and should be done today, 
>>> just use a struct.
>> 
>> I generally agree with this advice.
>> 
>>> 
  Any label is already at a distance from the name it labels.  Instead of 
 providing a label the important thing is that the semantic of the bound 
 variable be clear at the match site.  Much of the time the label actually 
 reduces clarity at a match site by adding verbosity and very often 
 repetition.  If the bound name clearly communicates the purpose of the 
 associated value a label cannot add any additional clarity, it can only 
 reduce clarity.
>>> 
>>> I disagree.  This would make sense in a world where we didn’t allow 
>>> overloading.  But for the purpose of disambiguation, this kind of logic 
>>> breaks down.  Say we have this construction
>>> 
>>> func bar(_ x : Foo) {
>>>   switch x {
>>>   case let .foo(x, y, z): break
>>>   case let .foo(x, y, z, w): break
>>>   }
>>> }
>>> 
>>> Without the definition of the original enum, could you tell me what each of 
>>> these cases were for, and why they were named so similarly?  Eliding the 
>>> label does not enable clarity, it saves keystrokes and enables ambiguous 
>>> patterns.
>> 
>> As stated above, I strongly dislike the syntax that distributes the `let` as 
>> I find *that* to be unclear.  Let’s rewrite that example:
>> 
>> func bar(_ x : Foo) {
>>   switch x {
>>   case .foo(let x, let y, let z): break
>>   case .foo(let x, let y, let z, let w): break
>>   }
>> }
>> 
>> Now I can see exactly where names are being bound.  I know if a label exists 
>> it matches the name that is bound.  If two distinct 

Re: [swift-evolution] [SE-0155][Discuss] The role of labels in enum case patterns

2017-09-08 Thread Robert Widmann via swift-evolution

> On Sep 8, 2017, at 2:59 PM, Matthew Johnson  wrote:
> 
>> 
>> On Sep 8, 2017, at 2:17 PM, Robert Widmann > > wrote:
>> 
>>> 
>>> On Sep 4, 2017, at 11:35 AM, Matthew Johnson via swift-evolution 
>>> > wrote:
>>> 
>>> 
 On Sep 4, 2017, at 11:47 AM, T.J. Usiyan > wrote:
 
 I wasn't arguing for a strictly parallel syntax. I was arguing against 
 being able to omit labels. I don't view those as strictly tied together. 
 How are they?
>>> 
>>> Like Xiaodi I don’t think it would be productive to rehash the prior 
>>> discussion so I’m going to try to be brief.  
>>> 
>>> In the discussion one idea that arose was to support two labels for 
>>> associated values in a manner similar to parameters.  One would be used 
>>> during construction and the other during matching.  
>>> 
>>> The idea behind this was that when creating a value a case is analagous to 
>>> a factory method and it would be nice to be able provide labels using the 
>>> same naming guidelines we use for external argument labels.  For example, 
>>> if an associated value was an index `at` might be used for clarity at the 
>>> call site.  Labels like this don’t necessarily make as much sense when 
>>> destructuring the value.  The idea of the “internal” label of a case was 
>>> that it would be used when matching and could be elided if the bound name 
>>> was identical.  In the example, `index` might be used.
>> 
>> It’s an interesting idea, but I don’t know of too many cases where I 
>> wouldn’t want the name for destructuring to serve as an API name somehow.  A 
>> function may use labels to aid understanding, flow,  readability, etc. but 
>> an enum case is not necessarily a function-like value, nor does this 
>> proposal want them to be (modulo some internal modeling).
> 
> An enum case is *exactly* analogous to a static factory method or property 
> when it is used to construct values.  It obviously plays a different role in 
> pattern context.
> 
>> 
>>> 
>>> When matching, `let` is interspersed between the label and the name binding.
>> 
>> Good thing this works then
>> 
>> enum Foo {
>>   case foo(x: Int, y: String, z: Float)
>> }
>> 
>> func bar(_ x : Foo) {
>>   switch x {
>>   case let .foo(x: x, y: y, z: z): break
>>   }
>> }
> 
> I consider this syntax to be an anti-pattern.  It can be unclear where a new 
> name is bound and where the value of a pre-existing name is matched.
> 
>> 
>> Even better, John mentioned in the rationale that if the labels ever grow to 
>> be clumsy we can come up with some kind of “ellipses-like” pattern to 
>> indicate we intend to match all the labelled values as they are so named, 
>> etc.  
> 
> It sounds like this would introduce name bindings without the name being 
> explicitly declared.  That works fine where there is a standard pattern such 
> as `oldValue` in a property observer.  I’m not sure I would like it in this 
> context though.
> 
>> Or, and this is the far easier thing that can and should be done today, just 
>> use a struct.
> 
> I generally agree with this advice.
> 
>> 
>>>  Any label is already at a distance from the name it labels.  Instead of 
>>> providing a label the important thing is that the semantic of the bound 
>>> variable be clear at the match site.  Much of the time the label actually 
>>> reduces clarity at a match site by adding verbosity and very often 
>>> repetition.  If the bound name clearly communicates the purpose of the 
>>> associated value a label cannot add any additional clarity, it can only 
>>> reduce clarity.
>> 
>> I disagree.  This would make sense in a world where we didn’t allow 
>> overloading.  But for the purpose of disambiguation, this kind of logic 
>> breaks down.  Say we have this construction
>> 
>> func bar(_ x : Foo) {
>>   switch x {
>>   case let .foo(x, y, z): break
>>   case let .foo(x, y, z, w): break
>>   }
>> }
>> 
>> Without the definition of the original enum, could you tell me what each of 
>> these cases were for, and why they were named so similarly?  Eliding the 
>> label does not enable clarity, it saves keystrokes and enables ambiguous 
>> patterns.
> 
> As stated above, I strongly dislike the syntax that distributes the `let` as 
> I find *that* to be unclear.  Let’s rewrite that example:
> 
> func bar(_ x : Foo) {
>   switch x {
>   case .foo(let x, let y, let z): break
>   case .foo(let x, let y, let z, let w): break
>   }
> }
> 
> Now I can see exactly where names are being bound.  I know if a label exists 
> it matches the name that is bound.  If two distinct cases might be matched I 
> would expect a compiler error.  For example, if Foo was defined as follows 
> the above switch to produce an error on the second pattern but not the first:
> 
> enum Foo {
>   case foo(x: Int, y: String, z: Float)
>   

Re: [swift-evolution] [Pitch] DateComponents{Encoding/Decoding}Strategy in JSON{Encoder/Decoder}

2017-09-08 Thread Itai Ferber via swift-evolution

Hi Pitiphong,

Thanks for taking the time and energy to pitch this, too! If we can find 
a good solution for matching this up with ISO 8601, and we have high 
demand for this feature, I think it will be worth reconsidering again in 
the future.

Thanks for the input!

— Itai

On 8 Sep 2017, at 13:00, Pitiphong Phongpattranont wrote:


Hi Itai,

As I told you in my last email that I’m thinking about the ISO 8601 
case. After thinking about that, having a discussion in the Swift 
Evolution and reading your emails, I think it may not worth to add 
this into Swift Standard Library. I think the use case is not that 
much so it’s not worth the cost of maintenance alone not to mention 
or think about how to implement it properly (if we choose to do and 
support the `iso8601` strategy.


I think I will close this pitch and would like to thank you for 
reviewing and discussing on this.



— Pitiphong P.


On 7 Sep BE 2560, at 01:03, Itai Ferber  wrote:

Hi Pitiphong,

Don’t worry — your original email was clear, and we are on the 
same page about Date{En,De}codingStrategy and 
DateComponents{En,De}codingStrategy being separate things.
To clarify my points, though, there are two main things I want to 
say:


I think there is a mismatch here between your goal of representing 
the components of a date (and what DateComponents can specifically 
hold) and the goal of ISO 8601
I think that there is an inherent problem in parsing DateComponents 
due to ambiguity
I think both of these issues can be solved by reading and writing a 
Date (formatted however you need it to be) instead of DateComponents.


To elaborate:

DateComponents is meant to be a container for an arbitrary subset of 
information about a Date. A Date represents a specific instant in 
time, but DateComponents are effectively meaningless without 
additional context. In the examples that you give, it’s possible to 
represent the concepts at hand with DateComponents, but in order to 
make those components actionable and meaningful, you still need to 
convert them to Dates. Note also that:


It’s entirely possible to create a DateComponents which represents 
a date which does not exist, or a time which does not exist
Any of these concepts can also be represented by a Date instead of 
just components; e.g., an all-day event can be represented by a Date 
that represents the beginning of the day (00:00:00) and a flag that 
indicates that the time of the event can be ignored, or by a start 
Date that represents the start of the day and and end Date that 
represents the end of the day
Unlike DateComponents, ISO 8601 strings have some structure to them. 
They cannot represent just a time zone, for instance, or some 
singular components of a date/time (e.g. a month without a year, a 
day without a month and year, a minute without an hour, a second 
without a minute and hour, etc.). I think this is a relatively large 
conceptual mismatch that is worth considering deeply. There are a lot 
of DateComponents instances which simply cannot be represented by an 
ISO 8601 string


There is also the issue of decoding arbitrary ISO 8601 strings into 
DateComponents. DateComponents, having no structure at all, have no 
specified format they can expect to decode from, and ISO 8601 does 
not always provide that structure. Consider the following example:


ISO 8601 allows for date representations by year, month, and day 
(-MM-DD), among other forms. But it also allows days to be left 
unspecified (-MM), and even months ()
Similarly, it allows for a time representations by hour, minute, and 
second (hh:mm:ss), but also just hour and minute (hh:mm), and just 
hour (hh). Importantly, it allows time separators to be omitted 
(hhmmss, hhmm, hh)
Consider then, attempting to parse the string "2017" without any 
context — what DateComponents should be read out? Intuitively, 2017 
looks like a year (), but it is equally valid to parse as the 
time 20:17 (hhmm). Without knowing the expected format, parsing is 
ambiguous
We cannot promise to parse DateComponents in all cases because there 
are many combinations of strings that are just completely ambiguous.


So, to get at the core of this — if there is a specific format that 
you would like to encode to and from, why not do so with a Date and a 
DateFormatter (or if you need ISO 8601 specifically, 
ISO8601DateFormatter)? With a formatter, the format is unambiguous 
because you explicitly provide it, and there is nothing the date 
can’t represent that DateComponents can. You can always parse the 
date and pull out only those components that you care about. You also 
mention interoperability with an external JSON source — how is that 
source producing a string/parsing one back? [What I’m getting at 
here is: what is the value of adding a new, potentially risky 
strategy over existing methods that might work just as well, or 
better?]


And lastly, if .iso8601 is not necessarily a good fit for this 

Re: [swift-evolution] [Pitch] Synthesized static enum property to iterate over cases

2017-09-08 Thread Matthew Johnson via swift-evolution

> On Sep 8, 2017, at 12:05 PM, Tony Allevato  wrote:
> 
> 
> 
> On Fri, Sep 8, 2017 at 9:44 AM Matthew Johnson  > wrote:
>> On Sep 8, 2017, at 11:32 AM, Tony Allevato > > wrote:
>> 
>> 
>> 
>> On Fri, Sep 8, 2017 at 8:35 AM Matthew Johnson > > wrote:
>>> On Sep 8, 2017, at 9:53 AM, Tony Allevato via swift-evolution 
>>> > wrote:
>>> 
>>> Thanks for bringing this up, Logan! It's something I've been thinking about 
>>> a lot lately after a conversation with some colleagues outside of this 
>>> community. Some of my thoughts:
>>> 
>>> AFAIK, there are two major use cases here: (1) you need the whole 
>>> collection of cases, like in your example, and (2) you just need the number 
>>> of cases. The latter seems to occur somewhat commonly when people want to 
>>> use an enum to define the sections of, say, a UITableView. They just return 
>>> the count from numberOfSections(in:) and then switch over the cases in 
>>> their cell-providing methods.
>>> 
>>> Because of #2, it would be nice to avoid instantiating the collection 
>>> eagerly. (Also because of examples like Jonathan's, where the enum is 
>>> large.) If all the user is ever really doing is iterating over them, 
>>> there's no need to keep the entire collection in memory. This leads us to 
>>> look at Sequence; we could use something like AnySequence to keep the 
>>> current case as our state and a transition function to advance to the next 
>>> one. If a user needs to instantiate the full array from that sequence they 
>>> can do so, but they have to do it explicitly.
>>> 
>>> The catch is that Sequence only provides `underestimatedCount`, rather than 
>>> `count`. Calling the former would be an awkward API (why is it 
>>> underestimated? we know how many cases there are). I suppose we could 
>>> create a concrete wrapper for Sequence (PrecountedSequence?) that provides 
>>> a `count` property to make that cleaner, and then have 
>>> `underestimatedCount` return the same thing if users passed this thing into 
>>> a generic operation constrained over Sequence. (The standard library 
>>> already has support wrappers like EnumeratedSequence, so maybe this is 
>>> appropriate.)
>>> 
>>> Another question that would need to be answered is, how should the cases be 
>>> ordered? Declaration order seems obvious and straightforward, but if you 
>>> have a raw-value enum (say, integers), you could have the declaration order 
>>> and the numeric order differ. Maybe that's not a problem. Tying the 
>>> iteration order to declaration order also means that the behavior of a 
>>> program could change simply by reördering the cases. Maybe that's not a big 
>>> problem either, but it's something to call out.
>>> 
>>> If I were designing this, I'd start with the following approach. First, add 
>>> a new protocol to the standard library:
>>> 
>>> ```
>>> public protocol ValueEnumerable {
>>>   associatedtype AllValuesSequence: Sequence where 
>>> AllValuesSequence.Iterator.Element == Self
>>> 
>>>   static var allValues: AllValuesSequence { get }
>>> }
>>> ```
>>> 
>>> Then, for enums that declare conformance to that protocol, synthesize the 
>>> body of `allValues` to return an appropriate sequence. If we imagine a 
>>> model like AnySequence, then the "state" can be the current case, and the 
>>> transition function can be a switch/case that returns it and advances to 
>>> the next one (finally returning nil).
>>> 
>>> There's an opportunity for optimization that may or may not be worth it: if 
>>> the enum is RawRepresentable with RawValue == Int, AND all the raw values 
>>> are in a contiguous range, AND declaration order is numerical order 
>>> (assuming we kept that constraint), then the synthesized state machine can 
>>> just be a simple integer incrementation and call to `init?(rawValue:)`. 
>>> When all the cases have been generated, that will return nil on its own.
>>> 
>>> So that covers enums without associated values. What about those with 
>>> associated values? I would argue that the "number of cases" isn't something 
>>> that's very useful here—if we consider that enum cases are really factory 
>>> functions for concrete values of the type, then we shouldn't think about 
>>> "what are all the cases of this enum" but "what are all the values of this 
>>> type". (For enums without associated values, those are synonymous.)
>>> 
>>> An enum with associated values can potentially have an infinite number of 
>>> values. Here's one:
>>> 
>>> ```
>>> enum BinaryTree {
>>>   case subtree(left: BinaryTree, right: BinaryTree)
>>>   case leaf
>>>   case empty
>>> }
>>> ```
>>> 
>>> Even without introducing an Element type in the leaf nodes, there are a 
>>> countably infinite number of binary trees. So first 

Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Jacob Williams via swift-evolution
Huge +1 to stdlib (or even Foundation) random number generator. I’ve worked 
with random numbers on both Linux and macOS/iOS and have found myself annoyed 
with the lack of easy random number generators. It seems that implementing a 
pure Swift RNG would be an obviously good addition to the stdlib.

I don’t think that it would be possible to make this work for floating point 
numbers. Although admittedly, I know very little about Floating Point numbers. 
I think this is still a worthwhile addition to Swift even for just Integers 
alone.

> On Sep 8, 2017, at 1:30 PM, Ben Cohen via swift-evolution 
>  wrote:
> 
> Hi Alejandro,
> 
> I’m really happy to see someone pick this up. We had suggested some kind of 
> random support could be a goal for addition to the standard library in Swift 
> 4 phase 2 but didn’t manage it, so I definitely think a good proposal would 
> be given consideration for Swift 5.
> 
> Regarding the implementation – I would suggest exploring something along the 
> lines of an extension on RandomAccessCollection that adds a property for a 
> random element, rather than a pair of free functions. This would have a 
> number of benefits:
> 
>  - a very common use case is picking a random entry from a collection, which 
> this would do automatically
>  - it gives you a very natural way of expressing a ranged random number i.e. 
> (0..<10).randomElement (not necessarily recommending that name btw, it’s one 
> of various possibilities)
>  - since both kinds of countable ranges are collections, it sidesteps that 
> issue :)
>  - it allows for multiple different integers without the need for casting 
> i.e. in the above, if type context meant the result was a UInt16, that’s what 
> it would be
> 
> The one downside is that you’d have to write (0.. justification for a static property on one of the Integer protocols as 
> shorthand for that.
> 
> The tricky part (in addition to the cross-platform aspect) is ensuring 
> correct distribution across the possible distances. But since this is 
> something that people might easily get wrong, that reinforces the idea of 
> this being something that’s easy to use correctly in the std lib.
> 
> I’d also suggest proposing a shuffle implementation for 
> RandomAccessCollection+MutableCollection at the same time (probably as a 
> separate but linked proposal), since this is also something that is often 
> requested, easy to get wrong, and needs a cross-platform source of random 
> numbers.
> 
> Regards,
> Ben
> 
> 
>> On Sep 8, 2017, at 10:34 AM, Alejandro Alonso via swift-evolution 
>> > wrote:
>> 
>> Range support is something that came up, and I think it’s a great idea as 
>> well. My question now is do we support both `CountableRange` and 
>> `CountableClosedRange`?
>> 
>> On Sep 8, 2017, 12:08 PM -0500, Shawn Erickson > >, wrote:
>>> It would be nice to leverage range support instead of a start and end value 
>>> IMHO.
>>> On Fri, Sep 8, 2017 at 9:52 AM Alejandro Alonso via swift-evolution 
>>> > 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
>>> 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
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org

Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Matthew Johnson via swift-evolution

> On Sep 8, 2017, at 2:30 PM, Ben Cohen via swift-evolution 
>  wrote:
> 
> Hi Alejandro,
> 
> I’m really happy to see someone pick this up. We had suggested some kind of 
> random support could be a goal for addition to the standard library in Swift 
> 4 phase 2 but didn’t manage it, so I definitely think a good proposal would 
> be given consideration for Swift 5.
> 
> Regarding the implementation – I would suggest exploring something along the 
> lines of an extension on RandomAccessCollection that adds a property for a 
> random element, rather than a pair of free functions. This would have a 
> number of benefits:
> 
>  - a very common use case is picking a random entry from a collection, which 
> this would do automatically
>  - it gives you a very natural way of expressing a ranged random number i.e. 
> (0..<10).randomElement (not necessarily recommending that name btw, it’s one 
> of various possibilities)
>  - since both kinds of countable ranges are collections, it sidesteps that 
> issue :)
>  - it allows for multiple different integers without the need for casting 
> i.e. in the above, if type context meant the result was a UInt16, that’s what 
> it would be
> 
> The one downside is that you’d have to write (0.. justification for a static property on one of the Integer protocols as 
> shorthand for that.
> 
> The tricky part (in addition to the cross-platform aspect) is ensuring 
> correct distribution across the possible distances. But since this is 
> something that people might easily get wrong, that reinforces the idea of 
> this being something that’s easy to use correctly in the std lib.
> 
> I’d also suggest proposing a shuffle implementation for 
> RandomAccessCollection+MutableCollection at the same time (probably as a 
> separate but linked proposal), since this is also something that is often 
> requested, easy to get wrong, and needs a cross-platform source of random 
> numbers.

How would this design address the relatively common use case of wanting a 
random floating point number in the range `0…1` or `0..<1`?  Floating point 
ranges are not countable.

> 
> Regards,
> Ben
> 
> 
>> On Sep 8, 2017, at 10:34 AM, Alejandro Alonso via swift-evolution 
>> > wrote:
>> 
>> Range support is something that came up, and I think it’s a great idea as 
>> well. My question now is do we support both `CountableRange` and 
>> `CountableClosedRange`?
>> 
>> On Sep 8, 2017, 12:08 PM -0500, Shawn Erickson > >, wrote:
>>> It would be nice to leverage range support instead of a start and end value 
>>> IMHO.
>>> On Fri, Sep 8, 2017 at 9:52 AM Alejandro Alonso via swift-evolution 
>>> > 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
>>> 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
> 
> ___
> swift-evolution mailing list
> 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


Re: [swift-evolution] [Proposal] Explicit Synthetic Behaviour

2017-09-08 Thread Itai Ferber via swift-evolution


> On Sep 8, 2017, at 12:46 AM, Haravikk via swift-evolution 
>  wrote:
> 
> 
>> On 7 Sep 2017, at 22:02, Itai Ferber > > wrote:
>> 
>> protocol Fooable : Equatable { // Equatable is just a simple example
>> var myFoo: Int { get }
>> }
>> 
>> extension Fooable {
>> static func ==(_ lhs: Self, _ rhs: Self) -> Bool {
>> return lhs.myFoo == rhs.myFoo
>> }
>> }
>> 
>> struct X : Fooable {
>> let myFoo: Int
>> let myName: String
>> // Whoops, forgot to give an implementation of ==
>> }
>> 
>> print(X(myFoo: 42, myName: "Alice") == X(myFoo: 42, myName: "Bob")) // true
>> This property is necessary, but not sufficient to provide a correct 
>> implementation. A default implementation might be able to assume something 
>> about the types that it defines, but it does not necessarily know enough.
> 
> Sorry but that's a bit of a contrived example; in this case the protocol 
> should not implement the equality operator if more information may be 
> required to define equality. It should only be implemented if the protocol is 
> absolutely clear that .myFoo is the only part of a Fooable that can or should 
> be compared as equatable, e.g- if a Fooable is a database record and .myFoo 
> is a primary key, the data could differ but it would still be a reference to 
> the same record.
> 
> To be clear, I'm not arguing that someone can't create a regular default 
> implementation that also makes flawed assumptions, but that 
> synthesised/reflective implementations by their very nature have to, as they 
> cannot under every circumstance guarantee correctness when using parts of a 
> concrete type that they know nothing about.
You can’t argue this both ways:
If you’re arguing this on principle, that in order for synthesized 
implementations to be correct, they must be able to — under every circumstance 
— guarantee correctness, then you have to apply the same reasoning to default 
protocol implementations. Given a default protocol implementation, it is 
possible to come up with a (no matter how contrived) case where the default 
implementation is wrong. Since you’re arguing this on principle, you cannot 
reject contrived examples.
If you are arguing this in practice, then you’re going to have to back up your 
argument with evidence that synthesized examples are more often wrong than 
default implementations. You can’t declare that synthesized implementations are 
by nature incorrect but allow default implementations to slide because in 
practice, many implementations are allowable. There’s a reason why synthesis 
passed code review and was accepted: in the majority of cases, synthesis was 
deemed to be beneficial, and would provide correct behavior. If you are 
willing to say that yes, sometimes default implementations are wrong but 
overall they’re correct, you’re going to have to provide hard evidence to back 
up the opposite case for synthesized implementations. You stated in a previous 
email that "A synthesised/reflective implementation however may return a result 
that is simply incorrect, because it is based on assumptions made by the 
protocol developer, with no input from the developer of the concrete type. In 
this case the developer must override it in to provide correct behaviour." — if 
you can back this up with evidence (say, taking a survey of a large number of 
model types and see if in the majority of cases synthesized implementation 
would be incorrect) to provide a compelling argument, then this is something 
that we should in that case reconsider.

>>> Reflective/synthesised default implementations must by their very nature 
>>> make assumptions about a concrete type that are not cannot be guaranteed to 
>>> be correct. The properties and methods they may end up interacting withmay 
>>> have nothing at all to do with the protocol. Equatable remains by far the 
>>> simplest example; just because a developer has used equatable properties 
>>> does not guarantee that all of them should be compared during a check for 
>>> equality.
>> In the same way that you might consider synthesized conformances to 
>> overreach into a type and touch things which are not related to a protocol, 
>> default implementations can be considered underreach in that they don’t know 
>> anything about properties which are necessary for providing a correct 
>> implementation.
> 
> If more information is necessary to provide a correct implementation, then a 
> default implementation shouldn't be provided. This is what unimplemented 
> properties and methods are for; either getting the developer to provide the 
> missing information, or getting them to implement the correct behaviour.
I agree, but you can’t selectively argue this.

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


Re: [swift-evolution] [SE-0155][Discuss] The role of labels in enum case patterns

2017-09-08 Thread Matthew Johnson via swift-evolution

> On Sep 8, 2017, at 2:17 PM, Robert Widmann  wrote:
> 
>> 
>> On Sep 4, 2017, at 11:35 AM, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>> 
>>> On Sep 4, 2017, at 11:47 AM, T.J. Usiyan >> > wrote:
>>> 
>>> I wasn't arguing for a strictly parallel syntax. I was arguing against 
>>> being able to omit labels. I don't view those as strictly tied together. 
>>> How are they?
>> 
>> Like Xiaodi I don’t think it would be productive to rehash the prior 
>> discussion so I’m going to try to be brief.  
>> 
>> In the discussion one idea that arose was to support two labels for 
>> associated values in a manner similar to parameters.  One would be used 
>> during construction and the other during matching.  
>> 
>> The idea behind this was that when creating a value a case is analagous to a 
>> factory method and it would be nice to be able provide labels using the same 
>> naming guidelines we use for external argument labels.  For example, if an 
>> associated value was an index `at` might be used for clarity at the call 
>> site.  Labels like this don’t necessarily make as much sense when 
>> destructuring the value.  The idea of the “internal” label of a case was 
>> that it would be used when matching and could be elided if the bound name 
>> was identical.  In the example, `index` might be used.
> 
> It’s an interesting idea, but I don’t know of too many cases where I wouldn’t 
> want the name for destructuring to serve as an API name somehow.  A function 
> may use labels to aid understanding, flow,  readability, etc. but an enum 
> case is not necessarily a function-like value, nor does this proposal want 
> them to be (modulo some internal modeling).

An enum case is *exactly* analogous to a static factory method or property when 
it is used to construct values.  It obviously plays a different role in pattern 
context.

> 
>> 
>> When matching, `let` is interspersed between the label and the name binding.
> 
> Good thing this works then
> 
> enum Foo {
>   case foo(x: Int, y: String, z: Float)
> }
> 
> func bar(_ x : Foo) {
>   switch x {
>   case let .foo(x: x, y: y, z: z): break
>   }
> }

I consider this syntax to be an anti-pattern.  It can be unclear where a new 
name is bound and where the value of a pre-existing name is matched.

> 
> Even better, John mentioned in the rationale that if the labels ever grow to 
> be clumsy we can come up with some kind of “ellipses-like” pattern to 
> indicate we intend to match all the labelled values as they are so named, 
> etc.  

It sounds like this would introduce name bindings without the name being 
explicitly declared.  That works fine where there is a standard pattern such as 
`oldValue` in a property observer.  I’m not sure I would like it in this 
context though.

> Or, and this is the far easier thing that can and should be done today, just 
> use a struct.

I generally agree with this advice.

> 
>>  Any label is already at a distance from the name it labels.  Instead of 
>> providing a label the important thing is that the semantic of the bound 
>> variable be clear at the match site.  Much of the time the label actually 
>> reduces clarity at a match site by adding verbosity and very often 
>> repetition.  If the bound name clearly communicates the purpose of the 
>> associated value a label cannot add any additional clarity, it can only 
>> reduce clarity.
> 
> I disagree.  This would make sense in a world where we didn’t allow 
> overloading.  But for the purpose of disambiguation, this kind of logic 
> breaks down.  Say we have this construction
> 
> func bar(_ x : Foo) {
>   switch x {
>   case let .foo(x, y, z): break
>   case let .foo(x, y, z, w): break
>   }
> }
> 
> Without the definition of the original enum, could you tell me what each of 
> these cases were for, and why they were named so similarly?  Eliding the 
> label does not enable clarity, it saves keystrokes and enables ambiguous 
> patterns.

As stated above, I strongly dislike the syntax that distributes the `let` as I 
find *that* to be unclear.  Let’s rewrite that example:

func bar(_ x : Foo) {
  switch x {
  case .foo(let x, let y, let z): break
  case .foo(let x, let y, let z, let w): break
  }
}

Now I can see exactly where names are being bound.  I know if a label exists it 
matches the name that is bound.  If two distinct cases might be matched I would 
expect a compiler error.  For example, if Foo was defined as follows the above 
switch to produce an error on the second pattern but not the first:

enum Foo {
  case foo(x: Int, y: String, z: Float)
  case foo(x: Int, y: String, z: Float, s: String)
  case foo(x: Int, y: String, z: Float, w: Double)
}

If the proposal had been accepted without the modification I would not find the 
above switch ambiguous in behavior although I admit that it carries more 
potential for mistake 

Re: [swift-evolution] [Pitch] Synthesized static enum property to iterate over cases

2017-09-08 Thread Logan Shire via swift-evolution
Hey folks!

Thanks for all the great feedback and discussion.
I really like Tony's suggestion of the opt-in ValueEnumerable protocol.
However, I think Kevin is right that it should be a simple array.
If we wanted to get fancy, we could implement a custom integer indexed
collection that indexed into the type's memory to provide a random
access collection of cases without allocating any new memory.
This does seem more complex than just synthesizing the array as
an opt-in, though.

I also agree that it should be in declaration order. If the user wants to
have integer enums in ascending order they can write an extension
that sorts allCases. And I think this should absolutely not work for
associated values. You can implement the protocol if you want,
but you don't get anything synthesized for you.

Best,
Logan

On Fri, Sep 8, 2017 at 11:49 AM Kevin Nattinger via swift-evolution <
swift-evolution@swift.org> wrote:

> I've been waiting for this for years. Literally since Swift was announced.
> IMO it's one of several major gaps in the language.
>
> Some thoughts:
> - It should be a simple array.
> - By far the most simple solution, and the one I (and, I'd guess, others)
> would expect.
> - Every time I've needed the count, I need the actual values either within
> the same method or within the same run loop (e.g. table view).
> - In my experience, direct indexing into the values array is more common
> than iterating over it.
> - Rarely more than a few cases.
> - Even an enum with a lot of cases, the actual number is trivial compared
> to the program's memory usage.
> - No compiler magic beyond spitting out the static array. How do you
> propose to generate on-demand a sequence of values without compiler magic
> and without the values being stored somewhere?
> - It should always be in declaration order. Period.
> - Reordering only in the case of Int raw values (especially only when 0-N
> are all covered) is unintuitive at best, and I expect rarely what the dev
> would want.
> - Should only work on enums without associated values. Enumerating on
> associated values is just begging for trouble.
> - (Infinite) recursion, as you pointed out.
> - It seems more intuitive to me to have enumerated cases grouped, but what
> if there are cases with and without ATs?
>
> [...]
>>
>> Great points! I was only considering the table view/section case where
>> the enum had raw values 0..> possible that someone could just define `enum Section { case header,
>> content, footer }` and then want to turn an IndexPath value into the
>> appropriate Section.
>>
>>
>> On the other hand, though, isn't that what raw value enums are for? If
>> the user needs to do what you're saying—map specific integers to enum
>> values—shouldn't they do so by giving those cases raw values and calling
>> init?(rawValue:), not by indexing into a collection? Especially since they
>> can already do that today, and the only thing they're missing is being able
>> to retrieve the count, which a "PrecountedSequence" mentioned above, or
>> something like it, could also provide.
>>
>> I... guess one could do that? Seems undesirable to me. What if I have
> them explicitly numbered, and delete one? Oops, now the whole thing is off
> and I have to go fix all the numbers. Besides, what if the dev wants to use
> it as a different raw representable? (`enum Title: String { ... }`)?
>
> First, I’m making observations about what people are doing, not what they
>> could do.
>>
>> Second, the raw value may not correspond to 0-based indices.  It might
>> not even be an Int.  There is no reason to couple this common use case of
>> `allValues` to `Int` raw values with 0-based indices.
>>
> +1000. There is absolutely no reason to join these, or special-case 0-N
> int raw representables.
>
> Do we know of any examples where a user is both (1) defining an enum with
> integer raw values that are noncontiguous or non-zero-based and (2) need
> declaration-ordinal-based indexing into those cases for other reasons, like
> a table/collection view? I can't think of why someone would do that, but
> I'm happy to consider something that I'm missing.
>
> Some underlying meaning? E.g. not a table view, but values or identifiers
> for some sort of low-level protocol.
>
> Third, `init(rawValue:)` is a failable initializer and would require a
>> force unwrap.  If the raw values *are* 0-based integers this is similar to
>> the collection bounds check that would be necessary, but it moves it into
>> user code.  People don’t like writing force unwraps.
>>
>
> Yeah, this is a really good point that I wasn't fully considering. If
> other invariants in the application hold—such as table view cell functions
> never receiving a section index outside 0.. forces users to address a situation that will never actually occur unless
> UIKit is fundamentally broken.
>
> Or the user makes a mistake numbering cases, or forgets to update
> 

Re: [swift-evolution] [Pitch] DateComponents{Encoding/Decoding}Strategy in JSON{Encoder/Decoder}

2017-09-08 Thread Pitiphong Phongpattranont via swift-evolution
Hi Itai,

As I told you in my last email that I’m thinking about the ISO 8601 case. After 
thinking about that, having a discussion in the Swift Evolution and reading 
your emails, I think it may not worth to add this into Swift Standard Library. 
I think the use case is not that much so it’s not worth the cost of maintenance 
alone not to mention or think about how to implement it properly (if we choose 
to do and support the `iso8601` strategy.

I think I will close this pitch and would like to thank you for reviewing and 
discussing on this.


— Pitiphong P.

> On 7 Sep BE 2560, at 01:03, Itai Ferber  wrote:
> 
> Hi Pitiphong,
> 
> Don’t worry — your original email was clear, and we are on the same page 
> about Date{En,De}codingStrategy and DateComponents{En,De}codingStrategy being 
> separate things.
> To clarify my points, though, there are two main things I want to say:
> 
> I think there is a mismatch here between your goal of representing the 
> components of a date (and what DateComponents can specifically hold) and the 
> goal of ISO 8601
> I think that there is an inherent problem in parsing DateComponents due to 
> ambiguity
> I think both of these issues can be solved by reading and writing a Date 
> (formatted however you need it to be) instead of DateComponents.
> 
> To elaborate:
> 
> DateComponents is meant to be a container for an arbitrary subset of 
> information about a Date. A Date represents a specific instant in time, but 
> DateComponents are effectively meaningless without additional context. In the 
> examples that you give, it’s possible to represent the concepts at hand with 
> DateComponents, but in order to make those components actionable and 
> meaningful, you still need to convert them to Dates. Note also that:
> 
> It’s entirely possible to create a DateComponents which represents a date 
> which does not exist, or a time which does not exist
> Any of these concepts can also be represented by a Date instead of just 
> components; e.g., an all-day event can be represented by a Date that 
> represents the beginning of the day (00:00:00) and a flag that indicates that 
> the time of the event can be ignored, or by a start Date that represents the 
> start of the day and and end Date that represents the end of the day
> Unlike DateComponents, ISO 8601 strings have some structure to them. They 
> cannot represent just a time zone, for instance, or some singular components 
> of a date/time (e.g. a month without a year, a day without a month and year, 
> a minute without an hour, a second without a minute and hour, etc.). I think 
> this is a relatively large conceptual mismatch that is worth considering 
> deeply. There are a lot of DateComponents instances which simply cannot be 
> represented by an ISO 8601 string
> 
> There is also the issue of decoding arbitrary ISO 8601 strings into 
> DateComponents. DateComponents, having no structure at all, have no specified 
> format they can expect to decode from, and ISO 8601 does not always provide 
> that structure. Consider the following example:
> 
> ISO 8601 allows for date representations by year, month, and day 
> (-MM-DD), among other forms. But it also allows days to be left 
> unspecified (-MM), and even months ()
> Similarly, it allows for a time representations by hour, minute, and second 
> (hh:mm:ss), but also just hour and minute (hh:mm), and just hour (hh). 
> Importantly, it allows time separators to be omitted (hhmmss, hhmm, hh)
> Consider then, attempting to parse the string "2017" without any context — 
> what DateComponents should be read out? Intuitively, 2017 looks like a year 
> (), but it is equally valid to parse as the time 20:17 (hhmm). Without 
> knowing the expected format, parsing is ambiguous
> We cannot promise to parse DateComponents in all cases because there are many 
> combinations of strings that are just completely ambiguous.
> 
> So, to get at the core of this — if there is a specific format that you would 
> like to encode to and from, why not do so with a Date and a DateFormatter (or 
> if you need ISO 8601 specifically, ISO8601DateFormatter)? With a formatter, 
> the format is unambiguous because you explicitly provide it, and there is 
> nothing the date can’t represent that DateComponents can. You can always 
> parse the date and pull out only those components that you care about. You 
> also mention interoperability with an external JSON source — how is that 
> source producing a string/parsing one back? [What I’m getting at here is: 
> what is the value of adding a new, potentially risky strategy over existing 
> methods that might work just as well, or better?]
> 
> And lastly, if .iso8601 is not necessarily a good fit for this strategy, what 
> separates .custom from just overriding encode(to:) and init(from:) and 
> writing the components out in the format that you need?
> 
> I think answers to these questions can help us push this forward. :)
> 

Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Ben Cohen via swift-evolution
Hi Alejandro,

I’m really happy to see someone pick this up. We had suggested some kind of 
random support could be a goal for addition to the standard library in Swift 4 
phase 2 but didn’t manage it, so I definitely think a good proposal would be 
given consideration for Swift 5.

Regarding the implementation – I would suggest exploring something along the 
lines of an extension on RandomAccessCollection that adds a property for a 
random element, rather than a pair of free functions. This would have a number 
of benefits:

 - a very common use case is picking a random entry from a collection, which 
this would do automatically
 - it gives you a very natural way of expressing a ranged random number i.e. 
(0..<10).randomElement (not necessarily recommending that name btw, it’s one of 
various possibilities)
 - since both kinds of countable ranges are collections, it sidesteps that 
issue :)
 - it allows for multiple different integers without the need for casting i.e. 
in the above, if type context meant the result was a UInt16, that’s what it 
would be

The one downside is that you’d have to write (0.. On Sep 8, 2017, at 10:34 AM, Alejandro Alonso via swift-evolution 
>  wrote:
> 
> Range support is something that came up, and I think it’s a great idea as 
> well. My question now is do we support both `CountableRange` and 
> `CountableClosedRange`?
> 
> On Sep 8, 2017, 12:08 PM -0500, Shawn Erickson , wrote:
>> It would be nice to leverage range support instead of a start and end value 
>> IMHO.
>> On Fri, Sep 8, 2017 at 9:52 AM Alejandro Alonso via swift-evolution 
>> > 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
>> 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

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


Re: [swift-evolution] [SE-0155][Discuss] The role of labels in enum case patterns

2017-09-08 Thread Robert Widmann via swift-evolution

> On Sep 4, 2017, at 11:35 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
>> On Sep 4, 2017, at 11:47 AM, T.J. Usiyan > > wrote:
>> 
>> I wasn't arguing for a strictly parallel syntax. I was arguing against being 
>> able to omit labels. I don't view those as strictly tied together. How are 
>> they?
> 
> Like Xiaodi I don’t think it would be productive to rehash the prior 
> discussion so I’m going to try to be brief.  
> 
> In the discussion one idea that arose was to support two labels for 
> associated values in a manner similar to parameters.  One would be used 
> during construction and the other during matching.  
> 
> The idea behind this was that when creating a value a case is analagous to a 
> factory method and it would be nice to be able provide labels using the same 
> naming guidelines we use for external argument labels.  For example, if an 
> associated value was an index `at` might be used for clarity at the call 
> site.  Labels like this don’t necessarily make as much sense when 
> destructuring the value.  The idea of the “internal” label of a case was that 
> it would be used when matching and could be elided if the bound name was 
> identical.  In the example, `index` might be used.

It’s an interesting idea, but I don’t know of too many cases where I wouldn’t 
want the name for destructuring to serve as an API name somehow.  A function 
may use labels to aid understanding, flow,  readability, etc. but an enum case 
is not necessarily a function-like value, nor does this proposal want them to 
be (modulo some internal modeling).

> 
> When matching, `let` is interspersed between the label and the name binding.

Good thing this works then

enum Foo {
  case foo(x: Int, y: String, z: Float)
}

func bar(_ x : Foo) {
  switch x {
  case let .foo(x: x, y: y, z: z): break
  }
}

Even better, John mentioned in the rationale that if the labels ever grow to be 
clumsy we can come up with some kind of “ellipses-like” pattern to indicate we 
intend to match all the labelled values as they are so named, etc.  Or, and 
this is the far easier thing that can and should be done today, just use a 
struct.

>  Any label is already at a distance from the name it labels.  Instead of 
> providing a label the important thing is that the semantic of the bound 
> variable be clear at the match site.  Much of the time the label actually 
> reduces clarity at a match site by adding verbosity and very often 
> repetition.  If the bound name clearly communicates the purpose of the 
> associated value a label cannot add any additional clarity, it can only 
> reduce clarity.

I disagree.  This would make sense in a world where we didn’t allow 
overloading.  But for the purpose of disambiguation, this kind of logic breaks 
down.  Say we have this construction

func bar(_ x : Foo) {
  switch x {
  case let .foo(x, y, z): break
  case let .foo(x, y, z, w): break
  }
}

Without the definition of the original enum, could you tell me what each of 
these cases were for, and why they were named so similarly?  Eliding the label 
does not enable clarity, it saves keystrokes and enables ambiguous patterns.

> 
> The proposal acknowledges most of this by allowing us to elide labels when 
> the bound name matches the label. 

That part of the proposal was not accepted which is part of why I’m bringing 
this up at all.  Besides, it wouldn’t have worked quite the way the authors 
intended.

enum Foo {
  case foo(x: Int, x: String)
}

func bar(_ x : Foo) {
  switch x {
  // We wanted to avoid labels, but instead we would be required to redeclare
  // 'x' in this pattern which forces the use of labels to allow a different 
bound name.
  case let .foo(x, x): break
 }
}  

~Robert Widmann

> 
>> 
>> On Mon, Sep 4, 2017 at 12:38 PM, Matthew Johnson > > wrote:
>> 
>>> On Sep 4, 2017, at 10:52 AM, T.J. Usiyan via swift-evolution 
>>> > wrote:
>>> 
>>> While re-litigating has it's issues, I am for simplifying the rule and 
>>> always requiring the labels if they exist. This is similar to the change 
>>> around external labels. Yes, it is slightly less convenient, but it removes 
>>> a difficult to motivate caveat for beginners.
>> 
>> I disagree.  Creating a value and destructuring it are two very different 
>> operations and I believe it is a mistake to require them to have parallel 
>> syntax.  
>> 
>> Imagine a future enhancement to the language that supports destructuring a 
>> struct.  A struct might not have a strictly memberwise initializer.  It 
>> might not even be possible to reconstruct initializer arguments for the sake 
>> of parallel destructuring syntax.  There might even be more than one 
>> projection that is reasonable to use when destructuring the value in a 
>> pattern (such as cartesian and polar 

Re: [swift-evolution] [SE-0155][Discuss] The role of labels in enum case patterns

2017-09-08 Thread Robert Widmann via swift-evolution

> On Sep 4, 2017, at 4:05 PM, Christopher Kornher via swift-evolution 
>  wrote:
> 
> Apologies for rehashing this, but we seem to be going down that path… I am in 
> the minority on this issue and have held my opinions because I thought that 
> they would have served as simply a distraction and I was extremely busy at 
> the time. That may have been a mistake on my part, because raising these 
> issues now is after the fact.
> 
> I am airing them now for two reasons:
> 1) To ensure that at least the agreed upon compromise is implemented.
> 2) To hopefully improve the evolution process, and help ensure that similar 
> proposals are given the scrutiny that they deserve.
> 
> I have noticed a pattern in software and other projects over the years. The 
> most catastrophic failures and expensive rework has been due to flawed or at 
> least incomplete basic assumptions. New postulates / basic assumptions should 
> be subjected to rigorous scrutiny. I don’t think that they were in this case.
> 
> I am speaking up now because there is a proposal out there to follow what I 
> consider to be a flawed basic assumption to its logical conclusion, which 
> seems quite reasonable, if you accept the basic assumption, which I don’t, of 
> course. 
> 
> Please don’t take this as a personal attack on those on the other side. This 
> is a philosophical disagreement with no “right” and “wrong” answer. I don’t 
> believe that this proposal is terrible. In fact, the agreed-upon compromise 
> does improve the construction and matching of enum values and leaves only 
> edge cases that I hope to address in a future proposal — specifically 
> matching is made more difficult in some cases of name overloading. 
> 
> The history of the process as I saw it:
>   There was a widely perceived problem with enums involving what could be 
> described as “legacy destructuring” which could lead to confusing code and 
> hard to discover transposition errors.
> 
>   A solution was proposed that was based upon an overarching premise: 
> that enums should be modeled as much as possible after function calls to 
> simplify the language. This led to the original proposal always requiring 
> labels (as function calls do, and closures don’t, but that is a discussion 
> for another time).
> 
> I believe that idea of using function calls as the primary model for enums is 
> flawed at its core. The problem is that enums and function calls only 
> resemble each other in Swift because some enums can have associated values. 

If the idea of modeling them as a tag and a tuple were OK, this proposal would 
not exist in the first place - or would be dramatically reduced in scope to 
just redoing pattern matching.  We are remodeling them as function-like 
precisely because the old scheme was causing headaches.  I feel it is 
reductionistic to say it is "only the case” that this is true given these 
circumstances.

> 
> The purpose of enums is to be matched. Enums that are never matched in some 
> way have no purpose. Function calls must always be “matched” (resolved) 
> unambiguously so that proper code can be executed. No such requirement exists 
> for enums. In fact the language includes rich functionality for matching 
> multiple cases and values with a single “case” (predicate). This is not a 
> flaw, it improves the expressive power of the language by allowing complex 
> matching logic to be expressed tersely and clearly.
> 

What complex matching (did you mean Expressive?) logic?  That you can express 
pattern matches just by matching by base name then a tuple pattern of proper 
cardinality with disjointed labels is far more complex and prone to actual 
ambiguities (the rationale and proposal both use some form of the phase “when a 
pattern is unambiguous”).  What this means in practice is that the scheme laid 
out in the proposal is prone to ambiguity by construction.  This does not 
enable expressive pattern matches, this enables users to save typing while 
simultaneously increasing the mental overhead of reading any switch statement.  
Under this proposal it is now impossible to tell at a glance which pattern over 
an Enum with overloaded base names is being matched unless you have the labels 
present.

> So, since the purpose of enums is to be matched, any modification to this 
> accepted proposal that makes that more difficult or cluttered should be 
> rejected.

I agree with the sentiment that we don’t want to increase entropy, but I 
disagree with the logic underpinning it.  You save a few keystrokes with this 
mentality.  You don’t gain anything in return.

~Robert Widmann

> 
> 
>> On Sep 4, 2017, at 9:52 AM, T.J. Usiyan via swift-evolution 
>> > wrote:
>> 
>> While re-litigating has it's issues, I am for simplifying the rule and 
>> always requiring the labels if they exist. This is similar to the change 
>> around external labels. Yes, it is 

Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Stephen Canon via swift-evolution
Quick thoughts:

1. A stdlib-level random number facility should default to a host-provided 
CSPRNG as the generator. Anything less is really not justifiable. The 
throughput of modern HW-backed CSPRNGs exceeds that of all but the fastest 
PRNGs, anyway.

2. MT is not a CSPRNG.

– Steve

> On Sep 8, 2017, at 1:31 PM, Kevin Nattinger via swift-evolution 
>  wrote:
> 
> IMO, we should have a `Random` or `RandomGenerator` interface and the stdlib 
> can provide a `SystemRandom` that wraps arc4*/random(), and maybe a 
> cryptographically secure one too (MT19937?).
> 
> protocol RandomGenerator {
> func uniform() -> Int
> func uniform() -> Double
> func uniformBytes(count: Int) -> Data
> }
> 
> Then we could add things like, e.g. a protocol extension to generate normally 
> distributed numbers 
> (https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform 
> ).
> 
> extension RandomGenerator {
> func normal() -> (T, T) {
> // ...
> }
> }
> 
>> On Sep 8, 2017, at 10:08 AM, Shawn Erickson via swift-evolution 
>> > wrote:
>> 
>> It would be nice to leverage range support instead of a start and end value 
>> IMHO.
>> On Fri, Sep 8, 2017 at 9:52 AM Alejandro Alonso via swift-evolution 
>> > 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
>> 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
> 
> ___
> swift-evolution mailing list
> 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


Re: [swift-evolution] [Pitch] Synthesized static enum property to iterate over cases

2017-09-08 Thread Kevin Nattinger via swift-evolution
I've been waiting for this for years. Literally since Swift was announced. IMO 
it's one of several major gaps in the language.

Some thoughts:
- It should be a simple array. 
- By far the most simple solution, and the one I (and, I'd guess, 
others) would expect.
- Every time I've needed the count, I need the actual values either 
within the same method or within the same run loop (e.g. table view).
- In my experience, direct indexing into the values array is more 
common than iterating over it.
- Rarely more than a few cases.
- Even an enum with a lot of cases, the actual number is trivial 
compared to the program's memory usage.
- No compiler magic beyond spitting out the static array. How do you 
propose to generate on-demand a sequence of values without compiler magic and 
without the values being stored somewhere?
- It should always be in declaration order. Period. 
- Reordering only in the case of Int raw values (especially only when 
0-N are all covered) is unintuitive at best, and I expect rarely what the dev 
would want.
- Should only work on enums without associated values. Enumerating on 
associated values is just begging for trouble. 
- (Infinite) recursion, as you pointed out.
- It seems more intuitive to me to have enumerated cases grouped, but 
what if there are cases with and without ATs?

>> [...]
>> Great points! I was only considering the table view/section case where the 
>> enum had raw values 0..> could just define `enum Section { case header, content, footer }` and then 
>> want to turn an IndexPath value into the appropriate Section.
>> 
>> On the other hand, though, isn't that what raw value enums are for? If the 
>> user needs to do what you're saying—map specific integers to enum 
>> values—shouldn't they do so by giving those cases raw values and calling 
>> init?(rawValue:), not by indexing into a collection? Especially since they 
>> can already do that today, and the only thing they're missing is being able 
>> to retrieve the count, which a "PrecountedSequence" mentioned above, or 
>> something like it, could also provide.

I... guess one could do that? Seems undesirable to me. What if I have them 
explicitly numbered, and delete one? Oops, now the whole thing is off and I 
have to go fix all the numbers. Besides, what if the dev wants to use it as a 
different raw representable? (`enum Title: String { ... }`)?

> 
> First, I’m making observations about what people are doing, not what they 
> could do.  
> 
> Second, the raw value may not correspond to 0-based indices.  It might not 
> even be an Int.  There is no reason to couple this common use case of 
> `allValues` to `Int` raw values with 0-based indices.

+1000. There is absolutely no reason to join these, or special-case 0-N int raw 
representables. 

> 
> Do we know of any examples where a user is both (1) defining an enum with 
> integer raw values that are noncontiguous or non-zero-based and (2) need 
> declaration-ordinal-based indexing into those cases for other reasons, like a 
> table/collection view? I can't think of why someone would do that, but I'm 
> happy to consider something that I'm missing.

Some underlying meaning? E.g. not a table view, but values or identifiers for 
some sort of low-level protocol.

>  
> 
> Third, `init(rawValue:)` is a failable initializer and would require a force 
> unwrap.  If the raw values *are* 0-based integers this is similar to the 
> collection bounds check that would be necessary, but it moves it into user 
> code.  People don’t like writing force unwraps.
> 
> Yeah, this is a really good point that I wasn't fully considering. If other 
> invariants in the application hold—such as table view cell functions never 
> receiving a section index outside 0.. users to address a situation that will never actually occur unless UIKit is 
> fundamentally broken.

Or the user makes a mistake numbering cases, or forgets to update something, 
... I usually put an assertion failure there, but I hate relying on even system 
libraries in production code. 

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


Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Taylor Swift via swift-evolution
I would very much like to see this implemented in pure Swift, i think it’s
only a hundred lines of code to implement anyway. That way, we also have
the same deterministic PRNGs across all Swift platforms. We should avoid
sticking more and more stuff into Foundation if it’s not necessary for
backwards compatibility. Instead it should go into its own Random core
module.

On Fri, Sep 8, 2017 at 11:52 AM, Alejandro Alonso via swift-evolution <
swift-evolution@swift.org> 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
> 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


Re: [swift-evolution] [Concurrency] async/await + actors

2017-09-08 Thread Kenny Leung via swift-evolution
Hi All.

A point of clarification in this example:

func loadWebResource(_ path: String) async -> Resource
func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image
func dewarpAndCleanupImage(_ i : Image) async -> Image

func processImageData1() async -> Image {
let dataResource  = await loadWebResource("dataprofile.txt")
let imageResource = await loadWebResource("imagedata.dat")
let imageTmp  = await decodeImage(dataResource, imageResource)
let imageResult   = await dewarpAndCleanupImage(imageTmp)
return imageResult
}

Do these:

await loadWebResource("dataprofile.txt")
await loadWebResource("imagedata.dat")

happen in in parallel? If so, how can I make the second one wait on the first 
one? If not, how can I make them go in parallel?

Thanks!

-Kenny

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


Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Taylor Swift via swift-evolution
I think ClosedRange. Also there should be support for floating types.

> On Sep 8, 2017, at 12:34 PM, Alejandro Alonso via swift-evolution 
>  wrote:
> 
> Range support is something that came up, and I think it’s a great idea as 
> well. My question now is do we support both `CountableRange` and 
> `CountableClosedRange`?
> 
>> On Sep 8, 2017, 12:08 PM -0500, Shawn Erickson , wrote:
>> It would be nice to leverage range support instead of a start and end value 
>> IMHO.
>>> On Fri, Sep 8, 2017 at 9:52 AM Alejandro Alonso via swift-evolution 
>>>  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
>>> 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
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Alejandro Alonso via swift-evolution
Range support is something that came up, and I think it’s a great idea as well. 
My question now is do we support both `CountableRange` and 
`CountableClosedRange`?

On Sep 8, 2017, 12:08 PM -0500, Shawn Erickson , wrote:
It would be nice to leverage range support instead of a start and end value 
IMHO.
On Fri, Sep 8, 2017 at 9:52 AM Alejandro Alonso via swift-evolution 
> 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
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


Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Kevin Nattinger via swift-evolution
IMO, we should have a `Random` or `RandomGenerator` interface and the stdlib 
can provide a `SystemRandom` that wraps arc4*/random(), and maybe a 
cryptographically secure one too (MT19937?).

protocol RandomGenerator {
func uniform() -> Int
func uniform() -> Double
func uniformBytes(count: Int) -> Data
}

Then we could add things like, e.g. a protocol extension to generate normally 
distributed numbers (https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform 
).

extension RandomGenerator {
func normal() -> (T, T) {
// ...
}
}

> On Sep 8, 2017, at 10:08 AM, Shawn Erickson via swift-evolution 
>  wrote:
> 
> It would be nice to leverage range support instead of a start and end value 
> IMHO.
> On Fri, Sep 8, 2017 at 9:52 AM Alejandro Alonso via swift-evolution 
> > 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
> 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

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


Re: [swift-evolution] [Proposal] Random Unification

2017-09-08 Thread Shawn Erickson via swift-evolution
It would be nice to leverage range support instead of a start and end value
IMHO.
On Fri, Sep 8, 2017 at 9:52 AM Alejandro Alonso via swift-evolution <
swift-evolution@swift.org> 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
> 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


Re: [swift-evolution] [Pitch] Synthesized static enum property to iterate over cases

2017-09-08 Thread Tony Allevato via swift-evolution
On Fri, Sep 8, 2017 at 9:44 AM Matthew Johnson 
wrote:

> On Sep 8, 2017, at 11:32 AM, Tony Allevato 
> wrote:
>
>
>
> On Fri, Sep 8, 2017 at 8:35 AM Matthew Johnson 
> wrote:
>
>> On Sep 8, 2017, at 9:53 AM, Tony Allevato via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Thanks for bringing this up, Logan! It's something I've been thinking
>> about a lot lately after a conversation with some colleagues outside of
>> this community. Some of my thoughts:
>>
>> AFAIK, there are two major use cases here: (1) you need the whole
>> collection of cases, like in your example, and (2) you just need the number
>> of cases. The latter seems to occur somewhat commonly when people want to
>> use an enum to define the sections of, say, a UITableView. They just return
>> the count from numberOfSections(in:) and then switch over the cases in
>> their cell-providing methods.
>>
>> Because of #2, it would be nice to avoid instantiating the collection
>> eagerly. (Also because of examples like Jonathan's, where the enum is
>> large.) If all the user is ever really doing is iterating over them,
>> there's no need to keep the entire collection in memory. This leads us to
>> look at Sequence; we could use something like AnySequence to keep the
>> current case as our state and a transition function to advance to the next
>> one. If a user needs to instantiate the full array from that sequence they
>> can do so, but they have to do it explicitly.
>>
>> The catch is that Sequence only provides `underestimatedCount`, rather
>> than `count`. Calling the former would be an awkward API (why is it
>> underestimated? we know how many cases there are). I suppose we could
>> create a concrete wrapper for Sequence (PrecountedSequence?) that provides
>> a `count` property to make that cleaner, and then have
>> `underestimatedCount` return the same thing if users passed this thing into
>> a generic operation constrained over Sequence. (The standard library
>> already has support wrappers like EnumeratedSequence, so maybe this is
>> appropriate.)
>>
>> Another question that would need to be answered is, how should the cases
>> be ordered? Declaration order seems obvious and straightforward, but if you
>> have a raw-value enum (say, integers), you could have the declaration order
>> and the numeric order differ. Maybe that's not a problem. Tying the
>> iteration order to declaration order also means that the behavior of a
>> program could change simply by reördering the cases. Maybe that's not a big
>> problem either, but it's something to call out.
>>
>> If I were designing this, I'd start with the following approach. First,
>> add a new protocol to the standard library:
>>
>> ```
>> public protocol ValueEnumerable {
>>   associatedtype AllValuesSequence: Sequence where
>> AllValuesSequence.Iterator.Element == Self
>>
>>   static var allValues: AllValuesSequence { get }
>> }
>> ```
>>
>> Then, for enums that declare conformance to that protocol, synthesize the
>> body of `allValues` to return an appropriate sequence. If we imagine a
>> model like AnySequence, then the "state" can be the current case, and the
>> transition function can be a switch/case that returns it and advances to
>> the next one (finally returning nil).
>>
>> There's an opportunity for optimization that may or may not be worth it:
>> if the enum is RawRepresentable with RawValue == Int, AND all the raw
>> values are in a contiguous range, AND declaration order is numerical order
>> (assuming we kept that constraint), then the synthesized state machine can
>> just be a simple integer incrementation and call to `init?(rawValue:)`.
>> When all the cases have been generated, that will return nil on its own.
>>
>> So that covers enums without associated values. What about those with
>> associated values? I would argue that the "number of cases" isn't something
>> that's very useful here—if we consider that enum cases are really factory
>> functions for concrete values of the type, then we shouldn't think about
>> "what are all the cases of this enum" but "what are all the values of this
>> type". (For enums without associated values, those are synonymous.)
>>
>> An enum with associated values can potentially have an infinite number of
>> values. Here's one:
>>
>> ```
>> enum BinaryTree {
>>   case subtree(left: BinaryTree, right: BinaryTree)
>>   case leaf
>>   case empty
>> }
>> ```
>>
>> Even without introducing an Element type in the leaf nodes, there are a
>> countably infinite number of binary trees. So first off, we wouldn't be
>> able to generate a meaningful `count` property for that. Since they're
>> countably infinite, we *could* theoretically lazily generate a sequence of
>> them! It would be a true statement to say "an enum with associated values
>> can have all of its values enumerated if all of its associated values are
>> also ValueEnumerable". But I don't think that's 

Re: [swift-evolution] [Pitch] Synthesized static enum property to iterate over cases

2017-09-08 Thread Matthew Johnson via swift-evolution

> On Sep 8, 2017, at 11:32 AM, Tony Allevato  wrote:
> 
> 
> 
> On Fri, Sep 8, 2017 at 8:35 AM Matthew Johnson  > wrote:
>> On Sep 8, 2017, at 9:53 AM, Tony Allevato via swift-evolution 
>> > wrote:
>> 
>> Thanks for bringing this up, Logan! It's something I've been thinking about 
>> a lot lately after a conversation with some colleagues outside of this 
>> community. Some of my thoughts:
>> 
>> AFAIK, there are two major use cases here: (1) you need the whole collection 
>> of cases, like in your example, and (2) you just need the number of cases. 
>> The latter seems to occur somewhat commonly when people want to use an enum 
>> to define the sections of, say, a UITableView. They just return the count 
>> from numberOfSections(in:) and then switch over the cases in their 
>> cell-providing methods.
>> 
>> Because of #2, it would be nice to avoid instantiating the collection 
>> eagerly. (Also because of examples like Jonathan's, where the enum is 
>> large.) If all the user is ever really doing is iterating over them, there's 
>> no need to keep the entire collection in memory. This leads us to look at 
>> Sequence; we could use something like AnySequence to keep the current case 
>> as our state and a transition function to advance to the next one. If a user 
>> needs to instantiate the full array from that sequence they can do so, but 
>> they have to do it explicitly.
>> 
>> The catch is that Sequence only provides `underestimatedCount`, rather than 
>> `count`. Calling the former would be an awkward API (why is it 
>> underestimated? we know how many cases there are). I suppose we could create 
>> a concrete wrapper for Sequence (PrecountedSequence?) that provides a 
>> `count` property to make that cleaner, and then have `underestimatedCount` 
>> return the same thing if users passed this thing into a generic operation 
>> constrained over Sequence. (The standard library already has support 
>> wrappers like EnumeratedSequence, so maybe this is appropriate.)
>> 
>> Another question that would need to be answered is, how should the cases be 
>> ordered? Declaration order seems obvious and straightforward, but if you 
>> have a raw-value enum (say, integers), you could have the declaration order 
>> and the numeric order differ. Maybe that's not a problem. Tying the 
>> iteration order to declaration order also means that the behavior of a 
>> program could change simply by reördering the cases. Maybe that's not a big 
>> problem either, but it's something to call out.
>> 
>> If I were designing this, I'd start with the following approach. First, add 
>> a new protocol to the standard library:
>> 
>> ```
>> public protocol ValueEnumerable {
>>   associatedtype AllValuesSequence: Sequence where 
>> AllValuesSequence.Iterator.Element == Self
>> 
>>   static var allValues: AllValuesSequence { get }
>> }
>> ```
>> 
>> Then, for enums that declare conformance to that protocol, synthesize the 
>> body of `allValues` to return an appropriate sequence. If we imagine a model 
>> like AnySequence, then the "state" can be the current case, and the 
>> transition function can be a switch/case that returns it and advances to the 
>> next one (finally returning nil).
>> 
>> There's an opportunity for optimization that may or may not be worth it: if 
>> the enum is RawRepresentable with RawValue == Int, AND all the raw values 
>> are in a contiguous range, AND declaration order is numerical order 
>> (assuming we kept that constraint), then the synthesized state machine can 
>> just be a simple integer incrementation and call to `init?(rawValue:)`. When 
>> all the cases have been generated, that will return nil on its own.
>> 
>> So that covers enums without associated values. What about those with 
>> associated values? I would argue that the "number of cases" isn't something 
>> that's very useful here—if we consider that enum cases are really factory 
>> functions for concrete values of the type, then we shouldn't think about 
>> "what are all the cases of this enum" but "what are all the values of this 
>> type". (For enums without associated values, those are synonymous.)
>> 
>> An enum with associated values can potentially have an infinite number of 
>> values. Here's one:
>> 
>> ```
>> enum BinaryTree {
>>   case subtree(left: BinaryTree, right: BinaryTree)
>>   case leaf
>>   case empty
>> }
>> ```
>> 
>> Even without introducing an Element type in the leaf nodes, there are a 
>> countably infinite number of binary trees. So first off, we wouldn't be able 
>> to generate a meaningful `count` property for that. Since they're countably 
>> infinite, we *could* theoretically lazily generate a sequence of them! It 
>> would be a true statement to say "an enum with associated values can have 
>> all of its values enumerated if all of its associated values are also 
>> 

Re: [swift-evolution] [Pitch] Synthesized static enum property to iterate over cases

2017-09-08 Thread Tony Allevato via swift-evolution
On Fri, Sep 8, 2017 at 8:35 AM Matthew Johnson 
wrote:

> On Sep 8, 2017, at 9:53 AM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Thanks for bringing this up, Logan! It's something I've been thinking
> about a lot lately after a conversation with some colleagues outside of
> this community. Some of my thoughts:
>
> AFAIK, there are two major use cases here: (1) you need the whole
> collection of cases, like in your example, and (2) you just need the number
> of cases. The latter seems to occur somewhat commonly when people want to
> use an enum to define the sections of, say, a UITableView. They just return
> the count from numberOfSections(in:) and then switch over the cases in
> their cell-providing methods.
>
> Because of #2, it would be nice to avoid instantiating the collection
> eagerly. (Also because of examples like Jonathan's, where the enum is
> large.) If all the user is ever really doing is iterating over them,
> there's no need to keep the entire collection in memory. This leads us to
> look at Sequence; we could use something like AnySequence to keep the
> current case as our state and a transition function to advance to the next
> one. If a user needs to instantiate the full array from that sequence they
> can do so, but they have to do it explicitly.
>
> The catch is that Sequence only provides `underestimatedCount`, rather
> than `count`. Calling the former would be an awkward API (why is it
> underestimated? we know how many cases there are). I suppose we could
> create a concrete wrapper for Sequence (PrecountedSequence?) that provides
> a `count` property to make that cleaner, and then have
> `underestimatedCount` return the same thing if users passed this thing into
> a generic operation constrained over Sequence. (The standard library
> already has support wrappers like EnumeratedSequence, so maybe this is
> appropriate.)
>
> Another question that would need to be answered is, how should the cases
> be ordered? Declaration order seems obvious and straightforward, but if you
> have a raw-value enum (say, integers), you could have the declaration order
> and the numeric order differ. Maybe that's not a problem. Tying the
> iteration order to declaration order also means that the behavior of a
> program could change simply by reördering the cases. Maybe that's not a big
> problem either, but it's something to call out.
>
> If I were designing this, I'd start with the following approach. First,
> add a new protocol to the standard library:
>
> ```
> public protocol ValueEnumerable {
>   associatedtype AllValuesSequence: Sequence where
> AllValuesSequence.Iterator.Element == Self
>
>   static var allValues: AllValuesSequence { get }
> }
> ```
>
> Then, for enums that declare conformance to that protocol, synthesize the
> body of `allValues` to return an appropriate sequence. If we imagine a
> model like AnySequence, then the "state" can be the current case, and the
> transition function can be a switch/case that returns it and advances to
> the next one (finally returning nil).
>
> There's an opportunity for optimization that may or may not be worth it:
> if the enum is RawRepresentable with RawValue == Int, AND all the raw
> values are in a contiguous range, AND declaration order is numerical order
> (assuming we kept that constraint), then the synthesized state machine can
> just be a simple integer incrementation and call to `init?(rawValue:)`.
> When all the cases have been generated, that will return nil on its own.
>
> So that covers enums without associated values. What about those with
> associated values? I would argue that the "number of cases" isn't something
> that's very useful here—if we consider that enum cases are really factory
> functions for concrete values of the type, then we shouldn't think about
> "what are all the cases of this enum" but "what are all the values of this
> type". (For enums without associated values, those are synonymous.)
>
> An enum with associated values can potentially have an infinite number of
> values. Here's one:
>
> ```
> enum BinaryTree {
>   case subtree(left: BinaryTree, right: BinaryTree)
>   case leaf
>   case empty
> }
> ```
>
> Even without introducing an Element type in the leaf nodes, there are a
> countably infinite number of binary trees. So first off, we wouldn't be
> able to generate a meaningful `count` property for that. Since they're
> countably infinite, we *could* theoretically lazily generate a sequence of
> them! It would be a true statement to say "an enum with associated values
> can have all of its values enumerated if all of its associated values are
> also ValueEnumerable". But I don't think that's something we could have the
> compiler synthesize generally: the logic to tie the sequences together
> would be quite complex in the absence of a construct like coroutines/yield,
> and what's worse, the compiler would have to do some deeper analysis to
> avoid 

Re: [swift-evolution] [Pitch] Synthesized static enum property to iterate over cases

2017-09-08 Thread Matthew Johnson via swift-evolution

> On Sep 8, 2017, at 9:53 AM, Tony Allevato via swift-evolution 
>  wrote:
> 
> Thanks for bringing this up, Logan! It's something I've been thinking about a 
> lot lately after a conversation with some colleagues outside of this 
> community. Some of my thoughts:
> 
> AFAIK, there are two major use cases here: (1) you need the whole collection 
> of cases, like in your example, and (2) you just need the number of cases. 
> The latter seems to occur somewhat commonly when people want to use an enum 
> to define the sections of, say, a UITableView. They just return the count 
> from numberOfSections(in:) and then switch over the cases in their 
> cell-providing methods.
> 
> Because of #2, it would be nice to avoid instantiating the collection 
> eagerly. (Also because of examples like Jonathan's, where the enum is large.) 
> If all the user is ever really doing is iterating over them, there's no need 
> to keep the entire collection in memory. This leads us to look at Sequence; 
> we could use something like AnySequence to keep the current case as our state 
> and a transition function to advance to the next one. If a user needs to 
> instantiate the full array from that sequence they can do so, but they have 
> to do it explicitly.
> 
> The catch is that Sequence only provides `underestimatedCount`, rather than 
> `count`. Calling the former would be an awkward API (why is it 
> underestimated? we know how many cases there are). I suppose we could create 
> a concrete wrapper for Sequence (PrecountedSequence?) that provides a `count` 
> property to make that cleaner, and then have `underestimatedCount` return the 
> same thing if users passed this thing into a generic operation constrained 
> over Sequence. (The standard library already has support wrappers like 
> EnumeratedSequence, so maybe this is appropriate.)
> 
> Another question that would need to be answered is, how should the cases be 
> ordered? Declaration order seems obvious and straightforward, but if you have 
> a raw-value enum (say, integers), you could have the declaration order and 
> the numeric order differ. Maybe that's not a problem. Tying the iteration 
> order to declaration order also means that the behavior of a program could 
> change simply by reördering the cases. Maybe that's not a big problem either, 
> but it's something to call out.
> 
> If I were designing this, I'd start with the following approach. First, add a 
> new protocol to the standard library:
> 
> ```
> public protocol ValueEnumerable {
>   associatedtype AllValuesSequence: Sequence where 
> AllValuesSequence.Iterator.Element == Self
> 
>   static var allValues: AllValuesSequence { get }
> }
> ```
> 
> Then, for enums that declare conformance to that protocol, synthesize the 
> body of `allValues` to return an appropriate sequence. If we imagine a model 
> like AnySequence, then the "state" can be the current case, and the 
> transition function can be a switch/case that returns it and advances to the 
> next one (finally returning nil).
> 
> There's an opportunity for optimization that may or may not be worth it: if 
> the enum is RawRepresentable with RawValue == Int, AND all the raw values are 
> in a contiguous range, AND declaration order is numerical order (assuming we 
> kept that constraint), then the synthesized state machine can just be a 
> simple integer incrementation and call to `init?(rawValue:)`. When all the 
> cases have been generated, that will return nil on its own.
> 
> So that covers enums without associated values. What about those with 
> associated values? I would argue that the "number of cases" isn't something 
> that's very useful here—if we consider that enum cases are really factory 
> functions for concrete values of the type, then we shouldn't think about 
> "what are all the cases of this enum" but "what are all the values of this 
> type". (For enums without associated values, those are synonymous.)
> 
> An enum with associated values can potentially have an infinite number of 
> values. Here's one:
> 
> ```
> enum BinaryTree {
>   case subtree(left: BinaryTree, right: BinaryTree)
>   case leaf
>   case empty
> }
> ```
> 
> Even without introducing an Element type in the leaf nodes, there are a 
> countably infinite number of binary trees. So first off, we wouldn't be able 
> to generate a meaningful `count` property for that. Since they're countably 
> infinite, we *could* theoretically lazily generate a sequence of them! It 
> would be a true statement to say "an enum with associated values can have all 
> of its values enumerated if all of its associated values are also 
> ValueEnumerable". But I don't think that's something we could have the 
> compiler synthesize generally: the logic to tie the sequences together would 
> be quite complex in the absence of a construct like coroutines/yield, and 
> what's worse, the compiler would have to do some deeper analysis to avoid 
> infinite recursion. 

Re: [swift-evolution] [Pitch] Synthesized static enum property to iterate over cases

2017-09-08 Thread Tony Allevato via swift-evolution
Thanks for bringing this up, Logan! It's something I've been thinking about
a lot lately after a conversation with some colleagues outside of this
community. Some of my thoughts:

AFAIK, there are two major use cases here: (1) you need the whole
collection of cases, like in your example, and (2) you just need the number
of cases. The latter seems to occur somewhat commonly when people want to
use an enum to define the sections of, say, a UITableView. They just return
the count from numberOfSections(in:) and then switch over the cases in
their cell-providing methods.

Because of #2, it would be nice to avoid instantiating the collection
eagerly. (Also because of examples like Jonathan's, where the enum is
large.) If all the user is ever really doing is iterating over them,
there's no need to keep the entire collection in memory. This leads us to
look at Sequence; we could use something like AnySequence to keep the
current case as our state and a transition function to advance to the next
one. If a user needs to instantiate the full array from that sequence they
can do so, but they have to do it explicitly.

The catch is that Sequence only provides `underestimatedCount`, rather than
`count`. Calling the former would be an awkward API (why is it
underestimated? we know how many cases there are). I suppose we could
create a concrete wrapper for Sequence (PrecountedSequence?) that provides
a `count` property to make that cleaner, and then have
`underestimatedCount` return the same thing if users passed this thing into
a generic operation constrained over Sequence. (The standard library
already has support wrappers like EnumeratedSequence, so maybe this is
appropriate.)

Another question that would need to be answered is, how should the cases be
ordered? Declaration order seems obvious and straightforward, but if you
have a raw-value enum (say, integers), you could have the declaration order
and the numeric order differ. Maybe that's not a problem. Tying the
iteration order to declaration order also means that the behavior of a
program could change simply by reördering the cases. Maybe that's not a big
problem either, but it's something to call out.

If I were designing this, I'd start with the following approach. First, add
a new protocol to the standard library:

```
public protocol ValueEnumerable {
  associatedtype AllValuesSequence: Sequence where
AllValuesSequence.Iterator.Element == Self

  static var allValues: AllValuesSequence { get }
}
```

Then, for enums that declare conformance to that protocol, synthesize the
body of `allValues` to return an appropriate sequence. If we imagine a
model like AnySequence, then the "state" can be the current case, and the
transition function can be a switch/case that returns it and advances to
the next one (finally returning nil).

There's an opportunity for optimization that may or may not be worth it: if
the enum is RawRepresentable with RawValue == Int, AND all the raw values
are in a contiguous range, AND declaration order is numerical order
(assuming we kept that constraint), then the synthesized state machine can
just be a simple integer incrementation and call to `init?(rawValue:)`.
When all the cases have been generated, that will return nil on its own.

So that covers enums without associated values. What about those with
associated values? I would argue that the "number of cases" isn't something
that's very useful here—if we consider that enum cases are really factory
functions for concrete values of the type, then we shouldn't think about
"what are all the cases of this enum" but "what are all the values of this
type". (For enums without associated values, those are synonymous.)

An enum with associated values can potentially have an infinite number of
values. Here's one:

```
enum BinaryTree {
  case subtree(left: BinaryTree, right: BinaryTree)
  case leaf
  case empty
}
```

Even without introducing an Element type in the leaf nodes, there are a
countably infinite number of binary trees. So first off, we wouldn't be
able to generate a meaningful `count` property for that. Since they're
countably infinite, we *could* theoretically lazily generate a sequence of
them! It would be a true statement to say "an enum with associated values
can have all of its values enumerated if all of its associated values are
also ValueEnumerable". But I don't think that's something we could have the
compiler synthesize generally: the logic to tie the sequences together
would be quite complex in the absence of a construct like coroutines/yield,
and what's worse, the compiler would have to do some deeper analysis to
avoid infinite recursion. For example, if it used the naïve approach of
generating the elements in declaration order, it would keep drilling down
into the `subtree` case above over and over; it really needs to hit the
base cases first, and requiring the user to order the cases in a certain
way for it to just work at all is a non-starter.

So, enums with associated 

Re: [swift-evolution] [Pitch] Synthesized static enum property to iterate over cases

2017-09-08 Thread Jonathan Hull via swift-evolution
+1000

I once made a country code enum, and creating that array was simple, but took 
forever, and was prone to mistakes.

Thanks,
Jon

> On Sep 8, 2017, at 2:56 AM, Logan Shire via swift-evolution 
>  wrote:
> 
> Googling ‘swift iterate over enum cases’ yields many results of various 
> levels of hackery.
> Obviously it’s trivial to write a computed property that returns an enum’s 
> cases as an
> array, but maintaining that is prone to error. If you add another case, you 
> need to make sure
> you update the array property. For enums without associated types,
> I propose adding a synthesized static var, ‘cases', to the enum’s type. E.g.
> 
> enum Suit: String {
>case spades = "♠"
>case hearts = "♥"
>case diamonds = "♦"
>case clubs = "♣"
> }
> 
> let values = (1…13).map { value in
>switch value {
>case 1: return “A”
>case 11: return “J”
>case 12: return “Q”
>case 13: return “K”
>default: return String(value)
>}
> }
> 
> let cards = values.flatMap { value in Suit.cases.map { “\($0)\(value)"  } }
> 
> Yields [“♠A”, “ ♥ A”, …, “♣K”]
> Thoughts?
> 
> 
> Thanks!
> - Logan Shire
> ___
> swift-evolution mailing list
> 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


Re: [swift-evolution] [Pitch] Synthesized static enum property to iterate over cases

2017-09-08 Thread Vladimir.S via swift-evolution

On 08.09.2017 12:56, Logan Shire via swift-evolution wrote:

Googling ‘swift iterate over enum cases’ yields many results of various levels 
of hackery.
Obviously it’s trivial to write a computed property that returns an enum’s 
cases as an
array, but maintaining that is prone to error. If you add another case, you 
need to make sure
you update the array property. For enums without associated types,
I propose adding a synthesized static var, ‘cases', to the enum’s type. E.g.


Yes, this feature was discussed previously, but was not going into formal review for 
different reasons. Personally, I want this feature very much.
Currently, as I understand, if someone will implement this feature in Swift and 
raised a formal review - this addition can be accepted.
So, if someone is ready to implement this in Swift compiler code, we can discuss 
details(again) in this pitch to prepare a formal proposal.


Vladimir.



enum Suit: String {
 case spades = "♠"
 case hearts = "♥"
 case diamonds = "♦"
 case clubs = "♣"
}

let values = (1…13).map { value in
 switch value {
 case 1: return “A”
 case 11: return “J”
 case 12: return “Q”
 case 13: return “K”
 default: return String(value)
 }
}

let cards = values.flatMap { value in Suit.cases.map { “\($0)\(value)"  } }

Yields [“♠A”, “ ♥ A”, …, “♣K”]
Thoughts?


Thanks!
- Logan Shire
___
swift-evolution mailing list
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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0184: Unsafe[Mutable][Raw][Buffer]Pointer: add missing methods, adjust existing labels for clarity, and remove deallocation size

2017-09-08 Thread Taylor Swift via swift-evolution
let me summarize why i think deallocate should lose the capacity parameter
for now:


   - up to now, the capacity argument has been poorly, even misleadingly
   documented. this means it is unlikely that existing users of the API are
   using it correctly.
   - deallocate(capacity:) allows for optimizations that could improve the
   performance of the Swift heap. however, these optimizations are not in
   place yet, nor will they be any time soon, so dropping the parameter would
   result in no performance regressions.
   - users coming from C/C++ are used to the malloc(_:) – free() pattern.
   Swift should support this both for learnability, and for
malloc-compatibility.

   - completely departing from the malloc memory model might save a few
   bytes of headers in the heap, but as discussed in this thread, there are
   other upsides of Swift being malloc-compatible.
   - there is nothing preventing us from reintroducing
   deallocate(allocatedCapacity:) in the future, once the runtime actually
   supports this feature. informed users looking for a performance boost could
   opt-in to use this API instead.
   - deprecating, and then un-deprecating deallocate(capacity:) might sound
   extra, but keeping this method unbothered is actually a bad idea. whoever
   is using it right now, is probably not using it correctly. The best
   strategy is to reintroduce it later as a well-documented *opt-in*
   feature. Grandfathering in old incorrect code offers no benefits and many
   problems.
   - lying to users is never a good idea. for the forseeable future,
   Heap.cpp calls free(), and Swift shouldn’t pretend like it supports
   something it doesn’t support.




On Thu, Sep 7, 2017 at 8:18 PM, Andrew Trick  wrote:

>
> On Sep 7, 2017, at 5:56 PM, Jordan Rose  wrote:
>
>
>
> On Sep 7, 2017, at 17:46, Andrew Trick  wrote:
>
>
> On Sep 7, 2017, at 5:40 PM, Joe Groff  wrote:
>
>
>
> But then given that, I don't understand why the 'capacity' parameter is
> necessary. Under what circumstances would it actually be faster than "just"
> calling malloc_size?
>
>
> The runtime may need to hash the address or traverse a lookup table to
> find out which allocation pool the block resides in. Now, that’s only if
> some platform ditches full malloc compatibility for user allocations, so
> I’m not sure how realistic it is.
>
>
> It seems to me that you could still provide malloc/free compatibility with
> a zone that had to do a relatively expensive traversal on free() to recover
> the pool the memory came from; malloc/free just wouldn't be the ideal
> interface in that situation.
>
> -Joe
>
>
> Joe is right, and I just learned how amazing malloc zones are.
>
>
> As long as you support multiple allocators (or hide everything behind
> malloc/free), there's already a cost of malloc_zone_from_ptr or equivalent.
> Without seeing a concrete use case, I wouldn't want to stay with the
> harder-to-use API *in UnsafePointer itself.* It might be a feature of a
> *particular* allocator that you need to keep the capacity around, but it
> *isn't* something generally true about Swift's memory model, and probably
> never will be.
>
> (Interesting reference points: malloc/malloc.h and the implementation of
> malloc on macOS
> 
>  -
> search for "free(void *ptr)".)
>
> Jordan
>
>
> I’m primarily arguing from the point of view that UnsafeBufferPointer
> should pass it’s deallocation capacity and should be implementable in terms
> of UnsafePointer. But I’m fine hiding the capacity argument from the public
> API for now. We know what the proposal author wants to do, so unless Joe
> still feels strongly, we could accept the proposal as-is, put the API
> decision to rest and focus on better documentation and and assertions.
>
> -Andy
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution