Re: [swift-evolution] 100% bikeshed topic: DictionaryLiteral

2018-01-12 Thread Chris Lattner via swift-evolution
On Jan 12, 2018, at 4:43 PM, Ted Kremenek  wrote:
> Hi Chris,
> 
> Instead of responding to each of your point bit-by-bit, I’ll try a different 
> tactic to explain my reasoning — which may be wrong — by explaining how I see 
> things top down with the tradeoffs they incur.  I’m going to say a bunch of 
> things I know *you* know, but others are on this thread and I’ll state things 
> for end-to-end clarity.

Sounds good.

> It seems to me that we are talking about two possible scenarios: (1) the 
> status quo of keeping everything in libswiftCore.dylib or (2) splitting 
> libswiftCore.dylib into two dylibs, one which includes some of the 
> “deprecated” APIs.  I’ll enumerate what I think are the tradeoffs/benefits we 
> will see with both scenarios, and see where the mismatch in our “talking past 
> each other” is happening.

Right.

> In both cases (A) and (B), with ABI stability the Standard Library has the 
> option to ship in the OS.  Thus applications using Swift on (say) iOS would 
> no longer need to include libswiftCore.dylib in the app when running on an OS 
> that shipped with the Standard Library.

Right.  Please keep in mind that both approaches also eliminate all the overlay 
dylibs for those apps, and both approaches put the vast majority of the stdlib 
code into the OS as well.  The ‘deprecated’ dylib is probably going to be 
comparatively small.

> With that in mind, here are the tradeoffs as I see between scenarios (A) and 
> (B):
> 
> (A) Status quo: Keep shipping everything in libswiftCore.dylib
> 
> - Applications running on an OS with the Standard Library would no longer 
> have *any* of the currently libswift*.dylib’s embedded inside the application 
> bundle because they would just use the one in the OS.

Right.

> - One benefit of using libswift*.dylibs in the OS as opposed to those 
> embedded inside the app bundle is that there is a non-neglible startup time 
> improvement, as the code signing verification that happens when an app 
> launches would be faster as it would not need to verify each of these dylibs 
> that were previously embedded in the app.  We should consider this the new 
> baseline for app startup time for an app running on an OS with an ABI stable 
> Standard Library.

This happens with both models.  Refer back to the dyld optimization WWDC talk 
by Nick and Louis 2-3 years ago.  The big problem with Swift for startup time 
is that it adds half a dozen (or more) dylibs to your app bundle.  In the talk 
they make it clear that adding a single dylib is not a big deal, it is adding a 
bunch of dylibs that is the problem, particularly if they have 
interdependencies between them.

Neither approach presents this performance problem.

Further, if it were important to solve this startup time problem, it is 
straight-forward to solve it for apps that do want to deploy backward (which 
will be almost all of them in NMOS).  You’d do this by merging all the dylibs 
into a single one in the app bundle instead of leaving them to be independently 
resolved at load time.

> - We continue to support the deprecated APIs for some time, possibly 
> indefinitely, even when better alternatives come around.

Agreed.

> (B) Split libswiftCore.dylib into two dylibs, one that gets embedded in the 
> app bundle
> 
> In the second scenario, we split out the deprecated APIs into a separate 
> dylib, say libswiftCoreDeprecated.dylib.  That solution would have the 
> following characteristics:
> 
> - Like scenario (A), app bundles would not need to embed libswiftCore.dylib 
> when running on an OS that had an ABI-stable Standard Library.
> 
> - Compared to scenario (A), the OS shipping the Standard Library would have a 
> slightly smaller libswiftCore.dylib that didn’t carry the bits for the 
> deprecated APIs.  This would be a benefit in the code size for the OS, but 
> not for the app itself.

The code size is small so it doesn’t matter much either way, but this actually 
is an advantage for the average app.  Part of the point of this is that most 
apps don’t use this stuff, so they wouldn’t include the dylib at all.  There is 
no cost for them in either launch time or size.

To pick on Mirrors, the one example someone came up with is an API used by the 
swift on server community.  I haven’t heard of anyone using them in an iOS app 
(but of course I’m sure there is someone somewhere doing it :-)

> - Any app using a deprecated API we put into libswiftCoreDeprecated.dylib 
> (e.g., Mirrors) would need to embed libswiftCoreDeprecated.dylib inside their 
> app bundle.  Compared to the new baseline I mentioned in (A), such apps would 
> have a launch time regression once they started using any API in the 
> libSwiftCoreDeprecated.dylib because code signing would need to verify the 
> dylib, just like it does today with the libswiftCore.dylib that is embedded 
> in every application.  They would also be slightly larger because the app 
> bundle has the burden of hosting 

Re: [swift-evolution] [Proposal] Revamp the playground quicklook APIs

2018-01-12 Thread Chris Lattner via swift-evolution
> On Jan 12, 2018, at 6:22 PM, Connor Wakamo  wrote:
> 
>>> The second case, and the one I’m more worried about, is subclassing. If, 
>>> for instance, you have the following:
>>> 
>>> class FooView: UIView, CustomPlaygroundRepresentable {
>>> var playgroundRepresentation: Any {
>>> return “A string describing this view"
>>> }
>>> }
>>> 
>>> class BarView: FooView {
>>> override var playgroundRepresentation: Any {
>>> // BarView instances wanted to be logged as themselves, 
>>> but there’s no way to express that
>>> return ???
>>> }
>>> }
>>> 
>>> There’s nothing that BarView can do to ensure it gets logged like a view 
>>> because FooView declared a conformance to CustomPlaygroundRepresentable.
>> 
>> I really don’t understand this.  FooView declares that it conforms, and it 
>> provides a “playgroundRepresentation” member.  Cool for FooView.
>> 
>> BarView comes around and overrides FooView’s implementation.  They don’t 
>> have to conform, because it *isa* FooView, so of course it conforms.  If it 
>> wants to customize its presentation, it overrides its  
>> “playgroundRepresentation” method and it… just works.  If it conditionally 
>> wants the FooView representation for some reason, it can even call 
>> “super.playgroundRepresentation”.  What’s the problem?  This seems ideal to 
>> me.
> 
> The issue is that there’s no way for `BarView` to recover the default 
> playground representation which `UIView` and its subclasses get.

I get it now, thanks.

> For a `UIView`, the PlaygroundLogger library renders an image of the view and 
> packages that up in a log entry. If `BarView` wants that instead of 
> `FooView`’s custom representation, there’s no way for it to request it.

I can think of two different ways to solve this problem:

1) Go with your suggestion upthread, where a custom enum is used: 
implementations do:

  if predicate() {
return .custom(“my representation)
  } else {
return .default
  }

The problem with this is that you’re forcing implementations of this to deal 
with the enum just because of the rare case.  Not a showstopper, but doesn’t 
feel right.

2) Go with the simple approach of returning Any, and add a new function to the 
Playground API somewhere that produces the default representation that they can 
call, the unusual case above would look like this:

  if predicate() {
return “my representation
  } else {
return SomePlaygroundAPI.getDefaultPlaygroundRepresentation(self)
  }

This seems like the best of both worlds to me.

>> IMO, every time you choose to privilege “well known” types in the standard 
>> library with special code in Xcode (or some other high level system loosely 
>> integrated with swift.org ) you are introducing technical 
>> debt into the Swift ecosystem.  This is because you are violating the basic 
>> principles on which Swift was established, which is that users can 
>> [re]define primitives to build their own abstractions and carve out new 
>> domains beyond what was originally envisioned when you’re writing the UI 
>> code.
> 
> So given that, I think it’s not unreasonable for a platform/toolchain’s 
> playground logger to know about that platform/toolchain’s important types so 
> it can produce the appropriate opaque log entries. If there’s some approach 
> that I’m overlooking — or if I’m dismissing the suite of protocols case too 
> quickly — I would love to hear it, because I’m open to suggestions.

Yes, you are completely right: Unless you are willing to make the structured 
schema public, there is no point to doing what I suggest.

I do think that there is a schema which would make sense to take public 
(similar to the abstract format used in treeviews like the navigator and UI 
debugger for variables, strikingly similar to what JSON can express with a 
fancier terminal than strings), but there is no rush to do that, and it is best 
to take time to consider it deliberately.


>> Is the problem the “one” case?  If that is the problem, then it might be 
>> better to take a completely different approach where you embrace the fact 
>> that you have structured data producing 2D results that need to be 
>> displayed.  Each result could either return an atomic result or a result 
>> that wraps some other recursive 2D presentation.
> 
> No, the issue is that the playground logger would see that `Foo.two` conforms 
> to `CustomPlaygroundConvertible`, and would therefore call 
> `playgroundDescription` another time, which would return another `Foo.two`, 
> and this would continue endlessly. I plan to guard against that in 
> PlaygroundLogger with a limit on chaining, but this protocol should not 
> require a failsafe as a feature.

Right, it seems like the best way to solve this is to provide explicit access 
to the default presentation.

-Chris


Re: [swift-evolution] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Chris Lattner via swift-evolution

> On Jan 12, 2018, at 3:08 PM, Jordan Rose  wrote:
> 
> Okay, I went back to `unknown case` in the proposal, but mentioned Chris's 
> point very specifically: if the compiler emits an error, we should go with 
> `case #unknown` instead. (I'm very strongly in the "warning" camp, though.)

Thanks!

Out of curiosity, why not “unknown default:”?  The “warning” behavior is a 
customization of default, so this seems like a more logical model.  It also 
fits into the existing Swift grammar, unlike “unknown case:” which requires 
adding a new special case production.

-Chris

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


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

2018-01-12 Thread Karl Wagner via swift-evolution


> On 13. Jan 2018, at 05:23, Nate Cook via swift-evolution 
>  wrote:
> 
> On Jan 12, 2018, at 6:24 PM, Jonathan Hull via swift-evolution 
> > wrote:
> 
>> I think we have different definitions of consistency.  I am fine with the 
>> ergonomics of (0…100).random() as a convenience, but it really worries me 
>> here that everything is special cased.  Special cased things are fine for 
>> individual projects, but not the standard library.  We should make sure that 
>> the design is flexible and extensible, and that comes in part from having a 
>> consistent interface.
>> 
>> Also, as I said before, we really shouldn’t be doing these crazy contortions 
>> to avoid ‘random() % 100’.  Instead we should look for that pattern and 
>> issue with a warning + fixit to change it to random(in:).  I think that will 
>> be much more effective in actually changing the behavior in the long run.
> 
> I’m not sure what contortions you’re describing—from what I’ve seen, the 
> proposal author is going to revise the proposal to have these ways of 
> generating individual values:
> 
> In extensions to FixedWidthInteger and BinaryFloatingPoint:
> static func random(in: Range/ClosedRange, using: RandomNumberGenerator) 
> -> Self
> 
> In an extension to Bool:
> static func random(using: RandomNumberGenerator) -> Self
> 
> If someone still needs a full-width random value as a building-block for 
> generating random instances of other types, they should use the `next()` 
> method directly on a RandomNumberGenerator. In the example code you sent, you 
> could switch to using a RandomNumberGenerator instead of your 
> RandomSourceValue, or base your RandomSourceValue generation on a 
> RandomNumberGenerator instead of whatever random generator you’re using now.

I’m not sure what the current most-recent proposal is, but I think that’s fine 
for a minimal API.

The only thing I would add would be a convenience function which accesses a 
random element from a RandomAccessCollection.

- Karl

> 
>> Finally, tying everything to Range is extremely limiting.  I understand if 
>> we don’t want to add other types to the standard library, but I should be 
>> able to build on what we add to do it myself without having to reinvent the 
>> wheel for each type.  It is important to have a consistent story for these 
>> things (including multi-dimensional types) so that they can interoperate.
>> 
>> We really should be looking at GamePlayKit more for design inspiration.  
>> There are several use-cases there that are being blatantly ignored in this 
>> discussion.  For example, what if I want to randomly generate a game world 
>> (e.g. The square from The Battle For Polytopia” formerly “SuperTribes”)?  Or 
>> what if I want an effect where it randomly fades in letters from a String.  
>> (…).random() will be completely inadequate for these things.
> 
> The goal at this point is to build into the standard library the basis for 
> all kinds of other use cases. Your library is one such example of something 
> that can be built on top of the protocol and methods that are being proposed, 
> as are a variety of other tasks, as I tried to show in the playground.
> 
> What’s being proposed now is deliberately short of solving every need—the 
> additions would handle the hard stuff (correct and safe generation of 
> integers and floating-points, along with shuffling collections) and lay the 
> groundwork for other libraries to take things farther (by establishing the 
> RandomNumberGenerator, a default generator, and a pattern for their use).
> 
> Speaking of GameplayKit, you can make GKRandomSource conform to 
> RandomNumberGenerator in an extension, making all the GK... sources 
> generators. If you’re already depending on those random sources, you’d still 
> have access to them with the proposed model.
> 
> Nate
> 
>> Thanks,
>> Jon
>> 
>> 
>> 
>>> On Jan 12, 2018, at 5:11 AM, Letanyan Arumugam >> > wrote:
>>> 
>>> Nate’s design follows a consistent idea of getting a random value from some 
>>> set of values. Adding the static method random() to a type essentially 
>>> creates an implicit set which you yourself said leads to inconsistency 
>>> (Double/Int). Secondly I don’t see why random(in:) should be added when it 
>>> is just a different spelling for what is already provided. If my second 
>>> statement is incorrect and there’s something I’m missing please correct me?
>>> 
>>> I think that consistency outweighs the random trapping inconsistency, 
>>> however I would actually be fine if random returned an optional. Though the 
>>> way random is used would likely lead to less opportunities for a trap than 
>>> the other methods you mention. 
>>> 
>>> 
>>> Letanyan
>>> 
 On 12 Jan 2018, at 04:39, Alejandro Alonso > wrote:
 
 If anything, 

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

2018-01-12 Thread Nate Cook via swift-evolution
> On Jan 12, 2018, at 6:24 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> I think we have different definitions of consistency.  I am fine with the 
> ergonomics of (0…100).random() as a convenience, but it really worries me 
> here that everything is special cased.  Special cased things are fine for 
> individual projects, but not the standard library.  We should make sure that 
> the design is flexible and extensible, and that comes in part from having a 
> consistent interface.
> 
> Also, as I said before, we really shouldn’t be doing these crazy contortions 
> to avoid ‘random() % 100’.  Instead we should look for that pattern and issue 
> with a warning + fixit to change it to random(in:).  I think that will be 
> much more effective in actually changing the behavior in the long run.

I’m not sure what contortions you’re describing—from what I’ve seen, the 
proposal author is going to revise the proposal to have these ways of 
generating individual values:

In extensions to FixedWidthInteger and BinaryFloatingPoint:
static func random(in: Range/ClosedRange, using: RandomNumberGenerator) 
-> Self

In an extension to Bool:
static func random(using: RandomNumberGenerator) -> Self

If someone still needs a full-width random value as a building-block for 
generating random instances of other types, they should use the `next()` method 
directly on a RandomNumberGenerator. In the example code you sent, you could 
switch to using a RandomNumberGenerator instead of your RandomSourceValue, or 
base your RandomSourceValue generation on a RandomNumberGenerator instead of 
whatever random generator you’re using now.

> Finally, tying everything to Range is extremely limiting.  I understand if we 
> don’t want to add other types to the standard library, but I should be able 
> to build on what we add to do it myself without having to reinvent the wheel 
> for each type.  It is important to have a consistent story for these things 
> (including multi-dimensional types) so that they can interoperate.
> 
> We really should be looking at GamePlayKit more for design inspiration.  
> There are several use-cases there that are being blatantly ignored in this 
> discussion.  For example, what if I want to randomly generate a game world 
> (e.g. The square from The Battle For Polytopia” formerly “SuperTribes”)?  Or 
> what if I want an effect where it randomly fades in letters from a String.  
> (…).random() will be completely inadequate for these things.

The goal at this point is to build into the standard library the basis for all 
kinds of other use cases. Your library is one such example of something that 
can be built on top of the protocol and methods that are being proposed, as are 
a variety of other tasks, as I tried to show in the playground.

What’s being proposed now is deliberately short of solving every need—the 
additions would handle the hard stuff (correct and safe generation of integers 
and floating-points, along with shuffling collections) and lay the groundwork 
for other libraries to take things farther (by establishing the 
RandomNumberGenerator, a default generator, and a pattern for their use).

Speaking of GameplayKit, you can make GKRandomSource conform to 
RandomNumberGenerator in an extension, making all the GK... sources generators. 
If you’re already depending on those random sources, you’d still have access to 
them with the proposed model.

Nate

> Thanks,
> Jon
> 
> 
> 
>> On Jan 12, 2018, at 5:11 AM, Letanyan Arumugam  wrote:
>> 
>> Nate’s design follows a consistent idea of getting a random value from some 
>> set of values. Adding the static method random() to a type essentially 
>> creates an implicit set which you yourself said leads to inconsistency 
>> (Double/Int). Secondly I don’t see why random(in:) should be added when it 
>> is just a different spelling for what is already provided. If my second 
>> statement is incorrect and there’s something I’m missing please correct me?
>> 
>> I think that consistency outweighs the random trapping inconsistency, 
>> however I would actually be fine if random returned an optional. Though the 
>> way random is used would likely lead to less opportunities for a trap than 
>> the other methods you mention. 
>> 
>> 
>> Letanyan
>> 
>>> On 12 Jan 2018, at 04:39, Alejandro Alonso  wrote:
>>> 
>>> If anything, Nate’s design is inconsistent as properties like `.first` and 
>>> `.last` return an optional, and methods like `.min()` and `.max()` return 
>>> an optional as well. Having `.random()` on ranges be an exception and 
>>> return non optionals are inconsistent with other collection facilities, and 
>>> with other collections that aren’t ranges that return optionals on 
>>> `.random()`.
>>> 
>>> - Alejandro
>>> 
 On Jan 11, 2018, 12:06 PM -0600, Letanyan Arumugam via swift-evolution 
 , wrote:
 This is really cool and seems 

Re: [swift-evolution] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread John McCall via swift-evolution
> On Jan 12, 2018, at 6:47 PM, Dave DeLong via swift-evolution 
>  wrote:
> 
> I feel like we’re talking past each other right now, so I’ll give a concrete 
> example:
> 
> Let’s say MyAwesomeFramework.framework defines this enum:
> 
> enum Access {
>   case none
>   case readOnly
>   case readWrite
> }
> 
> This framework is compiled, built, and embedded in to 
> MyAwesomeApp.app/Frameworks.
> 
> Somewhere in MyAwesomeApp, I switch on the access of a thing:
> 
> switch aThing.access {
>   case .none: break
>   case .readOnly: print(“I can read”)
>   case .readWrite: print(“I can write”)
> }
> 
> Let’s here observe some things:
> 
> 1️⃣ the enum “Access” is *not* declared as frozen, because it might get a new 
> case in the future (such as “writeOnly”)
> 2️⃣ the switch on an Access value is exhaustive
> 3️⃣ under the proposal, I’m going to get a warning on the switch because 
> Access is not frozen. That warning will tell me to add “unknown case:”
> 
> This is the problem I’m talking about. The warning I’ll get on the switch is 
> technically correct (I’m switching on a non-frozen enum), but semantically 
> incorrect (it’s ok because the framework CANNOT introduce a new case without 
> recompilation of the switch statement, because they are packaged together). 
> The compiler will tell me to add an unknown case statement to the switch when 
> it will be completely unnecessary. Since MyAwesomeFramework.framework is 
> embedded in my app, there is no binary compatibility concern here, and I will 
> never come across an unknown case.
> 
> I think this false positive is going to be very common, because lots of 
> people embed frameworks in their apps, and those frameworks declare enums. 
> Until the frameworks are updated to freeze the enums, the app authors will be 
> forced to add “unknown case” statements to their switches for places where it 
> is entirely unnecessary. (This brings up the question: does this proposal 
> include a fixit to remove an “unknown case” statement from switches where 
> it’s unnecessary?)
> 
> So, what I’m asking for is a part in the proposal (likely under “Future 
> Directions”) where you acknowledge this problem (the “false positive problem 
> for embedded modules”) and list it as something we’d like to solve in the 
> future.

I agree that it's important to discuss this in the proposal.

I think the point that Jordan is trying to make is that this kind of resilience 
problem can come up as a source-compatibility issue, not just a 
binary-compatibility issue.  Of course an app can be version-locked to its 
non-OS dependencies and nobody will care.  However, it's problematic for a 
library to be version-locked to its dependencies even if both the library and 
its dependencies are only ever distributed as source: you ought to be able to 
upgrade the dependencies without having to revise all the dependent libraries.  
If our library ecosystem doesn't let you pull a new version of BaseLib without 
simultaneously pulling new versions of everything else you use that requires 
BaseLib — or, alternatively, hand-fixing them all yourself if that library 
hasn't gotten updated yet — that's a pretty frustrating experience.

Conversely, an app ought to be able to be version-locked to its non-OS 
dependencies whether they're binaries or source.  So this really has almost 
nothing to do with binary vs. source distribution and everything to do with 
whether version-locking makes sense for a specific project.

John.

> 
> Dave
> 
>> On Jan 12, 2018, at 4:27 PM, Dave DeLong via swift-evolution 
>> > wrote:
>> 
>>> On Jan 12, 2018, at 4:22 PM, Jordan Rose >> > wrote:
>>> 
>>> No, it's "Revision-locked imports”.
>> 
>> Ah, yeah I can see how the rev-locked imports is a variation on “I’ve copied 
>> in this library”.
>> 
>>> A source-breaking change is one in which updating the library at compile 
>>> time will break clients at compile time. That's relevant for libraries 
>>> distributed with an app as well as for libraries that are part of the OS. 
>>> You may not care, but I do, and I think other package authors will too.
>> 
>> ??? Of course I care about getting warnings when I’ve chosen to update a 
>> dependency. Where did I ever imply otherwise?
>> 
>> What I’m saying is that if I’m embedding such a library in my app *now* and 
>> I’m importing it *now*, I shouldn’t get a warning about handling unknown 
>> cases off non-frozen enums *now*. 
>> 
>> And if I am going to see such warnings now, then the document needs to 
>> include how those “false positives” will be eliminated in the future.
>> 
>> Dave
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> 

Re: [swift-evolution] 100% bikeshed topic: DictionaryLiteral

2018-01-12 Thread Ted Kremenek via swift-evolution
Hi Xiaodi,

It’s an interesting suggestion.  My inclination is that seeding prototype APIs 
would be better done via source package managers, and not as binary frameworks. 
 But they are two different approaches to the same problem and it is an 
interesting idea.

I’d like to first focus, however, on the utility of having such a separate 
dylib for the purposes of sunsetting APIs.

Ted

> On Jan 12, 2018, at 6:02 PM, Xiaodi Wu  wrote:
> 
> One point to bring up is that what you call libswiftCoreDeprecated.dylib can 
> be the place that future APIs live until they’re sufficiently mature.
> 
> I highly doubt that additions to the Swift standard library past 5.0 will all 
> be fully baked on arrival, and having everything carved into stone the moment 
> it’s added seems unwise.
> 
> Against this consideration the benefit of enabling a more stable set and a 
> less stable set of APIs seems to outweigh the start-up time consideration. 
> Yes, the implication is that most Swift apps will have to incur an increased 
> runtime cost.
> On Fri, Jan 12, 2018 at 18:43 Ted Kremenek via swift-evolution 
> > wrote:
> Hi Chris,
> 
> Instead of responding to each of your point bit-by-bit, I’ll try a different 
> tactic to explain my reasoning — which may be wrong — by explaining how I see 
> things top down with the tradeoffs they incur.  I’m going to say a bunch of 
> things I know *you* know, but others are on this thread and I’ll state things 
> for end-to-end clarity.
> 
> It seems to me that we are talking about two possible scenarios: (1) the 
> status quo of keeping everything in libswiftCore.dylib or (2) splitting 
> libswiftCore.dylib into two dylibs, one which includes some of the 
> “deprecated” APIs.  I’ll enumerate what I think are the tradeoffs/benefits we 
> will see with both scenarios, and see where the mismatch in our “talking past 
> each other” is happening.
> 
> In both cases (A) and (B), with ABI stability the Standard Library has the 
> option to ship in the OS.  Thus applications using Swift on (say) iOS would 
> no longer need to include libswiftCore.dylib in the app when running on an OS 
> that shipped with the Standard Library.
> 
> With that in mind, here are the tradeoffs as I see between scenarios (A) and 
> (B):
> 
> 
> (A) Status quo: Keep shipping everything in libswiftCore.dylib
> 
> - Applications running on an OS with the Standard Library would no longer 
> have *any* of the currently libswift*.dylib’s embedded inside the application 
> bundle because they would just use the one in the OS.
> 
> - One benefit of using libswift*.dylibs in the OS as opposed to those 
> embedded inside the app bundle is that there is a non-neglible startup time 
> improvement, as the code signing verification that happens when an app 
> launches would be faster as it would not need to verify each of these dylibs 
> that were previously embedded in the app.  We should consider this the new 
> baseline for app startup time for an app running on an OS with an ABI stable 
> Standard Library.
> 
> - We continue to support the deprecated APIs for some time, possibly 
> indefinitely, even when better alternatives come around.
> 
> (B) Split libswiftCore.dylib into two dylibs, one that gets embedded in the 
> app bundle
> 
> In the second scenario, we split out the deprecated APIs into a separate 
> dylib, say libswiftCoreDeprecated.dylib.  That solution would have the 
> following characteristics:
> 
> - Like scenario (A), app bundles would not need to embed libswiftCore.dylib 
> when running on an OS that had an ABI-stable Standard Library.
> 
> - Compared to scenario (A), the OS shipping the Standard Library would have a 
> slightly smaller libswiftCore.dylib that didn’t carry the bits for the 
> deprecated APIs.  This would be a benefit in the code size for the OS, but 
> not for the app itself.
> 
> - Any app using a deprecated API we put into libswiftCoreDeprecated.dylib 
> (e.g., Mirrors) would need to embed libswiftCoreDeprecated.dylib inside their 
> app bundle.  Compared to the new baseline I mentioned in (A), such apps would 
> have a launch time regression once they started using any API in the 
> libSwiftCoreDeprecated.dylib because code signing would need to verify the 
> dylib, just like it does today with the libswiftCore.dylib that is embedded 
> in every application.  They would also be slightly larger because the app 
> bundle has the burden of hosting libswiftCoreDeprecated.dylib, instead of 
> compared to scenario (A) where the implementations of the deprecated APIs are 
> hosted by the libswiftCore.dylib that ships in the OS.
> 
> - Because of binary compatibility concerns, after Swift 5 we would *never* be 
> able to “take out” any further APIs from libswiftCore.dylib and put them in 
> libswiftCoreDeprecated.dylib.  This factorization can only happen once.
> 
> - There is some slight additional complexity 

Re: [swift-evolution] [Proposal] Revamp the playground quicklook APIs

2018-01-12 Thread Connor Wakamo via swift-evolution


> On Jan 11, 2018, at 11:51 PM, Chris Lattner  wrote:
> 
> On Jan 11, 2018, at 11:22 AM, Connor Wakamo  > wrote:
 I don’t think we can change this to return `Any` instead of `Any?`. I 
 think there are potentially cases where a developer might want to 
 selectively opt-in to this behavior.
>>> 
>>> Which cases?  How important are they?
>> 
>> I can think of a couple of cases where this could be useful.
>> 
>> The first is an enum. Extending Riley’s example from earlier in the thread:
>> 
>>  enum MyUnion {
>>  case string(String)
>>  case image(UIImage)
>>  case intPair(Int, Int)
>>  case none
>>  }
>> 
>> This enum might want to present the string and image cases as strings and 
>> images, but treat the intPair and none cases the “default” way for the enum. 
>> This is probably not the most compelling example as there is a workaround — 
>> return a second enum or other structured type from playgroundRepresentation 
>> — but that feels not great.
> 
> IMO, this is sugaring something that doesn’t need to be sugared.  There are 
> simple solutions to this problem without complicating the design of your 
> feature.  The few people who care about this can write it out long hand.

Agreed.

>> The second case, and the one I’m more worried about, is subclassing. If, for 
>> instance, you have the following:
>> 
>>  class FooView: UIView, CustomPlaygroundRepresentable {
>>  var playgroundRepresentation: Any {
>>  return “A string describing this view"
>>  }
>>  }
>> 
>>  class BarView: FooView {
>>  override var playgroundRepresentation: Any {
>>  // BarView instances wanted to be logged as themselves, 
>> but there’s no way to express that
>>  return ???
>>  }
>>  }
>> 
>> There’s nothing that BarView can do to ensure it gets logged like a view 
>> because FooView declared a conformance to CustomPlaygroundRepresentable.
> 
> I really don’t understand this.  FooView declares that it conforms, and it 
> provides a “playgroundRepresentation” member.  Cool for FooView.
> 
> BarView comes around and overrides FooView’s implementation.  They don’t have 
> to conform, because it *isa* FooView, so of course it conforms.  If it wants 
> to customize its presentation, it overrides its  “playgroundRepresentation” 
> method and it… just works.  If it conditionally wants the FooView 
> representation for some reason, it can even call 
> “super.playgroundRepresentation”.  What’s the problem?  This seems ideal to 
> me.

The issue is that there’s no way for `BarView` to recover the default 
playground representation which `UIView` and its subclasses get. For a 
`UIView`, the PlaygroundLogger library renders an image of the view and 
packages that up in a log entry. If `BarView` wants that instead of `FooView`’s 
custom representation, there’s no way for it to request it.

That being said, I think I’m convinced that this is enough of an edge case that 
shouldn’t complicate the design of the protocol. So in my updated proposal I’ll 
be going with:

protocol CustomPlaygroundConvertible {
var playgroundDescription: Any { get }
}

If we find out that this isn’t as much of an edge case as thought, we can add a 
type like `DefaultPlaygroundRepresentation` to PlaygroundSupport which 
would signal to the playground logger that it should log the wrapped type but 
without considering a `CustomPlaygroundConvertible` conformance.

 I also don’t think that `Optional` would get a conditional conformance to 
 this. I’m not proposing that any standard library or corelibs types gain 
 conformances to this protocol. Instead, it’s up to a playground logger 
 (such as PlaygroundLogger in swift-xcode-playground-support 
 ) to recognize 
 these types and handle them accordingly. The playground logger would look 
 through the `Optional` so that this would effectively be true, but ideally 
 the log data generated by a logger would indicate that it was wrapped by 
 `Optional.some`.
>>> 
>>> Why not?  I understand that that is how the old algorithm worked, but it 
>>> contained a lot of special case hacks due to the state of Swift 1 :-).  
>>> This is a chance to dissolve those away.
>> 
>> It’s a feature that Optional (and other standard library/corelibs/OS types) 
>> don’t conform to CustomPlaygroundRepresentable. In my mind, it’s the role of 
>> the PlaygroundLogger library to understand the types for which it wishes to 
>> generate an opaque representation instead of the standard/fallback 
>> structured representation. So Optional, String, Int, UIColor, NSView, etc. 
>> don’t themselves conform to CustomPlaygroundRepresentable — they’re not 
>> customizing their 

Re: [swift-evolution] 100% bikeshed topic: DictionaryLiteral

2018-01-12 Thread Xiaodi Wu via swift-evolution
One point to bring up is that what you call libswiftCoreDeprecated.dylib
can be the place that future APIs live until they’re sufficiently mature.

I highly doubt that additions to the Swift standard library past 5.0 will
all be fully baked on arrival, and having everything carved into stone the
moment it’s added seems unwise.

Against this consideration the benefit of enabling a more stable set and a
less stable set of APIs seems to outweigh the start-up time consideration.
Yes, the implication is that most Swift apps will have to incur an
increased runtime cost.
On Fri, Jan 12, 2018 at 18:43 Ted Kremenek via swift-evolution <
swift-evolution@swift.org> wrote:

> Hi Chris,
>
> Instead of responding to each of your point bit-by-bit, I’ll try a
> different tactic to explain my reasoning — which may be wrong — by
> explaining how I see things top down with the tradeoffs they incur.  I’m
> going to say a bunch of things I know *you* know, but others are on this
> thread and I’ll state things for end-to-end clarity.
>
> It seems to me that we are talking about two possible scenarios: (1) the
> status quo of keeping everything in libswiftCore.dylib or (2) splitting
> libswiftCore.dylib into two dylibs, one which includes some of the
> “deprecated” APIs.  I’ll enumerate what I think are the tradeoffs/benefits
> we will see with both scenarios, and see where the mismatch in our “talking
> past each other” is happening.
>
> In both cases (A) and (B), with ABI stability the Standard Library has the
> option to ship in the OS.  Thus applications using Swift on (say) iOS would
> no longer need to include libswiftCore.dylib in the app when running on an
> OS that shipped with the Standard Library.
>
> With that in mind, here are the tradeoffs as I see between scenarios (A)
> and (B):
>
>
> (A) Status quo: Keep shipping everything in libswiftCore.dylib
>
> - Applications running on an OS with the Standard Library would no longer
> have *any* of the currently libswift*.dylib’s embedded inside the
> application bundle because they would just use the one in the OS.
>
> - One benefit of using libswift*.dylibs in the OS as opposed to those
> embedded inside the app bundle is that there is a non-neglible startup time
> improvement, as the code signing verification that happens when an app
> launches would be faster as it would not need to verify each of these
> dylibs that were previously embedded in the app.  We should consider this
> the new baseline for app startup time for an app running on an OS with an
> ABI stable Standard Library.
>
> - We continue to support the deprecated APIs for some time, possibly
> indefinitely, even when better alternatives come around.
>
> (B) Split libswiftCore.dylib into two dylibs, one that gets embedded in
> the app bundle
>
> In the second scenario, we split out the deprecated APIs into a separate
> dylib, say libswiftCoreDeprecated.dylib.  That solution would have the
> following characteristics:
>
> - Like scenario (A), app bundles would not need to embed
> libswiftCore.dylib when running on an OS that had an ABI-stable Standard
> Library.
>
> - Compared to scenario (A), the OS shipping the Standard Library would
> have a slightly smaller libswiftCore.dylib that didn’t carry the bits for
> the deprecated APIs.  This would be a benefit in the code size for the OS,
> but not for the app itself.
>
> - Any app using a deprecated API we put into libswiftCoreDeprecated.dylib
> (e.g., Mirrors) would need to embed libswiftCoreDeprecated.dylib inside
> their app bundle.  Compared to the new baseline I mentioned in (A), such
> apps would have a launch time regression once they started using any API in
> the libSwiftCoreDeprecated.dylib because code signing would need to verify
> the dylib, just like it does today with the libswiftCore.dylib that is
> embedded in every application.  They would also be slightly larger because
> the app bundle has the burden of hosting libswiftCoreDeprecated.dylib,
> instead of compared to scenario (A) where the implementations of the
> deprecated APIs are hosted by the libswiftCore.dylib that ships in the OS.
>
> - Because of binary compatibility concerns, after Swift 5 we would *never*
> be able to “take out” any further APIs from libswiftCore.dylib and put them
> in libswiftCoreDeprecated.dylib.  This factorization can only happen once.
>
> - There is some slight additional complexity added to the compiler and
> build system to support this spit of the Standard Library into multiple
> dylibs.  It’s not a huge concern but it does exist and it is not free both
> in terms of implementing and maintaining.
>
> - We continue to support the deprecated APIs for some time, possibly
> indefinitely, even when better alternatives come around.  We *may* be able
> to completely sunset these APIs by having a future version of the Swift
> compiler simply refuse to build projects that use the deprecated (now
> obsoleted) APIs.  At that point, these apps need to move to using 

Re: [swift-evolution] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Matthew Johnson via swift-evolution

> On Jan 12, 2018, at 6:31 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> I’m definitely in the error camp, but I will go along with a warning if 
> everyone feels that is better.

I see advantages both ways.  The fact that the error approach generalizes much 
cleaner is definitely a plus.  

The primary downside to that approach is losing the ability to rebuild with the 
same version of a source dependency that has used #unkown when matching a 
non-frozen enum vended by a common dependency to which a case has been added 
since the source dependency was written.  Requiring this behavior can be viewed 
as a pretty significant downside.  It tightens the coupling between versions of 
dependencies.  This can make it difficult to update dependencies in a large 
project.  The warning approach allows people to opt-in to this behavior by 
treating warnings as errors without requiring everyone to make the same 
tradeoff.

It’s really a tough tradeoff.

> 
> Thanks,
> Jon
> 
>> On Jan 12, 2018, at 3:08 PM, Jordan Rose via swift-evolution 
>>  wrote:
>> 
>> Okay, I went back to `unknown case` in the proposal, but mentioned Chris's 
>> point very specifically: if the compiler emits an error, we should go with 
>> `case #unknown` instead. (I'm very strongly in the "warning" camp, though.)
>> 
>> I think the revised proposal is in good shape! 
>> (https://github.com/apple/swift-evolution/pull/777) I think I've addressed 
>> everyone's feedback either in the proposal or on-list, if not necessarily 
>> convinced them. If there are no other major comments I'll let Ted know that 
>> it's ready to re-run on Monday.
>> 
>> Jordan
>> ___
>> 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] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Rex Fenley via swift-evolution
Hey Jordan, coming into this a bit late, but it seems like `case #unknown`
is the more flexible syntax regardless of warning or error. If typed errors
are added then it would fall cleanly into catch pattern matching as well it
sounds like. Any thoughts there?

And for the record I'm slightly in favor of an error on unknown matches.
I'm just not sure that breaking source compatibility has been an issue with
enums thus far. It'd be my own preference to throw an error if I intend for
a type to be exhaustively matched, though I can definitely be ok with just
a warning too.

Okay, I went back to `unknown case` in the proposal, but mentioned Chris's
> point very specifically: if the compiler emits an error, we should go with
> `case #unknown` instead. (I'm very strongly in the "warning" camp, though.)



I think the revised proposal is in good shape! (
> https://github.com/apple/swift-evolution/pull/777) I think I've addressed
> everyone's feedback either in the proposal or on-list, if not necessarily
> convinced them. If there are no other major comments I'll let Ted know that
> it's ready to re-run on Monday. Jordan


-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 
 |  FOLLOW
US   |  LIKE US

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


[swift-evolution] [Review][returned for revision] SE 0192 - Non-Exhaustive Enums

2018-01-12 Thread Ted Kremenek via swift-evolution
The review of "SE 0192 - Non-Exhaustive Enums” had extensive discussion and has 
been returned for revision.

The proposal author, Jordan Rose, is working on a revised proposal that 
includes:

- Alterations to the naming of the attributes.
- New affordances for how switch statements work with non-exhaustive enums.

There will be a second round of review, but there is active discussion 
considering the latter point right now on swift-evolution on the thread 
"Handling unknown cases in enums”:

  
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20180108/042604.html
 


I encourage anyway interested in that topic to follow/participate in that 
thread.

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


Re: [swift-evolution] 100% bikeshed topic: DictionaryLiteral

2018-01-12 Thread Ted Kremenek via swift-evolution
Hi Chris,

Instead of responding to each of your point bit-by-bit, I’ll try a different 
tactic to explain my reasoning — which may be wrong — by explaining how I see 
things top down with the tradeoffs they incur.  I’m going to say a bunch of 
things I know *you* know, but others are on this thread and I’ll state things 
for end-to-end clarity.

It seems to me that we are talking about two possible scenarios: (1) the status 
quo of keeping everything in libswiftCore.dylib or (2) splitting 
libswiftCore.dylib into two dylibs, one which includes some of the “deprecated” 
APIs.  I’ll enumerate what I think are the tradeoffs/benefits we will see with 
both scenarios, and see where the mismatch in our “talking past each other” is 
happening.

In both cases (A) and (B), with ABI stability the Standard Library has the 
option to ship in the OS.  Thus applications using Swift on (say) iOS would no 
longer need to include libswiftCore.dylib in the app when running on an OS that 
shipped with the Standard Library.

With that in mind, here are the tradeoffs as I see between scenarios (A) and 
(B):


(A) Status quo: Keep shipping everything in libswiftCore.dylib

- Applications running on an OS with the Standard Library would no longer have 
*any* of the currently libswift*.dylib’s embedded inside the application bundle 
because they would just use the one in the OS.

- One benefit of using libswift*.dylibs in the OS as opposed to those embedded 
inside the app bundle is that there is a non-neglible startup time improvement, 
as the code signing verification that happens when an app launches would be 
faster as it would not need to verify each of these dylibs that were previously 
embedded in the app.  We should consider this the new baseline for app startup 
time for an app running on an OS with an ABI stable Standard Library.

- We continue to support the deprecated APIs for some time, possibly 
indefinitely, even when better alternatives come around.

(B) Split libswiftCore.dylib into two dylibs, one that gets embedded in the app 
bundle

In the second scenario, we split out the deprecated APIs into a separate dylib, 
say libswiftCoreDeprecated.dylib.  That solution would have the following 
characteristics:

- Like scenario (A), app bundles would not need to embed libswiftCore.dylib 
when running on an OS that had an ABI-stable Standard Library.

- Compared to scenario (A), the OS shipping the Standard Library would have a 
slightly smaller libswiftCore.dylib that didn’t carry the bits for the 
deprecated APIs.  This would be a benefit in the code size for the OS, but not 
for the app itself.

- Any app using a deprecated API we put into libswiftCoreDeprecated.dylib 
(e.g., Mirrors) would need to embed libswiftCoreDeprecated.dylib inside their 
app bundle.  Compared to the new baseline I mentioned in (A), such apps would 
have a launch time regression once they started using any API in the 
libSwiftCoreDeprecated.dylib because code signing would need to verify the 
dylib, just like it does today with the libswiftCore.dylib that is embedded in 
every application.  They would also be slightly larger because the app bundle 
has the burden of hosting libswiftCoreDeprecated.dylib, instead of compared to 
scenario (A) where the implementations of the deprecated APIs are hosted by the 
libswiftCore.dylib that ships in the OS.

- Because of binary compatibility concerns, after Swift 5 we would *never* be 
able to “take out” any further APIs from libswiftCore.dylib and put them in 
libswiftCoreDeprecated.dylib.  This factorization can only happen once.

- There is some slight additional complexity added to the compiler and build 
system to support this spit of the Standard Library into multiple dylibs.  It’s 
not a huge concern but it does exist and it is not free both in terms of 
implementing and maintaining.

- We continue to support the deprecated APIs for some time, possibly 
indefinitely, even when better alternatives come around.  We *may* be able to 
completely sunset these APIs by having a future version of the Swift compiler 
simply refuse to build projects that use the deprecated (now obsoleted) APIs.  
At that point, these apps need to move to using the newer API alternatives, or 
not upgrade to using a new Swift compiler.


With these points in mind, both scenarios are (by construction) very similar.  
Scenario (B) potentially provides a bit more flexibility in outright sunsetting 
deprecated APIs down the road — but only the APIs we deem today should be on 
that path. In the future when we decide to deprecate APIs in the Standard 
Library we will need to follow the same kind of deprecation-and-obsoletion path 
as other binary frameworks in macOS/iOS, which may mean keeping API 
implementations around for a very long time just for the purpose of binary 
compatibility.

If you agree with me up to this point, to me this boils down to a tradeoff of 
some slightly increased opportunity to sunset some APIs in the 

Re: [swift-evolution] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Jonathan Hull via swift-evolution
I’m definitely in the error camp, but I will go along with a warning if 
everyone feels that is better.

Thanks,
Jon

> On Jan 12, 2018, at 3:08 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> Okay, I went back to `unknown case` in the proposal, but mentioned Chris's 
> point very specifically: if the compiler emits an error, we should go with 
> `case #unknown` instead. (I'm very strongly in the "warning" camp, though.)
> 
> I think the revised proposal is in good shape! 
> (https://github.com/apple/swift-evolution/pull/777) I think I've addressed 
> everyone's feedback either in the proposal or on-list, if not necessarily 
> convinced them. If there are no other major comments I'll let Ted know that 
> it's ready to re-run on Monday.
> 
> Jordan
> ___
> 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

2018-01-12 Thread Jonathan Hull via swift-evolution

> On Jan 12, 2018, at 4:24 PM, Jonathan Hull  wrote:
> 
> Or what if I want an effect where it randomly fades in letters from a String.

Just to explain this example further.  I ran into this issue when trying to use 
arc4random to do this.  The eye is really sensitive to patterns in cases like 
this where it is represented visually.  I had to create my own RandomSource 
(see previous email) with a generator designed to make things less random (in a 
way that feels more random to the eye) to make this look ok. ___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2018-01-12 Thread Jonathan Hull via swift-evolution
I think we have different definitions of consistency.  I am fine with the 
ergonomics of (0…100).random() as a convenience, but it really worries me here 
that everything is special cased.  Special cased things are fine for individual 
projects, but not the standard library.  We should make sure that the design is 
flexible and extensible, and that comes in part from having a consistent 
interface.

Also, as I said before, we really shouldn’t be doing these crazy contortions to 
avoid ‘random() % 100’.  Instead we should look for that pattern and issue with 
a warning + fixit to change it to random(in:).  I think that will be much more 
effective in actually changing the behavior in the long run.

Finally, tying everything to Range is extremely limiting.  I understand if we 
don’t want to add other types to the standard library, but I should be able to 
build on what we add to do it myself without having to reinvent the wheel for 
each type.  It is important to have a consistent story for these things 
(including multi-dimensional types) so that they can interoperate.

We really should be looking at GamePlayKit more for design inspiration.  There 
are several use-cases there that are being blatantly ignored in this 
discussion.  For example, what if I want to randomly generate a game world 
(e.g. The square from The Battle For Polytopia” formerly “SuperTribes”)?  Or 
what if I want an effect where it randomly fades in letters from a String.  
(…).random() will be completely inadequate for these things.

Thanks,
Jon



> On Jan 12, 2018, at 5:11 AM, Letanyan Arumugam  wrote:
> 
> Nate’s design follows a consistent idea of getting a random value from some 
> set of values. Adding the static method random() to a type essentially 
> creates an implicit set which you yourself said leads to inconsistency 
> (Double/Int). Secondly I don’t see why random(in:) should be added when it is 
> just a different spelling for what is already provided. If my second 
> statement is incorrect and there’s something I’m missing please correct me?
> 
> I think that consistency outweighs the random trapping inconsistency, however 
> I would actually be fine if random returned an optional. Though the way 
> random is used would likely lead to less opportunities for a trap than the 
> other methods you mention. 
> 
> 
> Letanyan
> 
>> On 12 Jan 2018, at 04:39, Alejandro Alonso > > wrote:
>> 
>> If anything, Nate’s design is inconsistent as properties like `.first` and 
>> `.last` return an optional, and methods like `.min()` and `.max()` return an 
>> optional as well. Having `.random()` on ranges be an exception and return 
>> non optionals are inconsistent with other collection facilities, and with 
>> other collections that aren’t ranges that return optionals on `.random()`.
>> 
>> - Alejandro
>> 
>> On Jan 11, 2018, 12:06 PM -0600, Letanyan Arumugam via swift-evolution 
>> >, wrote:
>>> This is really cool and seems very powerful. However I don’t think we 
>>> should sacrifice consistency for extendability. Especially when the 
>>> extendability would not be what most people need. 
>>> 
>>> What I am basically trying to say is that. I think the proposals current 
>>> design direction fits better in a Random library rather than the Standard 
>>> Library. And Nate’s design more directly addresses the motivating points of 
>>> the proposal.
>>> 
>>> Letanyan
>>> 
 
 Sure. Small disclaimer that this was originally written back in the Swift 
 1~2 days, so it is overdue for a simplifying rewrite.
 
 Also, I should point out that the term “Source” has a special meaning in 
 my code.  It basically means that something will provide an ~infinite 
 collection of values of a type T.   I have what I call a “ConstantSource” 
 which just wraps a T and gives it back when asked.  But then I have a 
 bunch of other “sources" which let you create repeating patterns and do 
 deferred calculations and things like that.  Finally I have a 
 “RandomSource” which is part of what started this discussion.  You set up 
 a RandomSource with a set of constraints, and then it gives you random 
 values of T that adhere to those constraints (e.g. colors with a range of 
 hues but the same saturation) whenever you ask for them.
 
 This is really useful for doing things like graphic effects because, for 
 example, I can ask for a source of colors and a source of line widths and 
 then get out a large variety of interesting patterns from the same 
 algorithm.  I can make simple stripes with ConstantSources, or I can make 
 repeating patterns of lines with repeating sources, or I can have random 
 colors which look good together by using a RandomSource.  I can take a 
 BezierPath and make it look hand-drawn by breaking it into a bunch of 

Re: [swift-evolution] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Dave DeLong via swift-evolution
I feel like we’re talking past each other right now, so I’ll give a concrete 
example:

Let’s say MyAwesomeFramework.framework defines this enum:

enum Access {
case none
case readOnly
case readWrite
}

This framework is compiled, built, and embedded in to 
MyAwesomeApp.app/Frameworks.

Somewhere in MyAwesomeApp, I switch on the access of a thing:

switch aThing.access {
case .none: break
case .readOnly: print(“I can read”)
case .readWrite: print(“I can write”)
}

Let’s here observe some things:

1️⃣ the enum “Access” is *not* declared as frozen, because it might get a new 
case in the future (such as “writeOnly”)
2️⃣ the switch on an Access value is exhaustive
3️⃣ under the proposal, I’m going to get a warning on the switch because Access 
is not frozen. That warning will tell me to add “unknown case:”

This is the problem I’m talking about. The warning I’ll get on the switch is 
technically correct (I’m switching on a non-frozen enum), but semantically 
incorrect (it’s ok because the framework CANNOT introduce a new case without 
recompilation of the switch statement, because they are packaged together). The 
compiler will tell me to add an unknown case statement to the switch when it 
will be completely unnecessary. Since MyAwesomeFramework.framework is embedded 
in my app, there is no binary compatibility concern here, and I will never come 
across an unknown case.

I think this false positive is going to be very common, because lots of people 
embed frameworks in their apps, and those frameworks declare enums. Until the 
frameworks are updated to freeze the enums, the app authors will be forced to 
add “unknown case” statements to their switches for places where it is entirely 
unnecessary. (This brings up the question: does this proposal include a fixit 
to remove an “unknown case” statement from switches where it’s unnecessary?)

So, what I’m asking for is a part in the proposal (likely under “Future 
Directions”) where you acknowledge this problem (the “false positive problem 
for embedded modules”) and list it as something we’d like to solve in the 
future.

Dave

> On Jan 12, 2018, at 4:27 PM, Dave DeLong via swift-evolution 
>  wrote:
> 
>> On Jan 12, 2018, at 4:22 PM, Jordan Rose > > wrote:
>> 
>> No, it's "Revision-locked imports”.
> 
> Ah, yeah I can see how the rev-locked imports is a variation on “I’ve copied 
> in this library”.
> 
>> A source-breaking change is one in which updating the library at compile 
>> time will break clients at compile time. That's relevant for libraries 
>> distributed with an app as well as for libraries that are part of the OS. 
>> You may not care, but I do, and I think other package authors will too.
> 
> ??? Of course I care about getting warnings when I’ve chosen to update a 
> dependency. Where did I ever imply otherwise?
> 
> What I’m saying is that if I’m embedding such a library in my app *now* and 
> I’m importing it *now*, I shouldn’t get a warning about handling unknown 
> cases off non-frozen enums *now*. 
> 
> And if I am going to see such warnings now, then the document needs to 
> include how those “false positives” will be eliminated in the future.
> 
> Dave
> ___
> 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] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Dave DeLong via swift-evolution
> On Jan 12, 2018, at 4:22 PM, Jordan Rose  wrote:
> 
> No, it's "Revision-locked imports”.

Ah, yeah I can see how the rev-locked imports is a variation on “I’ve copied in 
this library”.

> A source-breaking change is one in which updating the library at compile time 
> will break clients at compile time. That's relevant for libraries distributed 
> with an app as well as for libraries that are part of the OS. You may not 
> care, but I do, and I think other package authors will too.

??? Of course I care about getting warnings when I’ve chosen to update a 
dependency. Where did I ever imply otherwise?

What I’m saying is that if I’m embedding such a library in my app *now* and I’m 
importing it *now*, I shouldn’t get a warning about handling unknown cases off 
non-frozen enums *now*. 

And if I am going to see such warnings now, then the document needs to include 
how those “false positives” will be eliminated in the future.

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


Re: [swift-evolution] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Jordan Rose via swift-evolution
No, it's "Revision-locked imports".

A source-breaking change is one in which updating the library at compile time 
will break clients at compile time. That's relevant for libraries distributed 
with an app as well as for libraries that are part of the OS. You may not care, 
but I do, and I think other package authors will too.

Jordan


> On Jan 12, 2018, at 15:20, Dave DeLong  wrote:
> 
> I assume you’re referring to this?
> Implicitly treat enums without binary compatibility concerns as @frozen
> 
> Several people questioned whether it was necessary to make this distinction 
> for libraries without binary compatibility concerns, i.e. those that are 
> shipped with their client apps. While there may be a need to do something to 
> handle enums shipped with Apple's OS SDKs, it's arguable whether this is 
> worth it for "source libraries", such as SwiftPM packages.
> 
> This question can be rephrased as "is adding a case to an enum a 
> source-breaking change?" 
> 
> 
> I don’t follow on how this is a source-breaking change.
> 
> Let’s say I’m writing an app “A” that embeds a module “M”, which defines and 
> enum “E”.
> 
> If E is frozen, the everything’s fine and all is well.
> If E is *not* frozen, then the compiler is going to force me to put in an 
> “unknown case”, because it has falsely concluded that E may change out from 
> underneath my app.
> 
> The will be a mistake on the compiler’s part. I do not need to include the 
> “unknown case” handler while enumerating on E, because there is no 
> possibility of ever getting an unknown enum value from M, because it is 
> statically copied in to my app and will never change.
> 
> Dave
> 
>> On Jan 12, 2018, at 4:16 PM, Jordan Rose > > wrote:
>> 
>> I included that, but also I again don't think that's the correct design. 
>> There's a case where that's useful, but that shouldn't be the default, and I 
>> don't think it's important enough to do in Swift 5.
>> 
>> Jordan
>> 
>> 
>>> On Jan 12, 2018, at 15:15, Dave DeLong >> > wrote:
>>> 
>>> Unless I’m missing something, this is still missing the discussion on being 
>>> able to treat all enums of internally-packaged libraries as frozen.
>>> 
>>> IE, that frozen vs unfrozen is only an issue for enums that come from 
>>> modules that are not packaged with your app.
>>> 
>>> Dave
>>> 
 On Jan 12, 2018, at 4:08 PM, Jordan Rose via swift-evolution 
 > wrote:
 
 Okay, I went back to `unknown case` in the proposal, but mentioned Chris's 
 point very specifically: if the compiler emits an error, we should go with 
 `case #unknown` instead. (I'm very strongly in the "warning" camp, though.)
 
 I think the revised proposal is in good shape! 
 (https://github.com/apple/swift-evolution/pull/777 
 ) I think I've 
 addressed everyone's feedback either in the proposal or on-list, if not 
 necessarily convinced them. If there are no other major comments I'll let 
 Ted know that it's ready to re-run on Monday.
 
 Jordan
 ___
 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] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Dave DeLong via swift-evolution
I assume you’re referring to this?
Implicitly treat enums without binary compatibility concerns as @frozen

Several people questioned whether it was necessary to make this distinction for 
libraries without binary compatibility concerns, i.e. those that are shipped 
with their client apps. While there may be a need to do something to handle 
enums shipped with Apple's OS SDKs, it's arguable whether this is worth it for 
"source libraries", such as SwiftPM packages.

This question can be rephrased as "is adding a case to an enum a 
source-breaking change?" 


I don’t follow on how this is a source-breaking change.

Let’s say I’m writing an app “A” that embeds a module “M”, which defines and 
enum “E”.

If E is frozen, the everything’s fine and all is well.
If E is *not* frozen, then the compiler is going to force me to put in an 
“unknown case”, because it has falsely concluded that E may change out from 
underneath my app.

The will be a mistake on the compiler’s part. I do not need to include the 
“unknown case” handler while enumerating on E, because there is no possibility 
of ever getting an unknown enum value from M, because it is statically copied 
in to my app and will never change.

Dave

> On Jan 12, 2018, at 4:16 PM, Jordan Rose  wrote:
> 
> I included that, but also I again don't think that's the correct design. 
> There's a case where that's useful, but that shouldn't be the default, and I 
> don't think it's important enough to do in Swift 5.
> 
> Jordan
> 
> 
>> On Jan 12, 2018, at 15:15, Dave DeLong > > wrote:
>> 
>> Unless I’m missing something, this is still missing the discussion on being 
>> able to treat all enums of internally-packaged libraries as frozen.
>> 
>> IE, that frozen vs unfrozen is only an issue for enums that come from 
>> modules that are not packaged with your app.
>> 
>> Dave
>> 
>>> On Jan 12, 2018, at 4:08 PM, Jordan Rose via swift-evolution 
>>> > wrote:
>>> 
>>> Okay, I went back to `unknown case` in the proposal, but mentioned Chris's 
>>> point very specifically: if the compiler emits an error, we should go with 
>>> `case #unknown` instead. (I'm very strongly in the "warning" camp, though.)
>>> 
>>> I think the revised proposal is in good shape! 
>>> (https://github.com/apple/swift-evolution/pull/777 
>>> ) I think I've addressed 
>>> everyone's feedback either in the proposal or on-list, if not necessarily 
>>> convinced them. If there are no other major comments I'll let Ted know that 
>>> it's ready to re-run on Monday.
>>> 
>>> Jordan
>>> ___
>>> 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] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Jordan Rose via swift-evolution
I included that, but also I again don't think that's the correct design. 
There's a case where that's useful, but that shouldn't be the default, and I 
don't think it's important enough to do in Swift 5.

Jordan


> On Jan 12, 2018, at 15:15, Dave DeLong  wrote:
> 
> Unless I’m missing something, this is still missing the discussion on being 
> able to treat all enums of internally-packaged libraries as frozen.
> 
> IE, that frozen vs unfrozen is only an issue for enums that come from modules 
> that are not packaged with your app.
> 
> Dave
> 
>> On Jan 12, 2018, at 4:08 PM, Jordan Rose via swift-evolution 
>>  wrote:
>> 
>> Okay, I went back to `unknown case` in the proposal, but mentioned Chris's 
>> point very specifically: if the compiler emits an error, we should go with 
>> `case #unknown` instead. (I'm very strongly in the "warning" camp, though.)
>> 
>> I think the revised proposal is in good shape! 
>> (https://github.com/apple/swift-evolution/pull/777) I think I've addressed 
>> everyone's feedback either in the proposal or on-list, if not necessarily 
>> convinced them. If there are no other major comments I'll let Ted know that 
>> it's ready to re-run on Monday.
>> 
>> Jordan
>> ___
>> 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] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Dave DeLong via swift-evolution
Unless I’m missing something, this is still missing the discussion on being 
able to treat all enums of internally-packaged libraries as frozen.

IE, that frozen vs unfrozen is only an issue for enums that come from modules 
that are not packaged with your app.

Dave

> On Jan 12, 2018, at 4:08 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> Okay, I went back to `unknown case` in the proposal, but mentioned Chris's 
> point very specifically: if the compiler emits an error, we should go with 
> `case #unknown` instead. (I'm very strongly in the "warning" camp, though.)
> 
> I think the revised proposal is in good shape! 
> (https://github.com/apple/swift-evolution/pull/777) I think I've addressed 
> everyone's feedback either in the proposal or on-list, if not necessarily 
> convinced them. If there are no other major comments I'll let Ted know that 
> it's ready to re-run on Monday.
> 
> Jordan
> ___
> 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] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Jordan Rose via swift-evolution
Okay, I went back to `unknown case` in the proposal, but mentioned Chris's 
point very specifically: if the compiler emits an error, we should go with 
`case #unknown` instead. (I'm very strongly in the "warning" camp, though.)

I think the revised proposal is in good shape! 
(https://github.com/apple/swift-evolution/pull/777) I think I've addressed 
everyone's feedback either in the proposal or on-list, if not necessarily 
convinced them. If there are no other major comments I'll let Ted know that 
it's ready to re-run on Monday.

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


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

2018-01-12 Thread Jonathan Hull via swift-evolution
We are doing crazy contortions to avoid the 'random % 100’ issue.  Why not just 
check for that pattern and issue a warning with a fixit to do it better?

I don’t think it is worth handicapping everything just to avoid this.

Thanks,
Jon
 
> On Jan 11, 2018, at 11:22 PM, Nate Cook via swift-evolution 
>  wrote:
> 
>> On Jan 11, 2018, at 9:17 PM, Alejandro Alonso > > wrote:
>> 
>> Sorry it takes me forever to respond! I finally got around to writing this! 
>> School really takes all my time x)
>> 
>> I have a few ideas on where we can go with this:
>> 
>> 1. I agree, we should ditch `Randomizable` as something like that should 
>> belong in a separate library or written by the user.
>> 
>> 2. I also agree we should ditch the associated type on 
>> `RandomNumberGenerator`. I think we can sacrifice 32 bit generators using 64 
>> bit ints to conform to the core team’s general use policy. This also makes 
>> default arguments for rngs possible which is a +1 for me!
>> 
>> I start to drift off from your design because `.random()` being an exception 
>> to ranges in that it’s inconsistent with other collection facilities and 
>> collection `.random()`. You make a few emails in the past that reference 
>> this as well. I think the right move is to have the static functions utilize 
>> the ranges to provide non optional types.
>> 
>> You wrote:
>> 
>> “
>> I see a couple points in favor of these static methods (or initializers) on 
>> the numeric types:
>> 
>> 1) The collection method will need to return an optional to match the 
>> semantics of existing methods (like min()). If this is the only method 
>> available, every time someone needs
>>  a random value in the range 1...10, they’ll need to unwrap the result (with 
>> either force unwrapping, which people will complain about, or some kind of 
>> conditional binding, which is its own problem). Even if the semantics are 
>> the same (trapping on an empty
>>  range), the user experience of using a non-optional method will be better.
>>  
>> 2) Floating-point ranges won’t get the collection method, so either we’ll 
>> have inconsistent APIs (random FP value is non-optional, random integer is 
>> optional) or we’ll make the
>>  FP API optional just to match. Both of those seem bad.
>> ”
>> 
>> I believe this is the direction we need to go to keep consistency with 
>> collection based methods by justifying `.random(in:)` on the numeric types. 
>> With that in mind, Ben made a comment a long while ago saying, “The
>>  one downside is that you’d have to write 0..> justification for a static property on one of the Integer protocols as 
>> shorthand for that.” I believe this makes it perfectly justifiable for 
>> `.random()` on numeric types. This also creates a consistency with 
>> `Bool.random()` making it justifiable for this as well. 
>> 
>> We can do all of this without `Randomizable` as well! Add extension methods 
>> on `FixedWidthInteger`, `BinaryFloatingPoint`, and `Bool`. These will be the 
>> methods that crash on an empty range, but we can precondition here to 
>> provide helpful debugging for developers. You made reference to users using 
>> the range based api for a safe alternative if they needed optionals.
>> 
>> ```
>> // Here you can use something more runtime oriented (such as an array count)
>> guard let x = (0 ..< 5).random() else {
>>  fatalError(“not going to happen")
>> }
>> ```
>> 
>> I’m not too sure if you’ve had a change of heart, but I think the following 
>> is justifiable if we remove `Randomizable`.
>> 
>> Sample Syntax:
>> ```
>> // Full Int width (shorthand for Int.random(in: .min … .max))
>> Int.random()
>> 
>> // random int from [0, 10)
>> Int.random(in: 0 ..< 10)
>> 
>> // random double from [0, 1) (Modulo isn’t an issue here!)
>> Double.random()
>> 
>> // random double from [0, .pi)
>> Double.random(in: 0 ..< .pi)
>> 
>> // random boolean
>> Bool.random()
>> ```
>> 
>> This seems very consistent to me. The only inconsistency is with 
>> `Int.random()` covering the full width, and `Double.random()` covering only 
>> `[0, 1)`, but to me this functionality is very precedented in many other 
>> languages. Also by removing `Randomizable`, other data types like `Data` 
>> don’t have to conform to a protocol, but can just add a random initializer 
>> that fits its needs.
>> 
>> I think now is when people will start saying, “Int.random() bad, modulo 
>> bias, no no” x)
>> I see the potential for error here, but logically I’m thinking that so many 
>> other languages have this feature and I wonder if you think they all did it 
>> wrong too and shouldn’t have done so. This type of behavior is found in C, 
>> C++, C#, Java, etc. I agree with Jonathon in that maybe we could suggest a 
>> warning/fixit in Xcode.
>> 
>> tl;dr - Remove `Randomizable`, remove associated type on 
>> `RandomNumberGenerator`, be consistent with `.random()` with other 
>> properties 

Re: [swift-evolution] [pitch] adding toggle to Bool

2018-01-12 Thread Anders Kierulf via swift-evolution
I also avoid using ! for negation when possible, and `toggle` or `invert` will 
be helpful, but in many cases I think the negative case is better expressed 
directly. For example, I find that using `nonEmpty` instead of !isEmpty makes 
the code easier to read: 

  extension String {
  var nonEmpty: Bool { return !self.isEmpty }
  }

  if !string.isEmpty { … }

  if string.isEmpty.inverted() { … }

  if string.nonEmpty { … }

For the case of `contains`, maybe define `lacks`?

  if !items.contains(item) { ... }

  if items.contains(item).inverted() { ... }

  if items.lacks(item) { ... }

Anders Kierulf

> On Jan 12, 2018, at 12:54 PM, Alejandro Martinez via swift-evolution 
>  wrote:
> 
> I wouldn't go as far as to ask to fade out ! but in all my code I end
> up doing == false just for readability. That ! knows who to hide
> himself too well :P
> 
> On Fri, Jan 12, 2018 at 10:13 AM, Adrian Zubarev via swift-evolution
>  wrote:
>> I’m not sure if this would be considered or not, but I would like if the
>> negation operator `!` would fade out.
>> 
>> If this is ever going to a review then I’d suggest that we add a pair of
>> functions, one mutating and the other non-mutating.
>> 
>> extension Bool {
>>  mutating func invert() {
>>self = !self
>>  }
>> 
>>  func inverted() {
>>return !self
>>  }
>> }
>> 
>> I’d rather use `inverted` instead of `!` because of the readability this
>> function provides.
>> 
>> if !items.contains(item) { ... }
>> 
>> if items.contains(item).inverted() { ... }
>> 
>> ——
>> 
>> I personally have some other extensions like:
>> 
>> extension Bool {
>>  @discardableResult
>>  func whenTrue(execute closure: () throws -> T) rethrows -> T? {
>>if self { return try closure() }
>>return nil
>>  }
>> 
>>  @discardableResult
>>  func whenFalse(execute closure: () throws -> T) rethrows -> T? {
>>if !self { return try closure() }
>>return nil
>>  }
>> }
>> 
>> But this is more a personal preference.
>> 
>> ——
>> 
>> That said, if the community is fine with the `invert/inverted` pair then I’d
>> say go for it ;)
>> 
>> Am 12. Januar 2018 um 09:14:22, Nate Cook via swift-evolution
>> (swift-evolution@swift.org) schrieb:
>> 
>> 
>> On Jan 12, 2018, at 12:15 AM, Chris Eidhof via swift-evolution
>>  wrote:
>> 
>> Hey SE!
>> 
>> When we have a bunch of nested structs:
>> 
>>struct Sample {
>>var bar: Bar
>>}
>> 
>>struct Bar {
>>var show: Bool
>>}
>> 
>>var foo = Sample(bar: Bar(show: false))
>> 
>> It can be repetitive to toggle a deeply nested boolean:
>> 
>>foo.bar.show = !foo.bar.show // duplication
>> 
>> I sometimes add a `toggle` extension on `Bool`
>> 
>>extension Bool {
>>mutating func toggle() {
>>self = !self
>>}
>>}
>> 
>> This allows you to write the same code without duplication, and makes the
>> intent clearer:
>> 
>>foo.bar.show.toggle()
>> 
>> 
>> I like it!
>> 
>> In other languages, I don't think the `toggle` would make as much sense, but
>> the mutable self makes this very useful.
>> 
>> After I posted it on Twitter, it turns out I'm not the only one:
>> https://twitter.com/PublicExtension/status/730434956376346624
>> 
>> I would have gone straight to a proposal, but I think we can do some
>> bikeshedding about the name of `toggle`?
>> 
>> 
>> Another verb that could work is `invert`.
>> 
>> The `!` operator that does this is the negation operator, but I think
>> `negate` could sound to some like "make this false" rather than toggling.
>> 
>> Nate
>> ___
>> 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
>> 
> 
> 
> 
> -- 
> Alejandro Martinez
> http://alejandromp.com
> ___
> 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] Make try? + optional chain flattening work together

2018-01-12 Thread Matthew Johnson via swift-evolution

> On Jan 12, 2018, at 2:00 PM, John McCall via swift-evolution 
>  wrote:
> 
> 
>> On Jan 12, 2018, at 12:53 PM, BJ Homer via swift-evolution 
>> > wrote:
>> 
>> I agree that this behavior is annoying. However, wouldn’t it be 
>> source-breaking to change this now?
> 
> Source compatibility means that we can't change the behavior of Swift 3 / 
> Swift 4 source.  This would be a semantic change when building Swift 5 source 
> (or later).  There is no technical reason we couldn't make this change.  It 
> does need to meet a very high bar, because we are trying to avoid making 
> significant semantic breaks.  My personal sense is that it meets that bar 
> because double-optionals can be very confusing for novices and very annoying 
> for everyone else.
> 
> I think most use sites probably do want the optional-collapsing behavior.  
> 'try?' is already "sugar" syntax and should aim to be as convenient as 
> possible for the majority of use cases.  Much like the collapsing done by 
> optional chaining, I think you can come up with examples where somebody would 
> want the non-collapsing behavior, but it doesn't seem unreasonable to say 
> that they just shouldn't use the sugar.

I think I agree with this.  `try?` already has some implicit optional 
collapsing behavior when it is used in an expression where there is more than 
one call that can throw.  The most intuitive behavior is for this collapsing to 
compose with the collapsing of optional chaining.

> 
> John.
> 
>> 
>> -BJ
>> 
>>> On Jan 12, 2018, at 10:25 AM, Russ Bishop via swift-evolution 
>>> > wrote:
>>> 
>>> Greetings swift-evolution!
>>> 
>>> There is currently a disconnect between optional chaining and try? when it 
>>> comes to optional flattening:
>>> 
>>> 
>>> struct SomeType {
>>> func nonThrow() -> SomeType? { return self }
>>> func doThrow() throws -> SomeType? { return self }
>>> func nonOptional() throws -> SomeType { return self }
>>> }
>>> 
>>> let w = SomeType().nonThrow()?.nonThrow()?.nonThrow()?.nonThrow()
>>> // w has type SomeType?
>>> 
>>> let x = try? 
>>> SomeType().nonOptional().nonOptional().nonOptional().nonOptional()
>>> // x has type SomeType?
>>> 
>>> let y = try! SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
>>> // y has type SomeType?
>>> 
>>> let z = try? SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
>>> // z has type SomeType??
>>> 
>>> 
>>> We get a double-optional only when combining try? and optional-chaining. 
>>> That is inconvenient and it would be natural to have the compiler do the 
>>> flattening here.
>>> 
>>> 
>>> If anyone is interested in working on the proposal or implementation please 
>>> let me know. It would make a nice self-contained task if you're looking to 
>>> start contributing.
>>> 
>>> 
>>> Russ Bishop
>>>  Simulator
>>> 
>>> 
>>> ___
>>> 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] Make try? + optional chain flattening work together

2018-01-12 Thread John McCall via swift-evolution

> On Jan 12, 2018, at 12:53 PM, BJ Homer via swift-evolution 
>  wrote:
> 
> I agree that this behavior is annoying. However, wouldn’t it be 
> source-breaking to change this now?

Source compatibility means that we can't change the behavior of Swift 3 / Swift 
4 source.  This would be a semantic change when building Swift 5 source (or 
later).  There is no technical reason we couldn't make this change.  It does 
need to meet a very high bar, because we are trying to avoid making significant 
semantic breaks.  My personal sense is that it meets that bar because 
double-optionals can be very confusing for novices and very annoying for 
everyone else.

I think most use sites probably do want the optional-collapsing behavior.  
'try?' is already "sugar" syntax and should aim to be as convenient as possible 
for the majority of use cases.  Much like the collapsing done by optional 
chaining, I think you can come up with examples where somebody would want the 
non-collapsing behavior, but it doesn't seem unreasonable to say that they just 
shouldn't use the sugar.

John.

> 
> -BJ
> 
>> On Jan 12, 2018, at 10:25 AM, Russ Bishop via swift-evolution 
>> > wrote:
>> 
>> Greetings swift-evolution!
>> 
>> There is currently a disconnect between optional chaining and try? when it 
>> comes to optional flattening:
>> 
>> 
>> struct SomeType {
>> func nonThrow() -> SomeType? { return self }
>> func doThrow() throws -> SomeType? { return self }
>> func nonOptional() throws -> SomeType { return self }
>> }
>> 
>> let w = SomeType().nonThrow()?.nonThrow()?.nonThrow()?.nonThrow()
>> // w has type SomeType?
>> 
>> let x = try? 
>> SomeType().nonOptional().nonOptional().nonOptional().nonOptional()
>> // x has type SomeType?
>> 
>> let y = try! SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
>> // y has type SomeType?
>> 
>> let z = try? SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
>> // z has type SomeType??
>> 
>> 
>> We get a double-optional only when combining try? and optional-chaining. 
>> That is inconvenient and it would be natural to have the compiler do the 
>> flattening here.
>> 
>> 
>> If anyone is interested in working on the proposal or implementation please 
>> let me know. It would make a nice self-contained task if you're looking to 
>> start contributing.
>> 
>> 
>> Russ Bishop
>>  Simulator
>> 
>> 
>> ___
>> 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] adding toggle to Bool

2018-01-12 Thread Adrian Zubarev via swift-evolution
All I meant is that it’s usage should fade, which is my personal opinion. That 
said, I didn’t meant to say it should be removed or something. ;)


Am 12. Januar 2018 um 20:54:16, Alejandro Martinez (alexi...@gmail.com) schrieb:

I wouldn't go as far as to ask to fade out ! but in all my code I end  
up doing == false just for readability. That ! knows who to hide  
himself too well :P  

On Fri, Jan 12, 2018 at 10:13 AM, Adrian Zubarev via swift-evolution  
 wrote:  
> I’m not sure if this would be considered or not, but I would like if the  
> negation operator `!` would fade out.  
>  
> If this is ever going to a review then I’d suggest that we add a pair of  
> functions, one mutating and the other non-mutating.  
>  
> extension Bool {  
> mutating func invert() {  
> self = !self  
> }  
>  
> func inverted() {  
> return !self  
> }  
> }  
>  
> I’d rather use `inverted` instead of `!` because of the readability this  
> function provides.  
>  
> if !items.contains(item) { ... }  
>  
> if items.contains(item).inverted() { ... }  
>  
> ——  
>  
> I personally have some other extensions like:  
>  
> extension Bool {  
> @discardableResult  
> func whenTrue(execute closure: () throws -> T) rethrows -> T? {  
> if self { return try closure() }  
> return nil  
> }  
>  
> @discardableResult  
> func whenFalse(execute closure: () throws -> T) rethrows -> T? {  
> if !self { return try closure() }  
> return nil  
> }  
> }  
>  
> But this is more a personal preference.  
>  
> ——  
>  
> That said, if the community is fine with the `invert/inverted` pair then I’d  
> say go for it ;)  
>  
> Am 12. Januar 2018 um 09:14:22, Nate Cook via swift-evolution  
> (swift-evolution@swift.org) schrieb:  
>  
>  
> On Jan 12, 2018, at 12:15 AM, Chris Eidhof via swift-evolution  
>  wrote:  
>  
> Hey SE!  
>  
> When we have a bunch of nested structs:  
>  
> struct Sample {  
> var bar: Bar  
> }  
>  
> struct Bar {  
> var show: Bool  
> }  
>  
> var foo = Sample(bar: Bar(show: false))  
>  
> It can be repetitive to toggle a deeply nested boolean:  
>  
> foo.bar.show = !foo.bar.show // duplication  
>  
> I sometimes add a `toggle` extension on `Bool`  
>  
> extension Bool {  
> mutating func toggle() {  
> self = !self  
> }  
> }  
>  
> This allows you to write the same code without duplication, and makes the  
> intent clearer:  
>  
> foo.bar.show.toggle()  
>  
>  
> I like it!  
>  
> In other languages, I don't think the `toggle` would make as much sense, but  
> the mutable self makes this very useful.  
>  
> After I posted it on Twitter, it turns out I'm not the only one:  
> https://twitter.com/PublicExtension/status/730434956376346624  
>  
> I would have gone straight to a proposal, but I think we can do some  
> bikeshedding about the name of `toggle`?  
>  
>  
> Another verb that could work is `invert`.  
>  
> The `!` operator that does this is the negation operator, but I think  
> `negate` could sound to some like "make this false" rather than toggling.  
>  
> Nate  
> ___  
> 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  
>  



--  
Alejandro Martinez  
http://alejandromp.com  
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [pitch] adding toggle to Bool

2018-01-12 Thread Alejandro Martinez via swift-evolution
I wouldn't go as far as to ask to fade out ! but in all my code I end
up doing == false just for readability. That ! knows who to hide
himself too well :P

On Fri, Jan 12, 2018 at 10:13 AM, Adrian Zubarev via swift-evolution
 wrote:
> I’m not sure if this would be considered or not, but I would like if the
> negation operator `!` would fade out.
>
> If this is ever going to a review then I’d suggest that we add a pair of
> functions, one mutating and the other non-mutating.
>
> extension Bool {
>   mutating func invert() {
> self = !self
>   }
>
>   func inverted() {
> return !self
>   }
> }
>
> I’d rather use `inverted` instead of `!` because of the readability this
> function provides.
>
> if !items.contains(item) { ... }
>
> if items.contains(item).inverted() { ... }
>
> ——
>
> I personally have some other extensions like:
>
> extension Bool {
>   @discardableResult
>   func whenTrue(execute closure: () throws -> T) rethrows -> T? {
> if self { return try closure() }
> return nil
>   }
>
>   @discardableResult
>   func whenFalse(execute closure: () throws -> T) rethrows -> T? {
> if !self { return try closure() }
> return nil
>   }
> }
>
> But this is more a personal preference.
>
> ——
>
> That said, if the community is fine with the `invert/inverted` pair then I’d
> say go for it ;)
>
> Am 12. Januar 2018 um 09:14:22, Nate Cook via swift-evolution
> (swift-evolution@swift.org) schrieb:
>
>
> On Jan 12, 2018, at 12:15 AM, Chris Eidhof via swift-evolution
>  wrote:
>
> Hey SE!
>
> When we have a bunch of nested structs:
>
> struct Sample {
> var bar: Bar
> }
>
> struct Bar {
> var show: Bool
> }
>
> var foo = Sample(bar: Bar(show: false))
>
> It can be repetitive to toggle a deeply nested boolean:
>
> foo.bar.show = !foo.bar.show // duplication
>
> I sometimes add a `toggle` extension on `Bool`
>
> extension Bool {
> mutating func toggle() {
> self = !self
> }
> }
>
> This allows you to write the same code without duplication, and makes the
> intent clearer:
>
> foo.bar.show.toggle()
>
>
> I like it!
>
> In other languages, I don't think the `toggle` would make as much sense, but
> the mutable self makes this very useful.
>
> After I posted it on Twitter, it turns out I'm not the only one:
> https://twitter.com/PublicExtension/status/730434956376346624
>
> I would have gone straight to a proposal, but I think we can do some
> bikeshedding about the name of `toggle`?
>
>
> Another verb that could work is `invert`.
>
> The `!` operator that does this is the negation operator, but I think
> `negate` could sound to some like "make this false" rather than toggling.
>
> Nate
> ___
> 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
>



-- 
Alejandro Martinez
http://alejandromp.com
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Goffredo Marocchi via swift-evolution

Sent from my iPhone

> On 12 Jan 2018, at 18:25, Jordan Rose via swift-evolution 
>  wrote:
> 
> 
> 
>> On Jan 11, 2018, at 23:30, Chris Lattner  wrote:
>> 
>> 
>>> On Jan 11, 2018, at 11:15 PM, Jean-Daniel via swift-evolution 
>>>  wrote:
>>> 
>>> A question about the new #unknown behavior. Is it intended to be used for 
>>> error handling too ?
>>> Will it be possible to use in catch clause ?
>> 
>> If we go with the #unknown approach, then yes of course it will work in 
>> catch clauses.  They are patterns, so it naturally falls out.
> 
> It will not work in catch clauses because you need to have a static type 
> that's an enum. Catch clauses always (today…) have a static type of 'Error'.
> 
> 
>> 
>> If we go with the “unknown default:” / “unknown case:"  approach, then no, 
>> this has nothing to do with error handling.
>> 
>> IMO, this pivots on the desired semantics for “unknown cases in enums”: if 
>> you intentionally try to match on this, do we get a warning or error if you 
>> don’t handle all the cases?  If we can get to consensus on that point, then 
>> the design is pretty obvious IMO.
> 
> That's fair. I'm strongly in favor of a warning, though, because again, 
> people don't edit their dependencies.

A warning is better than nothing :), but for third party libraries you include 
in the app you are responsible for not updating to a library that would break 
your build and between compiler and automation catch this error before merging 
a PR and putting it in production. It is also your responsibility to reasonable 
choose a library that is properly maintained and vetted.

> 
> Jordan
> 
> ___
> 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] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Jordan Rose via swift-evolution


> On Jan 12, 2018, at 06:49, Michel Fortin via swift-evolution 
>  wrote:
> 
>> Le 12 janv. 2018 à 4:44, Vladimir.S via swift-evolution 
>> > a écrit :
>> 
>> On 12.01.2018 10:30, Chris Lattner via swift-evolution wrote:
 On Jan 11, 2018, at 11:15 PM, Jean-Daniel via swift-evolution 
 > wrote:
 
 A question about the new #unknown behavior. Is it intended to be used for 
 error handling too ?
 Will it be possible to use in catch clause ?
>>> If we go with the #unknown approach, then yes of course it will work in 
>>> catch clauses.  They are patterns, so it naturally falls out.
>>> If we go with the “unknown default:” / “unknown case:"  approach, then no, 
>>> this has nothing to do with error handling.
>>> IMO, this pivots on the desired semantics for “unknown cases in enums”: if 
>>> you intentionally try to match on this, do we get a warning or error if you 
>>> don’t handle all the cases?  If we can get to consensus on that point, then 
>>> the design is pretty obvious IMO.
>> 
>> For me the other question is what "all the cases" means for enum with 
>> private cases(if we'll have them). I.e. if switch contains all the "public" 
>> cases of frozen enum - does this mean "all the cases" were processed? As I 
>> understand, the answer is no, because we *can* have 'private' case value 
>> here and so we need to react to this. How switch will look in this case?
>> 
>> switch frozenEnumWithPrivateCases {
>>  case .one: ..
>>  case .two: ..
>>  unknown default: ..  // or 'case #unknown:' depending on our decision, or 
>> 'unknown case:' etc
>> }
>> ?
>> But then such switch looks exactly as switch for non-frozen enum value, no? 
>> It looks like we are reacting on future new cases, while enum is frozen.
>> 
>> Moreover. How the switch for non-frozed enum with private cases should looks 
>> like?
>> 
>> switch nonfrozenEnumWithPrivateCases {
>>  case .one: ..
>>  case .two: ..
>>  unknown default: ..  // or 'case #unknown:' depending on our decision, or 
>> 'unknown case:' etc
>> }
>> ? But then, is that 'unknown default' for reacting on "future" cases we 
>> didn't know about during the compilation OR it is for reacting on private 
>> cases?
>> 
>> Or the main idea that we don't want to separate "future" cases and "private" 
>> cases?
> 
> I think treating both as the same thing is the right idea. You also need to 
> handle "future private" cases and "private cases that become public in the 
> future". These are all unknown cases in the context of the switch.
> 
> So an enum with private cases can't be switched exhaustively outside of its 
> module. Thus, @frozen would need to forbid private cases... or we need 
> @exhaustive to forbid private cases so they can be allowed by @frozen.

As mentioned in "Future directions", my recommendation to anyone planning to 
write a proposal for non-public cases is to go with the former, which would 
keep it from infecting the design.

Jordan

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


Re: [swift-evolution] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jan 12, 2018, at 12:25 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> 
> 
>> On Jan 11, 2018, at 23:30, Chris Lattner  wrote:
>> 
>> 
>>> On Jan 11, 2018, at 11:15 PM, Jean-Daniel via swift-evolution 
>>>  wrote:
>>> 
>>> A question about the new #unknown behavior. Is it intended to be used for 
>>> error handling too ?
>>> Will it be possible to use in catch clause ?
>> 
>> If we go with the #unknown approach, then yes of course it will work in 
>> catch clauses.  They are patterns, so it naturally falls out.
> 
> It will not work in catch clauses because you need to have a static type 
> that's an enum. Catch clauses always (today…) have a static type of 'Error'.

Right, although it should work for enum Error types in catch clauses if we add 
typed errors in the future.  That’s worth considering when making this decision.

> 
> 
>> 
>> If we go with the “unknown default:” / “unknown case:"  approach, then no, 
>> this has nothing to do with error handling.
>> 
>> IMO, this pivots on the desired semantics for “unknown cases in enums”: if 
>> you intentionally try to match on this, do we get a warning or error if you 
>> don’t handle all the cases?  If we can get to consensus on that point, then 
>> the design is pretty obvious IMO.
> 
> That's fair. I'm strongly in favor of a warning, though, because again, 
> people don't edit their dependencies.
> 
> Jordan
> 
> ___
> 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] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Jordan Rose via swift-evolution


> On Jan 11, 2018, at 23:30, Chris Lattner  wrote:
> 
> 
>> On Jan 11, 2018, at 11:15 PM, Jean-Daniel via swift-evolution 
>>  wrote:
>> 
>> A question about the new #unknown behavior. Is it intended to be used for 
>> error handling too ?
>> Will it be possible to use in catch clause ?
> 
> If we go with the #unknown approach, then yes of course it will work in catch 
> clauses.  They are patterns, so it naturally falls out.

It will not work in catch clauses because you need to have a static type that's 
an enum. Catch clauses always (today…) have a static type of 'Error'.


> 
> If we go with the “unknown default:” / “unknown case:"  approach, then no, 
> this has nothing to do with error handling.
> 
> IMO, this pivots on the desired semantics for “unknown cases in enums”: if 
> you intentionally try to match on this, do we get a warning or error if you 
> don’t handle all the cases?  If we can get to consensus on that point, then 
> the design is pretty obvious IMO.

That's fair. I'm strongly in favor of a warning, though, because again, people 
don't edit their dependencies.

Jordan

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


Re: [swift-evolution] [Pitch] Make try? + optional chain flattening work together

2018-01-12 Thread Nevin Brackett-Rozinsky via swift-evolution
This is not an optional-chaining issue *per se*. If you simply write,

let a = try? SomeType().doThrow()

// a has type SomeType??

you get a double-optional as well. Are you proposing to change that?

Nevin


On Fri, Jan 12, 2018 at 12:25 PM, Russ Bishop via swift-evolution <
swift-evolution@swift.org> wrote:

> Greetings swift-evolution!
>
> There is currently a disconnect between optional chaining and try? when it
> comes to optional flattening:
>
>
> struct SomeType {
> func nonThrow() -> SomeType? { return self }
> func doThrow() throws -> SomeType? { return self }
> func nonOptional() throws -> SomeType { return self }
> }
>
> let w = SomeType().nonThrow()?.nonThrow()?.nonThrow()?.nonThrow()
> // w has type SomeType?
>
> let x = try? SomeType().nonOptional().nonOptional().nonOptional().nonOpti
> onal()
> // x has type SomeType?
>
> let y = try! SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
> // y has type SomeType?
>
> let z = try? SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
> // z has type SomeType??
>
>
> We get a double-optional only when combining try? and optional-chaining.
> That is inconvenient and it would be natural to have the compiler do the
> flattening here.
>
>
> If anyone is interested in working on the proposal or implementation
> please let me know. It would make a nice self-contained task if you're
> looking to start contributing.
>
>
> Russ Bishop
>  Simulator
>
>
>
> ___
> 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] Make try? + optional chain flattening work together

2018-01-12 Thread BJ Homer via swift-evolution
I agree that this behavior is annoying. However, wouldn’t it be source-breaking 
to change this now?

-BJ

> On Jan 12, 2018, at 10:25 AM, Russ Bishop via swift-evolution 
>  wrote:
> 
> Greetings swift-evolution!
> 
> There is currently a disconnect between optional chaining and try? when it 
> comes to optional flattening:
> 
> 
> struct SomeType {
> func nonThrow() -> SomeType? { return self }
> func doThrow() throws -> SomeType? { return self }
> func nonOptional() throws -> SomeType { return self }
> }
> 
> let w = SomeType().nonThrow()?.nonThrow()?.nonThrow()?.nonThrow()
> // w has type SomeType?
> 
> let x = try? 
> SomeType().nonOptional().nonOptional().nonOptional().nonOptional()
> // x has type SomeType?
> 
> let y = try! SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
> // y has type SomeType?
> 
> let z = try? SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
> // z has type SomeType??
> 
> 
> We get a double-optional only when combining try? and optional-chaining. That 
> is inconvenient and it would be natural to have the compiler do the 
> flattening here.
> 
> 
> If anyone is interested in working on the proposal or implementation please 
> let me know. It would make a nice self-contained task if you're looking to 
> start contributing.
> 
> 
> Russ Bishop
>  Simulator
> 
> 
> ___
> 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] [Pitch] Make try? + optional chain flattening work together

2018-01-12 Thread Russ Bishop via swift-evolution
Greetings swift-evolution!

There is currently a disconnect between optional chaining and try? when it 
comes to optional flattening:


struct SomeType {
func nonThrow() -> SomeType? { return self }
func doThrow() throws -> SomeType? { return self }
func nonOptional() throws -> SomeType { return self }
}

let w = SomeType().nonThrow()?.nonThrow()?.nonThrow()?.nonThrow()
// w has type SomeType?

let x = try? SomeType().nonOptional().nonOptional().nonOptional().nonOptional()
// x has type SomeType?

let y = try! SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
// y has type SomeType?

let z = try? SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
// z has type SomeType??


We get a double-optional only when combining try? and optional-chaining. That 
is inconvenient and it would be natural to have the compiler do the flattening 
here.


If anyone is interested in working on the proposal or implementation please let 
me know. It would make a nice self-contained task if you're looking to start 
contributing.


Russ Bishop
 Simulator


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


Re: [swift-evolution] [pitch] adding toggle to Bool

2018-01-12 Thread Ben Cohen via swift-evolution
+1 for toggle, seems the clear winner for me.

> On Jan 12, 2018, at 8:29 AM, Cheyo Jimenez via swift-evolution 
>  wrote:
> 
> It’s a slippery slope because it makes me want to have something like `not()` 
> added to the library. I don’t think it’s worth it. 
> 

I would love to have not(), but for a different purpose:

func not(_ predicate: @escaping (T)->Bool) -> (T)->Bool {
  return { !predicate($0) }
}

let noScrubs = guys.filter(not(isBusta))

I guess you could overload a version of ! for predicates but that doesn’t seem 
wise.


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


Re: [swift-evolution] [pitch] adding toggle to Bool

2018-01-12 Thread Cheyo Jimenez via swift-evolution


> On Jan 12, 2018, at 12:14 AM, Nate Cook via swift-evolution 
>  wrote:
> 
> 
>> On Jan 12, 2018, at 12:15 AM, Chris Eidhof via swift-evolution 
>>  wrote:
>> 
>> Hey SE!
>> 
>> When we have a bunch of nested structs:
>> 
>> struct Sample {
>> var bar: Bar
>> }
>> 
>> struct Bar {
>> var show: Bool
>> }
>> 
>> var foo = Sample(bar: Bar(show: false))
>> 
>> It can be repetitive to toggle a deeply nested boolean:
>> 
>> foo.bar.show = !foo.bar.show // duplication
>> 
>> I sometimes add a `toggle` extension on `Bool`
>> 
>> extension Bool {
>> mutating func toggle() {
>> self = !self
>> }
>> }
>> 
>> This allows you to write the same code without duplication, and makes the 
>> intent clearer:
>> 
>> foo.bar.show.toggle()
> 
> I like it!
> 
>> In other languages, I don't think the `toggle` would make as much sense, but 
>> the mutable self makes this very useful.
>> 
>> After I posted it on Twitter, it turns out I'm not the only one: 
>> https://twitter.com/PublicExtension/status/730434956376346624
>> 
>> I would have gone straight to a proposal, but I think we can do some 
>> bikeshedding about the name of `toggle`?
> 
> Another verb that could work is `invert`.

That’s a good one. Similar to bit flipping which Apple calls inverting. 

“The bitwise NOT operator (~) inverts all bits in a number:”

I was thinking `flip` for this function but then I actually don’t think this 
extension is a good idea in the standard library :(

Should we also have a mutating extension for the `NOT` operator? Probably no. 

If people need it, they can add it and call it toggle, invert, flip, reverse, 
negate or what ever they want.  

It’s a slippery slope because it makes me want to have something like `not()` 
added to the library. I don’t think it’s worth it. 



> 
> The `!` operator that does this is the negation operator, but I think 
> `negate` could sound to some like "make this false" rather than toggling. 
> 
> Nate
> ___
> 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

2018-01-12 Thread Alejandro Alonso via swift-evolution
Done and done!

Sent from my iPhone

On Jan 12, 2018, at 01:22, Nate Cook 
> wrote:

On Jan 11, 2018, at 9:17 PM, Alejandro Alonso 
> wrote:

Sorry it takes me forever to respond! I finally got around to writing this! 
School really takes all my time x)

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

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

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

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

You wrote:

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

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



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

I believe this is the direction we need to go to keep consistency with 
collection based methods by justifying `.random(in:)` on the numeric types. 
With that in mind, Ben made a comment a long while ago saying, “The one 
downside is that you’d have to write 0..mailto:swift-evolution@swift.org>>, wrote:
I created a playground to explore this question, starting with a minimal subset 
of the proposal’s additions and building from there. The attached playground 
demonstrates what’s possible with this subset on the first page, then uses 
subsequent pages to explore how the main random facilities of the C++ STL work 
under this model. (In my opinion, they work pretty well!)

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

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

Nate


On Dec 2, 2017, at 9:50 PM, Dave Abrahams via swift-evolution 
> wrote:

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

Sent from my iPad

On Dec 2, 2017, at 5:12 PM, Kyle Murray via swift-evolution 
> wrote:


On Dec 2, 2017, at 6:02 PM, Xiaodi Wu via swift-evolution 
> wrote:

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

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

For someone who doesn't know or care about the subtleties of insecure or 
pseudorandom numbers, I'm not sure that the name insecureRandom is effectively 
much different than badRandom, at least in terms of the information it conveys 
to 

Re: [swift-evolution] [Review] SE-0194: Derived Collection of Enum Cases

2018-01-12 Thread Paul Cantrell via swift-evolution


> On Jan 11, 2018, at 11:42 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Jan 11, 2018, at 4:21 PM, Paul Cantrell > > wrote:
>> 
>> This raises a question related to Chris’s: what is the utility of having 
>> Limb conform to a protocol instead of just providing allValues ad hoc? Does 
>> CaseEnumerable / ValueEnumerable serve any purpose other than triggering 
>> special behavior in the compiler? Would the protocol ever be used as the 
>> type of something in code?
>> 
>> My answers, admittedly weak ones, are: (1) conventions are nice and 
>> consistency is nice, and (2) you never know how an abstraction might be 
>> used, but you do know that people will be angry when it should fit but 
>> doesn’t. I can’t come up with a more compelling or specific argument than 
>> those.
> 
> Here's a place where you might want to use the protocol: Suppose you're 
> writing a table view data source that displays editable controls for a form. 
> You support several different types of controls, one of which is a list of 
> choices for a picker controller.
> 
>   enum Control {
>   case textField
>   case picker(choices: [Value])
>   …
>   
>   func makeView() -> UIView { … }
>   subscript(valueOf view: UIView) -> Value { get { … } set { … } }
>   }
> 
> Presumably you end up writing a schema which looks something like:
> 
>   formDataSource = FormDataSource(value: person)
>   formDataSource.fields = [
>   Section(title: nil, fields: [
>   Field(title: "Name", keyPath: \.name, control: 
> .textField),
>   Field(title: "Gender", keyPath: \.gender, control: . 
> picker(choices: Array(Gender.allValues))),
>   …
>   ])
>   ]
>   tableView.dataSource = formDataSource
> 
> The `Array(Gender.allValues)` here is clutter; it'd be nice if we didn't have 
> to write it explicitly. After all, if you're choosing a value of something 
> you know is an enum, it's sensible to assume that you want to choose from all 
> values if it doesn't specify anything more specific. If `ValueEnumerable` is 
> a formalized protocol, you can do that with a constrained extension:
> 
>   extension Control where Value: ValueEnumerable {
>   static var picker: Control {
>   return .picker(choices: Array(Value.allValues))
>   }
>   }
> 
> And now you just need to write:
> 
>   Field(title: "Gender", keyPath: \.gender, control: . 
> picker)

One magic future day, the protocol could be Chris’s narrower CaseEnumerable, 
Brent’s hypothetical picker could use a more general ValueEnumerable, and we 
could short-circuit the whole debate with:

extension CaseEnumerable: ValueEnumerable {
var allValues: WhateverThisTypeIsSupposedToBe {
return allCases
}
}

…but I recall a particularly thorny “alternatives considered” section about the 
implications of allowing extensions to add protocol conformance to other 
protocols!

Absent that language feature, I do think Brent has a point.

I tend to agree with Chris’s assessment here, which to my eyes doesn’t 
contradict Brent’s example:

> On Jan 12, 2018, at 1:28 AM, Chris Lattner  wrote:
> 

> While we generally generally steer protocols towards being a “bag of 
> semantics” instead of a “bag of syntax”, there are definitely exceptions to 
> that rule, including the ExpressibleBy and other compiler intrinsic protocols 
> which really are *all about* defining syntax.  These protocols are not 
> particularly useful for generic algorithms.
> 
> The next level down are protocols like hashable/comparable that are useful 
> for generic algorithms, but are also particularly interesting because of 
> compiler synthesized conformances.  They are unique because they are both 
> sometimes interesting for generic algorithms, but also sometimes interesting 
> just because you want the synthesized members on *concrete* types for 
> non-generic uses.  IMO, this is the bucket that this proposal falls into.


That seems right: this CaseEnumerable / ValueEnumerable protocol will usually 
be about synthesized conformance, but occasionally be about semantics that are 
useful for generic algorithms.

I wouldn’t want to touch the “all possible values for all types” idea with an 
ℵ₀-foot pole.[1] However, I don’t see the harm in going Brent’s direction: a 
protocol whose “bag of semantics” is along the lines of “has a limited, known 
set of possible values that does not change during execution, and that might 
reasonably be iterated over or displayed to the user as a set of choices.”

That suggests to me the name ValueEnumerable. As with Equatable, it is named 
for the generic use, but synthesized by the compiler in a specific situation 
where it makes obvious sense to do 

Re: [swift-evolution] [pitch] adding toggle to Bool

2018-01-12 Thread Xiaodi Wu via swift-evolution
Agree: toggle makes the most sense to me as well.
On Fri, Jan 12, 2018 at 06:14 David Hart via swift-evolution <
swift-evolution@swift.org> wrote:

>
>
> On 12 Jan 2018, at 07:15, Chris Eidhof via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hey SE!
>
> When we have a bunch of nested structs:
>
> struct Sample {
> var bar: Bar
> }
>
> struct Bar {
> var show: Bool
> }
>
> var foo = Sample(bar: Bar(show: false))
>
> It can be repetitive to toggle a deeply nested boolean:
>
> foo.bar.show = !foo.bar.show // duplication
>
> I sometimes add a `toggle` extension on `Bool`
>
> extension Bool {
> mutating func toggle() {
> self = !self
> }
> }
>
> This allows you to write the same code without duplication, and makes the
> intent clearer:
>
> foo.bar.show.toggle()
>
> In other languages, I don't think the `toggle` would make as much sense,
> but the mutable self makes this very useful.
>
> After I posted it on Twitter, it turns out I'm not the only one:
> https://twitter.com/PublicExtension/status/730434956376346624
>
> I would have gone straight to a proposal, but I think we can do some
> bikeshedding about the name of `toggle`?
>
>
> Out of all the versions I heard, toggle is the one that makes the most
> sense to me.
>
> --
> Chris Eidhof
> ___
> 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] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Michel Fortin via swift-evolution
> Le 12 janv. 2018 à 4:44, Vladimir.S via swift-evolution 
>  a écrit :
> 
> On 12.01.2018 10:30, Chris Lattner via swift-evolution wrote:
>>> On Jan 11, 2018, at 11:15 PM, Jean-Daniel via swift-evolution 
>>>  wrote:
>>> 
>>> A question about the new #unknown behavior. Is it intended to be used for 
>>> error handling too ?
>>> Will it be possible to use in catch clause ?
>> If we go with the #unknown approach, then yes of course it will work in 
>> catch clauses.  They are patterns, so it naturally falls out.
>> If we go with the “unknown default:” / “unknown case:"  approach, then no, 
>> this has nothing to do with error handling.
>> IMO, this pivots on the desired semantics for “unknown cases in enums”: if 
>> you intentionally try to match on this, do we get a warning or error if you 
>> don’t handle all the cases?  If we can get to consensus on that point, then 
>> the design is pretty obvious IMO.
> 
> For me the other question is what "all the cases" means for enum with private 
> cases(if we'll have them). I.e. if switch contains all the "public" cases of 
> frozen enum - does this mean "all the cases" were processed? As I understand, 
> the answer is no, because we *can* have 'private' case value here and so we 
> need to react to this. How switch will look in this case?
> 
> switch frozenEnumWithPrivateCases {
>  case .one: ..
>  case .two: ..
>  unknown default: ..  // or 'case #unknown:' depending on our decision, or 
> 'unknown case:' etc
> }
> ?
> But then such switch looks exactly as switch for non-frozen enum value, no? 
> It looks like we are reacting on future new cases, while enum is frozen.
> 
> Moreover. How the switch for non-frozed enum with private cases should looks 
> like?
> 
> switch nonfrozenEnumWithPrivateCases {
>  case .one: ..
>  case .two: ..
>  unknown default: ..  // or 'case #unknown:' depending on our decision, or 
> 'unknown case:' etc
> }
> ? But then, is that 'unknown default' for reacting on "future" cases we 
> didn't know about during the compilation OR it is for reacting on private 
> cases?
> 
> Or the main idea that we don't want to separate "future" cases and "private" 
> cases?

I think treating both as the same thing is the right idea. You also need to 
handle "future private" cases and "private cases that become public in the 
future". These are all unknown cases in the context of the switch.

So an enum with private cases can't be switched exhaustively outside of its 
module. Thus, @frozen would need to forbid private cases... or we need 
@exhaustive to forbid private cases so they can be allowed by @frozen.

-- 
Michel Fortin
https://michelf.ca

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


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

2018-01-12 Thread Alejandro Alonso via swift-evolution
Give up*

Sent from my iPhone

On Jan 12, 2018, at 08:10, Alejandro Alonso via swift-evolution 
> wrote:

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

Sent from my iPhone

On Jan 11, 2018, at 21:28, Xiaodi Wu 
> wrote:

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

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

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

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

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

You wrote:

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

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



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

I believe this is the direction we need to go to keep consistency with 
collection based methods by justifying `.random(in:)` on the numeric types. 
With that in mind, Ben made a comment a long while ago saying, “The one 
downside is that you’d have to write 0..mailto:swift-evolution@swift.org>>, wrote:
I created a playground to explore this question, starting with a minimal subset 
of the proposal’s additions and building from there. The attached playground 
demonstrates what’s possible with this subset on the first page, then uses 
subsequent pages to explore how the main random facilities of the C++ STL work 
under this model. (In my opinion, they work pretty well!)

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

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

Nate


On Dec 2, 2017, at 9:50 PM, Dave Abrahams via swift-evolution 
> wrote:

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

Sent from my iPad

On Dec 2, 2017, at 5:12 PM, Kyle Murray via swift-evolution 
> wrote:


On Dec 2, 2017, at 6:02 PM, Xiaodi Wu via swift-evolution 
> wrote:

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

I like that you're considering the balance here. I've been lightly following 
this thread and want to add my thoughts on keeping crypto and pseudorandomness 
out of the name of at 

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

2018-01-12 Thread Alejandro Alonso via swift-evolution
(0 ..< 10).random() would return an optional
Int.random(in: 0 ..< 10) would return a non optional (this is the one that 
crashes on bad range)

Sent from my iPhone

On Jan 12, 2018, at 07:11, Letanyan Arumugam 
> wrote:

Nate’s design follows a consistent idea of getting a random value from some set 
of values. Adding the static method random() to a type essentially creates an 
implicit set which you yourself said leads to inconsistency (Double/Int). 
Secondly I don’t see why random(in:) should be added when it is just a 
different spelling for what is already provided. If my second statement is 
incorrect and there’s something I’m missing please correct me?

I think that consistency outweighs the random trapping inconsistency, however I 
would actually be fine if random returned an optional. Though the way random is 
used would likely lead to less opportunities for a trap than the other methods 
you mention.


Letanyan

On 12 Jan 2018, at 04:39, Alejandro Alonso 
> wrote:

If anything, Nate’s design is inconsistent as properties like `.first` and 
`.last` return an optional, and methods like `.min()` and `.max()` return an 
optional as well. Having `.random()` on ranges be an exception and return non 
optionals are inconsistent with other collection facilities, and with other 
collections that aren’t ranges that return optionals on `.random()`.

- Alejandro

On Jan 11, 2018, 12:06 PM -0600, Letanyan Arumugam via swift-evolution 
>, wrote:
This is really cool and seems very powerful. However I don’t think we should 
sacrifice consistency for extendability. Especially when the extendability 
would not be what most people need.

What I am basically trying to say is that. I think the proposals current design 
direction fits better in a Random library rather than the Standard Library. And 
Nate’s design more directly addresses the motivating points of the proposal.

Letanyan


Sure. Small disclaimer that this was originally written back in the Swift 1~2 
days, so it is overdue for a simplifying rewrite.

Also, I should point out that the term “Source” has a special meaning in my 
code.  It basically means that something will provide an ~infinite collection 
of values of a type T.   I have what I call a “ConstantSource” which just wraps 
a T and gives it back when asked.  But then I have a bunch of other “sources" 
which let you create repeating patterns and do deferred calculations and things 
like that.  Finally I have a “RandomSource” which is part of what started this 
discussion.  You set up a RandomSource with a set of constraints, and then it 
gives you random values of T that adhere to those constraints (e.g. colors with 
a range of hues but the same saturation) whenever you ask for them.

This is really useful for doing things like graphic effects because, for 
example, I can ask for a source of colors and a source of line widths and then 
get out a large variety of interesting patterns from the same algorithm.  I can 
make simple stripes with ConstantSources, or I can make repeating patterns of 
lines with repeating sources, or I can have random colors which look good 
together by using a RandomSource.  I can take a BezierPath and make it look 
hand-drawn by breaking it into a bunch of lines and then offset the points a 
small amount using a RandomSource of CGVectors.

Not sure how useful this concept of randomness (and pattern) is to others, but 
I find it immensely useful!  Not sure of the best way to implement it.  The way 
I do it is a type erased protocol with private conforming structs and then 
public initializers on the type-erasing box.  The end result is that I can just 
say:

let myConst = Source(1) //ConstantSource with 1 as a value
let myPattern = Source([1, 2]) //OrderedSource which repeats 1, then 2 over and 
over forever
let myMeta = Source([myConst, myPattern]) //Will alternate between sub-sources 
in order. Can be nested.
//…and so on.

It is quite extensible and can make very complex/interesting patterns very 
easily.  What I like about it is that (well controlled) random values and 
patterns or constant values can be interchanged very easily.

The RandomSource has a RandomSourceCreatable Protocol that lets it take random 
bits and turn them into objects/structs of T adhering to the given constraints. 
 This is way more complex under the hood than it needs to be, but it works well 
in practice, and I haven’t gotten around to cleaning it up yet:

public protocol RandomSourceCreatable {
associatedtype ConstraintType = Self

///This should be implimented by simple types without internal components
static func createRandom(rnd value:RandomSourceValue, 
constraint:RandomSourceConstraint)->Self

///This should be implimented by complex types with multiple axis of constraints
static func createRandom(rnd 

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

2018-01-12 Thread Alejandro Alonso via swift-evolution
I am willing to give `.random()`. However I still wish to preserve 
`.random(in:)` and `.random()` on Bool.

Sent from my iPhone

On Jan 11, 2018, at 21:28, Xiaodi Wu 
> wrote:

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

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

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

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

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

You wrote:

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

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



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

I believe this is the direction we need to go to keep consistency with 
collection based methods by justifying `.random(in:)` on the numeric types. 
With that in mind, Ben made a comment a long while ago saying, “The one 
downside is that you’d have to write 0..mailto:swift-evolution@swift.org>>, wrote:
I created a playground to explore this question, starting with a minimal subset 
of the proposal’s additions and building from there. The attached playground 
demonstrates what’s possible with this subset on the first page, then uses 
subsequent pages to explore how the main random facilities of the C++ STL work 
under this model. (In my opinion, they work pretty well!)

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

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

Nate


On Dec 2, 2017, at 9:50 PM, Dave Abrahams via swift-evolution 
> wrote:

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

Sent from my iPad

On Dec 2, 2017, at 5:12 PM, Kyle Murray via swift-evolution 
> wrote:


On Dec 2, 2017, at 6:02 PM, Xiaodi Wu via swift-evolution 
> wrote:

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

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

For someone who doesn't know or care about the subtleties of insecure or 
pseudorandom numbers, I'm not sure that the 

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

2018-01-12 Thread Letanyan Arumugam via swift-evolution
Nate’s design follows a consistent idea of getting a random value from some set 
of values. Adding the static method random() to a type essentially creates an 
implicit set which you yourself said leads to inconsistency (Double/Int). 
Secondly I don’t see why random(in:) should be added when it is just a 
different spelling for what is already provided. If my second statement is 
incorrect and there’s something I’m missing please correct me?

I think that consistency outweighs the random trapping inconsistency, however I 
would actually be fine if random returned an optional. Though the way random is 
used would likely lead to less opportunities for a trap than the other methods 
you mention. 


Letanyan

> On 12 Jan 2018, at 04:39, Alejandro Alonso  wrote:
> 
> If anything, Nate’s design is inconsistent as properties like `.first` and 
> `.last` return an optional, and methods like `.min()` and `.max()` return an 
> optional as well. Having `.random()` on ranges be an exception and return non 
> optionals are inconsistent with other collection facilities, and with other 
> collections that aren’t ranges that return optionals on `.random()`.
> 
> - Alejandro
> 
> On Jan 11, 2018, 12:06 PM -0600, Letanyan Arumugam via swift-evolution 
> , wrote:
>> This is really cool and seems very powerful. However I don’t think we should 
>> sacrifice consistency for extendability. Especially when the extendability 
>> would not be what most people need. 
>> 
>> What I am basically trying to say is that. I think the proposals current 
>> design direction fits better in a Random library rather than the Standard 
>> Library. And Nate’s design more directly addresses the motivating points of 
>> the proposal.
>> 
>> Letanyan
>> 
>>> 
>>> Sure. Small disclaimer that this was originally written back in the Swift 
>>> 1~2 days, so it is overdue for a simplifying rewrite.
>>> 
>>> Also, I should point out that the term “Source” has a special meaning in my 
>>> code.  It basically means that something will provide an ~infinite 
>>> collection of values of a type T.   I have what I call a “ConstantSource” 
>>> which just wraps a T and gives it back when asked.  But then I have a bunch 
>>> of other “sources" which let you create repeating patterns and do deferred 
>>> calculations and things like that.  Finally I have a “RandomSource” which 
>>> is part of what started this discussion.  You set up a RandomSource with a 
>>> set of constraints, and then it gives you random values of T that adhere to 
>>> those constraints (e.g. colors with a range of hues but the same 
>>> saturation) whenever you ask for them.
>>> 
>>> This is really useful for doing things like graphic effects because, for 
>>> example, I can ask for a source of colors and a source of line widths and 
>>> then get out a large variety of interesting patterns from the same 
>>> algorithm.  I can make simple stripes with ConstantSources, or I can make 
>>> repeating patterns of lines with repeating sources, or I can have random 
>>> colors which look good together by using a RandomSource.  I can take a 
>>> BezierPath and make it look hand-drawn by breaking it into a bunch of lines 
>>> and then offset the points a small amount using a RandomSource of CGVectors.
>>> 
>>> Not sure how useful this concept of randomness (and pattern) is to others, 
>>> but I find it immensely useful!  Not sure of the best way to implement it.  
>>> The way I do it is a type erased protocol with private conforming structs 
>>> and then public initializers on the type-erasing box.  The end result is 
>>> that I can just say:
>>> 
>>> let myConst = Source(1) //ConstantSource with 1 as a value
>>> let myPattern = Source([1, 2]) //OrderedSource which repeats 1, then 2 over 
>>> and over forever
>>> let myMeta = Source([myConst, myPattern]) //Will alternate between 
>>> sub-sources in order. Can be nested.
>>> //…and so on.
>>> 
>>> It is quite extensible and can make very complex/interesting patterns very 
>>> easily.  What I like about it is that (well controlled) random values and 
>>> patterns or constant values can be interchanged very easily.
>>> 
>>> The RandomSource has a RandomSourceCreatable Protocol that lets it take 
>>> random bits and turn them into objects/structs of T adhering to the given 
>>> constraints.  This is way more complex under the hood than it needs to be, 
>>> but it works well in practice, and I haven’t gotten around to cleaning it 
>>> up yet:
>>> 
>>> public protocol RandomSourceCreatable {
>>> associatedtype ConstraintType = Self
>>> 
>>> 
>>> ///This should be implimented by simple types without internal components
>>> 
>>> static func createRandom(rnd value:RandomSourceValue, 
>>> constraint:RandomSourceConstraint)->Self
>>> 
>>> ///This should be implimented by complex types with multiple axis of 
>>> constraints
>>> 
>>> static func createRandom(rnd value:RandomSourceValue, 
>>> 

Re: [swift-evolution] [pitch] adding toggle to Bool

2018-01-12 Thread David Hart via swift-evolution


> On 12 Jan 2018, at 07:15, Chris Eidhof via swift-evolution 
>  wrote:
> 
> Hey SE!
> 
> When we have a bunch of nested structs:
> 
> struct Sample {
> var bar: Bar
> }
> 
> struct Bar {
> var show: Bool
> }
> 
> var foo = Sample(bar: Bar(show: false))
> 
> It can be repetitive to toggle a deeply nested boolean:
> 
> foo.bar.show = !foo.bar.show // duplication
> 
> I sometimes add a `toggle` extension on `Bool`
> 
> extension Bool {
> mutating func toggle() {
> self = !self
> }
> }
> 
> This allows you to write the same code without duplication, and makes the 
> intent clearer:
> 
> foo.bar.show.toggle()
> 
> In other languages, I don't think the `toggle` would make as much sense, but 
> the mutable self makes this very useful.
> 
> After I posted it on Twitter, it turns out I'm not the only one: 
> https://twitter.com/PublicExtension/status/730434956376346624 
> 
> 
> I would have gone straight to a proposal, but I think we can do some 
> bikeshedding about the name of `toggle`?

Out of all the versions I heard, toggle is the one that makes the most sense to 
me.

> -- 
> Chris Eidhof
> ___
> 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] adding toggle to Bool

2018-01-12 Thread Adrian Zubarev via swift-evolution
I’m not sure if this would be considered or not, but I would like if the 
negation operator `!` would fade out.

If this is ever going to a review then I’d suggest that we add a pair of 
functions, one mutating and the other non-mutating.

extension Bool {
  mutating func invert() {
    self = !self
  }

  func inverted() {
    return !self
  }
}

I’d rather use `inverted` instead of `!` because of the readability this 
function provides.

if !items.contains(item) { ... }

if items.contains(item).inverted() { ... } 

——

I personally have some other extensions like:

extension Bool {
  @discardableResult
  func whenTrue(execute closure: () throws -> T) rethrows -> T? {
    if self { return try closure() }
    return nil
  }

  @discardableResult
  func whenFalse(execute closure: () throws -> T) rethrows -> T? {
    if !self { return try closure() }
    return nil
  }
}

But this is more a personal preference.

—— 

That said, if the community is fine with the `invert/inverted` pair then I’d 
say go for it ;)
Am 12. Januar 2018 um 09:14:22, Nate Cook via swift-evolution 
(swift-evolution@swift.org) schrieb:


On Jan 12, 2018, at 12:15 AM, Chris Eidhof via swift-evolution 
 wrote:

Hey SE!

When we have a bunch of nested structs:

    struct Sample {
        var bar: Bar
    }
    
    struct Bar {
        var show: Bool
    }
    
    var foo = Sample(bar: Bar(show: false))

It can be repetitive to toggle a deeply nested boolean:

    foo.bar.show = !foo.bar.show // duplication

I sometimes add a `toggle` extension on `Bool`

    extension Bool {
        mutating func toggle() {
            self = !self
        }
    }

This allows you to write the same code without duplication, and makes the 
intent clearer:

    foo.bar.show.toggle()

I like it!

In other languages, I don't think the `toggle` would make as much sense, but 
the mutable self makes this very useful.

After I posted it on Twitter, it turns out I'm not the only one: 
https://twitter.com/PublicExtension/status/730434956376346624

I would have gone straight to a proposal, but I think we can do some 
bikeshedding about the name of `toggle`?

Another verb that could work is `invert`.

The `!` operator that does this is the negation operator, but I think `negate` 
could sound to some like "make this false" rather than toggling. 

Nate
___
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] [Review] SE-0194: Derived Collection of Enum Cases

2018-01-12 Thread Vladimir.S via swift-evolution

On 11.01.2018 1:54, Jordan Rose via swift-evolution wrote:

[Proposal: 
https://github.com/apple/swift-evolution/blob/master/proposals/0194-derived-collection-of-enum-cases.md]

I think this is generally reasonable, and none of the names offend me enough to weigh in on that discussion. I do think 
it's a little weird that @objc enums defined in Swift /cannot/ conform to ValueEnumerable, just because imported enums 
won't. (But especially while knee-deep in SE-0192, I think it's /correct/ that imported enums won't. The exception could 
be C enums marked `enum_extensibility(closed)`, but I'm not convinced we need that yet.)


The biggest problem I have is unavailable cases. An unavailable case /must not/ be instantiated—consider an enum where 
some cases are only available on iOS and not macOS. (I bet we optimize based on this, which makes it all the more 
important to get right.)


I think you should explicitly call out that the derived implementation only kicks in when ValueEnumerable is declared on 
the enum itself, not an extension. Or if that's not the case, it should be limited to extensions in the same module as 
the enum. (You could add "unless the enum is '@frozen'", but that's not really necessary.)




I'd also ask to append that information into the proposal, as IMO it is very 
important point.
I was under impression that we'll be allowed to retroactively conform to ValueEnumerable for frozen enums from other 
modules. Wouldn't this be a very requested feature of ValueEnumerable ? I.e. when we have a module with frozen enum, but 
author of that enum didn't consider conforming to ValueEnumerable for some reason.


Vladimir.

I don't think this should be implemented with a run-time function; compile-time code generation makes more sense to me. 
But that's an implementation detail; it doesn't change the language surface.


Jordan


___
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] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Vladimir.S via swift-evolution

On 12.01.2018 10:30, Chris Lattner via swift-evolution wrote:



On Jan 11, 2018, at 11:15 PM, Jean-Daniel via swift-evolution 
 wrote:

A question about the new #unknown behavior. Is it intended to be used for error 
handling too ?
Will it be possible to use in catch clause ?


If we go with the #unknown approach, then yes of course it will work in catch 
clauses.  They are patterns, so it naturally falls out.

If we go with the “unknown default:” / “unknown case:"  approach, then no, this 
has nothing to do with error handling.

IMO, this pivots on the desired semantics for “unknown cases in enums”: if you 
intentionally try to match on this, do we get a warning or error if you don’t 
handle all the cases?  If we can get to consensus on that point, then the 
design is pretty obvious IMO.


For me the other question is what "all the cases" means for enum with private cases(if we'll have them). I.e. if switch 
contains all the "public" cases of frozen enum - does this mean "all the cases" were processed? As I understand, the 
answer is no, because we *can* have 'private' case value here and so we need to react to this. How switch will look in 
this case?


switch frozenEnumWithPrivateCases {
  case .one: ..
  case .two: ..
  unknown default: ..  // or 'case #unknown:' depending on our decision, or 
'unknown case:' etc
}
?
But then such switch looks exactly as switch for non-frozen enum value, no? It looks like we are reacting on future new 
cases, while enum is frozen.


Moreover. How the switch for non-frozed enum with private cases should looks 
like?

switch nonfrozenEnumWithPrivateCases {
  case .one: ..
  case .two: ..
  unknown default: ..  // or 'case #unknown:' depending on our decision, or 
'unknown case:' etc
}
? But then, is that 'unknown default' for reacting on "future" cases we didn't know about during the compilation OR it 
is for reacting on private cases?


Or the main idea that we don't want to separate "future" cases and "private" cases? Then still the first 'switch' on 
frozen enum confuses the reader.


I understand that we are not discussing the 'private' cases yet, but IMO we should consider how new 'case 
#unknown/unknown default' will be used in case we'll add that feature.


Vladimir.



-Chris

___
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] adding toggle to Bool

2018-01-12 Thread Nate Cook via swift-evolution

> On Jan 12, 2018, at 12:15 AM, Chris Eidhof via swift-evolution 
>  wrote:
> 
> Hey SE!
> 
> When we have a bunch of nested structs:
> 
> struct Sample {
> var bar: Bar
> }
> 
> struct Bar {
> var show: Bool
> }
> 
> var foo = Sample(bar: Bar(show: false))
> 
> It can be repetitive to toggle a deeply nested boolean:
> 
> foo.bar.show = !foo.bar.show // duplication
> 
> I sometimes add a `toggle` extension on `Bool`
> 
> extension Bool {
> mutating func toggle() {
> self = !self
> }
> }
> 
> This allows you to write the same code without duplication, and makes the 
> intent clearer:
> 
> foo.bar.show.toggle()

I like it!

> In other languages, I don't think the `toggle` would make as much sense, but 
> the mutable self makes this very useful.
> 
> After I posted it on Twitter, it turns out I'm not the only one: 
> https://twitter.com/PublicExtension/status/730434956376346624
> 
> I would have gone straight to a proposal, but I think we can do some 
> bikeshedding about the name of `toggle`?

Another verb that could work is `invert`.

The `!` operator that does this is the negation operator, but I think `negate` 
could sound to some like "make this false" rather than toggling. 

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