Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Jon Shier via swift-evolution
> Generic errors have caused me problems on multiple occasions.They often make 
> it difficult to handle and pass-through arbitrary errors. This pseudo Swift3 
> code is what I have resorted to doing on some projects. 
> 
> ```
> enum MyError : Error
> {
>   …
> 
>   case wrappedError( Error )
> }
> ```
> 
> I would go so far as to say that generic errors are an anti-pattern in Swift.

I wouldn’t call them an anti pattern, but they do force the user to 
make a decision about how they’re handling errors. Either everything is wrapped 
in their own custom error type at some point, or they just return NSErrors for 
everything. I preferred wrapping everything in my own type so handling was 
centralized and I knew my code exhaustively handled all cases. Of course I 
never used to the more advanced features of NSError. It certainly looks like 
this has to change now.

> On Aug 14, 2016, at 9:43 PM, Charles Srstka  wrote:
> 
> Is there something wrong with just returning a Swift.Error and using casting 
> to catch specific errors?

Fundamentally, I think there is, as it requires users know every type 
of error that could possibly be returned by an API to handle them exhaustively, 
or for users to create some sort of default behavior that may not be optimal or 
safe in all cases. Unfortunately I understand now that it’s largely unavoidable 
given the nature of NSError and error handling in Apple’s frameworks in 
general. So I’ve accepted that’s how we have to do it from now on. My recent 
questions, however, were merely seeking guidance as a framework developer. I’ve 
come to the conclusion that there isn’t really a better solution for Alamofire 
than removing the generic error parameter from the relevant types and letting 
Error bubble up from the underlying frameworks. Users can still wrap everything 
in a custom type that captures the underlying errors or handle everything 
manually. I guess there is no clever solution here.


Thanks everyone,

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Charles Srstka via swift-evolution
> On Aug 14, 2016, at 7:04 PM, Jon Shier  wrote:
> 
>   Yes, if you return a single error type it works fine. However, since 
> Alamofire wraps the underlying networking frameworks there’s a need to return 
> the errors returned from them as well, which are now returned as Error. In 
> order to let these errors be returned alongside Alamofire’s errors we’d 
> either have to get rid of the generic error and just use Error or wrap all 
> errors in our error type. So far the least painful method seems to be just 
> getting rid of the generic error and returning Error for everything. That way 
> users will use the same logic they would have had to use anyway and can also 
> provide their own error wrapper if they want. Thankfully (or unfortunately, 
> depending on your point of view), the new pattern is to cast out the various 
> error types, so the previous concern about having to do that is no longer an 
> issue.

Is there something wrong with just returning a Swift.Error and using casting to 
catch specific errors?

import Foundation

enum Result {
case success(Value)
case failure(Swift.Error)
}

struct StarTrek {
enum Error: Swift.Error, LocalizedError {
case insufficientData
case sheCannaTakeIt
case warpCoreBreach(minutes: Int)
case irrelevant
case mustSterilize

var failureReason: String? {
switch self {
case .insufficientData:
return "Insufficient data. Please specify parameters."
case .sheCannaTakeIt:
return "She canna take it anymore, Captain!"
case let .warpCoreBreach(minutes):
return "Warning: Warp core breach in \(minutes) minutes."
case .mustSterilize:
return "Error! Must Sterilize! Must 
Steeeiiiizzeee"
case .irrelevant:
return "Irrelevant. Resistance is futile."
}
}
}

static func engage(warpFactor: Int) throws {
throw Error.sheCannaTakeIt
}
}

struct SciFi {
enum Error: Swift.Error, LocalizedError {
case doesNotCompute
case imSorryDave
case fixedPointInTime
case gameOver
case endOfLine

var failureReason: String? {
switch self {
case .doesNotCompute:
return "Does Not Compute! Does Not Compute! Does Not Compute!"
case .imSorryDave:
return "I'm sorry Dave, I'm afraid I can't do that."
case .fixedPointInTime:
return "I'm sorry, I'm so sorry."
case .gameOver:
return "Game over man, game over!"
case .endOfLine:
return "End of Line!"
}
}
}

static func flyThroughSpace(isStarTrek: Bool, completionHandler: 
(Result) -> ()) {
if isStarTrek {
do {
try StarTrek.engage(warpFactor: 5)
completionHandler(.success("We have arrived at Rigel VII"))
} catch {
completionHandler(.failure(error))
}
} else {
completionHandler(.failure(Error.imSorryDave))
}
}
}

let completionHandler = { (result: Result) in
switch result {
case let .success(value):
print("returned '\(value)'")
case let .failure(error):
if let starTrekError = error as? StarTrek.Error {
print("Star Trek error: \(starTrekError.localizedDescription)")

if case .sheCannaTakeIt = starTrekError {
print("Scotty, I need more power!")
}
} else if let scifiError = error as? SciFi.Error {
print("Sci fi error: \(scifiError.localizedDescription)")

if scifiError == .imSorryDave {
print("Daisy... Daaiisy.")
}
} else {
print("Some other error: \(error.localizedDescription)")
}
}
}

SciFi.flyThroughSpace(isStarTrek: true, completionHandler: completionHandler)
SciFi.flyThroughSpace(isStarTrek: false, completionHandler: completionHandler)

Star Trek error: The operation couldn’t be completed. She canna take it 
anymore, Captain!
Scotty, I need more power!
Sci fi error: The operation couldn’t be completed. I'm sorry Dave, I'm afraid I 
can't do that.
Daisy... Daaiisy.
Program ended with exit code: 0

And of course, for synchronous APIs using try/catch, you can just use “catch 
error as StarTrek.Error” to get these.

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Christopher Kornher via swift-evolution
My 2 cents:

Generic errors have caused me problems on multiple occasions.They often make it 
difficult to handle and pass-through arbitrary errors. This pseudo Swift3 code 
is what I have resorted to doing on some projects. 

```
enum MyError : Error
{
…

case wrappedError( Error )
}
```

I would go so far as to say that generic errors are an anti-pattern in Swift.

- Chris 


> On Aug 14, 2016, at 6:04 PM, Jon Shier via swift-evolution 
>  wrote:
> 
>   Yes, if you return a single error type it works fine. However, since 
> Alamofire wraps the underlying networking frameworks there’s a need to return 
> the errors returned from them as well, which are now returned as Error. In 
> order to let these errors be returned alongside Alamofire’s errors we’d 
> either have to get rid of the generic error and just use Error or wrap all 
> errors in our error type. So far the least painful method seems to be just 
> getting rid of the generic error and returning Error for everything. That way 
> users will use the same logic they would have had to use anyway and can also 
> provide their own error wrapper if they want. Thankfully (or unfortunately, 
> depending on your point of view), the new pattern is to cast out the various 
> error types, so the previous concern about having to do that is no longer an 
> issue.
> 
> 
> Jon
> 
>> On Aug 14, 2016, at 4:18 AM, Charles Srstka > > wrote:
>> 
>>> On Aug 14, 2016, at 2:34 AM, Jon Shier >> > wrote:
>>> 
>>> Sorry Charles, I should’ve been more specific. This isn’t about some 
>>> other type named Error being usable, but about our doubly generic Result 
>>> and other types being usable with Error as the generic error type. If we 
>>> have Result defined as:
>>> 
>>> public enum Result {
>>> case success(Value)
>>> case failure(ErrorType)
>>> }
>>> 
>>> then attempting to create the type Result results in the 
>>> error message I posted. For methods that previously returned 
>>> Result, where the NSError is either a system error or an 
>>> Alamofire one, this is something of a problem. Of course, removing the 
>>> generic error type fixes this but may have an undesirable usability impact, 
>>> as making Result double generic was the primary reason behind the quick 
>>> upgrade between Alamofire 2 and 3. I think it’s less of a problem now, as 
>>> having to enumerate all of the different expected error types is how user’s 
>>> are supposed to interact with Error in the first place, but at the time it 
>>> wasn’t desirable to try and force everything through ErrorProtocol for that 
>>> reason. Perhaps this is a good compromise, where instead of returning all 
>>> NSErrors from the framework and allowing consumers to add their own to the 
>>> mix we’ll just create our own AFError type (whether enum or struct) and 
>>> then anything coming back will have to be checked for that type in addition 
>>> to the system types. From my testing it looks like users could still wrap 
>>> everything coming in by capturing the underlying Error.
>> 
>> Still seems to be working well, unless I’m misunderstanding what you’re 
>> trying to do:
>> 
>> import Foundation
>> 
>> enum Result {
>> case success(Value)
>> case failure(ErrorType)
>> }
>> 
>> struct MyThing {
>> enum Error: Swift.Error, LocalizedError {
>> case doesNotCompute
>> case imSorryDave
>> case mustSterilize
>> case irrelevant
>> case endOfLine
>> 
>> var failureReason: String? {
>> switch self {
>> case .doesNotCompute:
>> return "Does Not Compute! Does Not Compute! Does Not 
>> Compute!"
>> case .imSorryDave:
>> return "I'm sorry Dave, I'm afraid I can't do that."
>> case .mustSterilize:
>> return "Error! Must Sterilize! Must 
>> Steeeiiiizzeee"
>> case .irrelevant:
>> return "Irrelevant. Resistance is futile."
>> case .endOfLine:
>> return "End of Line!"
>> }
>> }
>> }
>> 
>> func trySomething(shouldWork: Bool, completionHandler: (Result> Error>) -> ()) {
>> if shouldWork {
>> completionHandler(.success("It worked!"))
>> } else {
>> completionHandler(.failure(Error.imSorryDave))
>> }
>> }
>> }
>> 
>> let thing = MyThing()
>> 
>> let completionHandler = { (result: Result) in
>> switch result {
>> case let .success(value):
>> print("returned '\(value)'")
>> case let .failure(error):
>> print("error: \(error.localizedDescription)")
>> }
>> }
>> 
>> thing.trySomething(shouldWork: true, 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-14 Thread Karl via swift-evolution

> On 14 Aug 2016, at 11:17, John Holdsworth via swift-evolution 
>  wrote:
> 
> Hi folks,
> 
> I see from building the latest Swift-3.0 branch that I’m a little behind the 
> times and this proposal has been accepted :(
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
> 
> Is there no way we can revisit this decision? 60 emails on a mail group not 
> read by the whole community
> doesn’t quite seem enough validation for such a significant change to me. Of 
> those that expressed an
> opinion on the thread many were against sealing classes outside the module. 
> 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160627/022364.html
> 
> I personally feel it's a huge mistake for the following reasons:
> 
> 1) it “breaks open source” reducing the reusability of third party software 
> by default.
> 
> 2) Contrary to arguments about the likely performance benefits of 
> de-virtualisation of method dispatch it is
> likely to make Swift programs launch more slowly due to the dynamic linker 
> having to slide large numbers
> of function pointers for most method calls (itself an expensive operation) 
> whether a call is even made.
> 
> On the first point it's an established technique in OOP to be able to 
> subclass and override to adapt a class
> for a role perhaps it’s author never considered. Call this “monkey-patching” 
> if you like but it is a part of being
> able to use open source libraries without having to make a fork as would be 
> the case if sealed by default.
> Are we expecting developers to remember to leave their classes (and methods?) 
> "open”? If they do feel
> that others shouldn’t subclass or override there was always “final". 
> Distinctions about whether this is possible
> inside or outside a module seem a mute point to me.
> 
> The second point is more of an engineering one. “Virtual” dispatch on Swift 
> is not a significant overhead
> compared to fully dynamic dispatch on Objective-C which even then was seldom 
> a problem. There is a
> cost however to de-virtualisation and resolving to a direct call to a method 
> address in that the dynamic
> linker has to resolve and slide the pointer on load. This type of concern is 
> a bad argument to use in 
> designing a language anyway even if it is called Swift.
> 
> Well, I know the boat has left on this one and I’ll likely have to live with 
> it but this is the proposal I
> most disagree with on evolution this far. Programmers have morals and just 
> because you shouldn’t
> do something doesn’t mean the language needs to turn that into can’t by 
> default when the need arises.
> If this change does go ahead please try to get it into the next Xcode beta as 
> it is a very incompatible one.
> 
> Cheers,
> 
> John
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

It we are happy with non-open != final, I would be in favour of some kind of 
monkey-patching import attribute, similar to @testable, which allows you to 
subclass non-open classes at your own risk.

I would be doubly-happy if we were to call it "@monkey-patched import UIKit"

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


Re: [swift-evolution] Swiftier implementation of Measurement and Unit

2016-08-14 Thread Karl via swift-evolution

> On 11 Aug 2016, at 00:51, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Probably swift-corelibs-dev would be the forum for that? IIUC correctly, 
> though, the current goal for corelibs-foundation is to vend the exact same 
> API as Apple Foundation. I'd also be curious as to when it would be 
> appropriate to start exploring Swiftier implementations.
> 
> On Wed, Aug 10, 2016 at 3:59 PM, Joanna Carter via swift-evolution 
> > wrote:
> I have spent some time working on a version of the Measurement and Unit held 
> in the apple/swift-corelibs-foundation section of GitHub. How can I best find 
> out if my efforts are worthwhile?
> 
> Joanna
> ___
> 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

I think that deadline may have already passed with the new value-type API in 
Swift 3.

There are some parts that haven’t been brought over - such as 
NSRegularExpresion, because I believe the plan is to do something special with 
those.

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


Re: [swift-evolution] Swiftier implementation of Measurement and Unit

2016-08-14 Thread Silvan Mosberger via swift-evolution
I do have a small (WIP) framework for working with units and measurement, which 
I think has he basic idea right. Here is the link for anyone interested 
https://github.com/Infinisil/SwiftUnits/blob/master/README.md

> On 11 Aug 2016, at 00:51, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Probably swift-corelibs-dev would be the forum for that? IIUC correctly, 
> though, the current goal for corelibs-foundation is to vend the exact same 
> API as Apple Foundation. I'd also be curious as to when it would be 
> appropriate to start exploring Swiftier implementations.
> 
>> On Wed, Aug 10, 2016 at 3:59 PM, Joanna Carter via swift-evolution 
>>  wrote:
>> I have spent some time working on a version of the Measurement and Unit held 
>> in the apple/swift-corelibs-foundation section of GitHub. How can I best 
>> find out if my efforts are worthwhile?
>> 
>> Joanna
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-14 Thread Félix Cloutier via swift-evolution
There was an order of magnitude more than 60 emails about this. In my inbox, I 
count 452 emails that have 0117 in the title. Discussion had already started 
before the proposal and I'm not counting these.

Félix

> Le 14 août 2016 à 02:17:36, John Holdsworth via swift-evolution 
>  a écrit :
> 
> Hi folks,
> 
> I see from building the latest Swift-3.0 branch that I’m a little behind the 
> times and this proposal has been accepted :(
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
> 
> Is there no way we can revisit this decision? 60 emails on a mail group not 
> read by the whole community
> doesn’t quite seem enough validation for such a significant change to me. Of 
> those that expressed an
> opinion on the thread many were against sealing classes outside the module. 
> 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160627/022364.html
> 
> I personally feel it's a huge mistake for the following reasons:
> 
> 1) it “breaks open source” reducing the reusability of third party software 
> by default.
> 
> 2) Contrary to arguments about the likely performance benefits of 
> de-virtualisation of method dispatch it is
> likely to make Swift programs launch more slowly due to the dynamic linker 
> having to slide large numbers
> of function pointers for most method calls (itself an expensive operation) 
> whether a call is even made.
> 
> On the first point it's an established technique in OOP to be able to 
> subclass and override to adapt a class
> for a role perhaps it’s author never considered. Call this “monkey-patching” 
> if you like but it is a part of being
> able to use open source libraries without having to make a fork as would be 
> the case if sealed by default.
> Are we expecting developers to remember to leave their classes (and methods?) 
> "open”? If they do feel
> that others shouldn’t subclass or override there was always “final". 
> Distinctions about whether this is possible
> inside or outside a module seem a mute point to me.
> 
> The second point is more of an engineering one. “Virtual” dispatch on Swift 
> is not a significant overhead
> compared to fully dynamic dispatch on Objective-C which even then was seldom 
> a problem. There is a
> cost however to de-virtualisation and resolving to a direct call to a method 
> address in that the dynamic
> linker has to resolve and slide the pointer on load. This type of concern is 
> a bad argument to use in 
> designing a language anyway even if it is called Swift.
> 
> Well, I know the boat has left on this one and I’ll likely have to live with 
> it but this is the proposal I
> most disagree with on evolution this far. Programmers have morals and just 
> because you shouldn’t
> do something doesn’t mean the language needs to turn that into can’t by 
> default when the need arises.
> If this change does go ahead please try to get it into the next Xcode beta as 
> it is a very incompatible one.
> 
> Cheers,
> 
> John
> 
> 
> ___
> 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] Sealed classes by default

2016-08-14 Thread Chris Lattner via swift-evolution

> On Aug 14, 2016, at 5:59 AM, Jean-Denis Muys via swift-evolution 
>  wrote:
> 
> I for one would very much like this discussion to start again.

To set expectations here, we are beyond the end of source breaking changes for 
Swift 3, so they cannot be changed for Swift 3.  We plan to have ways to take 
limited source breaking changes in Swift 4, but don't know the scope of them 
because we haven’t designed the mechanism, and don’t know what scope it will 
allow.

This is all a way of saying that we *cannot* change this right now, and that 
discussing it is pointless.

>From another perspective, I will point out that this was a carefully 
>considered decision with much active debate, so unless there is *new* 
>information that comes to light, it won’t be reopened.

-Chris

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-14 Thread Jean-Denis Muys via swift-evolution
I for one would very much like this discussion to start again.

Yes it was discussed. Unfortunately, it was discussed in a summer time when in 
my country at least, many of us are off the grid for vacation. This is not a 
criticism of the process of course, just an indication that not everyone may 
have had the chance to voice their concerns.

As I expressed it already, even after reading all the arguments for the 
decision, I stand convinced that this decision is a tragic mistake. Note that I 
agree with many of the given rationales. I just think that the decision doesn't 
follow.

I will not rehash everything, but I will make a couple of points that may not 
have been expressed stridently enough:

- many many many people expressed contrary voices, and where shut up by the 
core team's expressing their opinion in favor of preventing subclassability by 
default. See a small sample at 
http://mjtsai.com/blog/2016/07/17/swift-classes-to-be-non-publicly-subclassable-by-default/

- One reason I (and others) gave is that I would not trust any programmer 
(least of which myself) to have the double sight ability to foresee every use 
of their classes/libraries. One disingenuous answer to that was "if you don't 
trust the programmer, why do you use their code to begin with?". Well, I don't 
trust my spouse's ability to forecast the time it takes to drive from place A 
to place B. Yet I will not break up over that. Time and time again, I have 
heard Apple executives praise us developers for the use of Apple's technology 
that they would never have foreseen. This decision goes totally contrary to 
those praises.

This decision is bad, not because it makes the default for classes to be 
unsubclassable, but because it puts the power of final decision into the wrong 
hands: the library author's. 

As a result, guidelines everywhere will eventually mandate for library authors 
to make everything "open", exactly as the guidelines for public C++ classes is 
often to make methods virtual. This will nullify much of the benefits of the 
decision.

The final programmer, the client programmer who uses the class should have the 
final say. The class author is entitled to express "beware, you will likely 
shoot yourself in the foot". But the final programmer should have the power to 
answer "thanks for saying. Now give me that gun."

My hope is that we can give back the final say to the final programmer through 
an additive Swift evolution proposal down the line, which would explicitly 
allow her to "force open" a closed class. I believe that such an addition would 
right the wrong while still keeping he benefits of the decision.

I don't think that such a proposal would affect the ABI, so it seems to me this 
is not yet the time to come up with such a proposal. I may be wrong on that 
though: I am quite unclear on what does or does not affect the ABI. 

To conclude let me give you an anecdote: I was writing this in-house iPhone app 
for a client, that used the common UITabViewController UI model. We had 5 tabs 
and 5 icons and all was good. Then the client asked for a new feature into a 
new 6th tab and wanted a 6th icon to be squeezed in the tab bar. The Apple's UI 
guidelines the, and the UITabViewController class precluded that (it may have 
changed since, I haven't developed for iOS in quite a while). However user 
testing showed that it was quite OK to put 6 icons there. I was able to 
subclass UITabViewController to accommodate for that, despite the fact the it 
was not only not designed for that, but also actively designed to prevent that.

Now there are many reasons why it could be claimed that what I did was wrong. 
And I would agree with those I suspect. However, that I could do it (pondering 
all factors) was actually the difference between "yes but" and "no way". As a 
result, my customer was another happy Apple user.

With Swift and that decision, this would not have happened, and we would all 
have been the poorer for it.

I hope I that this additive proposal I mentioned above can see the light of day 
in due time.

Best regards,

Jean-Denis


> On Aug 14, 2016, at 14:26, Goffredo Marocchi via swift-evolution 
>  wrote:
> 
> You are not familiar with us Italians and our love for (hopefully reasonable) 
> arguing I see ;). I  commit to and accept the decision taken, but it remains 
> a decision I disagree with and something that will probably birth a painful 
> fork once say Android and/or other big corporations moved to Swift and 
> decided for example that they wanted a new set of rules.
> 
> Sent from my iPhone
> 
>> On 14 Aug 2016, at 11:14, Jean-Daniel Dupas via swift-evolution 
>>  wrote:
>> 
>> 
>>> Le 14 août 2016 à 11:17, John Holdsworth via swift-evolution 
>>>  a écrit :
>>> 
>>> Hi folks,
>>> 
>>> I see from building the latest Swift-3.0 branch that I’m a little behind 
>>> the times and this proposal has been accepted :(

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-08-14 Thread Goffredo Marocchi via swift-evolution
You are not familiar with us Italians and our love for (hopefully reasonable) 
arguing I see ;). I  commit to and accept the decision taken, but it remains a 
decision I disagree with and something that will probably birth a painful fork 
once say Android and/or other big corporations moved to Swift and decided for 
example that they wanted a new set of rules.

Sent from my iPhone

> On 14 Aug 2016, at 11:14, Jean-Daniel Dupas via swift-evolution 
>  wrote:
> 
> 
>> Le 14 août 2016 à 11:17, John Holdsworth via swift-evolution 
>>  a écrit :
>> 
>> Hi folks,
>> 
>> I see from building the latest Swift-3.0 branch that I’m a little behind the 
>> times and this proposal has been accepted :(
>> 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
>> 
>> Is there no way we can revisit this decision? 60 emails on a mail group not 
>> read by the whole community
>> doesn’t quite seem enough validation for such a significant change to me.
> 
> 60 emails ?  You’re joking. It is more 600 emails than 60 that was send about 
> that proposal, and I’m pretty sure nobody want to see that discussion start 
> again.
> 
> 
> ___
> 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] Sealed classes by default

2016-08-14 Thread Jean-Daniel Dupas via swift-evolution

> Le 14 août 2016 à 11:17, John Holdsworth via swift-evolution 
>  a écrit :
> 
> Hi folks,
> 
> I see from building the latest Swift-3.0 branch that I’m a little behind the 
> times and this proposal has been accepted :(
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
> 
> Is there no way we can revisit this decision? 60 emails on a mail group not 
> read by the whole community
> doesn’t quite seem enough validation for such a significant change to me.

60 emails ?  You’re joking. It is more 600 emails than 60 that was send about 
that proposal, and I’m pretty sure nobody want to see that discussion start 
again.


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


[swift-evolution] [Proposal] Sealed classes by default

2016-08-14 Thread John Holdsworth via swift-evolution
Hi folks,

I see from building the latest Swift-3.0 branch that I’m a little behind the 
times and this proposal has been accepted :(

https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md

Is there no way we can revisit this decision? 60 emails on a mail group not 
read by the whole community
doesn’t quite seem enough validation for such a significant change to me. Of 
those that expressed an
opinion on the thread many were against sealing classes outside the module. 

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160627/022364.html

I personally feel it's a huge mistake for the following reasons:

1) it “breaks open source” reducing the reusability of third party software by 
default.

2) Contrary to arguments about the likely performance benefits of 
de-virtualisation of method dispatch it is
likely to make Swift programs launch more slowly due to the dynamic linker 
having to slide large numbers
of function pointers for most method calls (itself an expensive operation) 
whether a call is even made.

On the first point it's an established technique in OOP to be able to subclass 
and override to adapt a class
for a role perhaps it’s author never considered. Call this “monkey-patching” if 
you like but it is a part of being
able to use open source libraries without having to make a fork as would be the 
case if sealed by default.
Are we expecting developers to remember to leave their classes (and methods?) 
"open”? If they do feel
that others shouldn’t subclass or override there was always “final". 
Distinctions about whether this is possible
inside or outside a module seem a mute point to me.

The second point is more of an engineering one. “Virtual” dispatch on Swift is 
not a significant overhead
compared to fully dynamic dispatch on Objective-C which even then was seldom a 
problem. There is a
cost however to de-virtualisation and resolving to a direct call to a method 
address in that the dynamic
linker has to resolve and slide the pointer on load. This type of concern is a 
bad argument to use in 
designing a language anyway even if it is called Swift.

Well, I know the boat has left on this one and I’ll likely have to live with it 
but this is the proposal I
most disagree with on evolution this far. Programmers have morals and just 
because you shouldn’t
do something doesn’t mean the language needs to turn that into can’t by default 
when the need arises.
If this change does go ahead please try to get it into the next Xcode beta as 
it is a very incompatible one.

Cheers,

John


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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Charles Srstka via swift-evolution
> On Aug 14, 2016, at 2:34 AM, Jon Shier  wrote:
> 
>   Sorry Charles, I should’ve been more specific. This isn’t about some 
> other type named Error being usable, but about our doubly generic Result and 
> other types being usable with Error as the generic error type. If we have 
> Result defined as:
> 
> public enum Result {
> case success(Value)
> case failure(ErrorType)
> }
> 
> then attempting to create the type Result results in the 
> error message I posted. For methods that previously returned Result NSError>, where the NSError is either a system error or an Alamofire one, 
> this is something of a problem. Of course, removing the generic error type 
> fixes this but may have an undesirable usability impact, as making Result 
> double generic was the primary reason behind the quick upgrade between 
> Alamofire 2 and 3. I think it’s less of a problem now, as having to enumerate 
> all of the different expected error types is how user’s are supposed to 
> interact with Error in the first place, but at the time it wasn’t desirable 
> to try and force everything through ErrorProtocol for that reason. Perhaps 
> this is a good compromise, where instead of returning all NSErrors from the 
> framework and allowing consumers to add their own to the mix we’ll just 
> create our own AFError type (whether enum or struct) and then anything coming 
> back will have to be checked for that type in addition to the system types. 
> From my testing it looks like users could still wrap everything coming in by 
> capturing the underlying Error.

Still seems to be working well, unless I’m misunderstanding what you’re trying 
to do:

import Foundation

enum Result {
case success(Value)
case failure(ErrorType)
}

struct MyThing {
enum Error: Swift.Error, LocalizedError {
case doesNotCompute
case imSorryDave
case mustSterilize
case irrelevant
case endOfLine

var failureReason: String? {
switch self {
case .doesNotCompute:
return "Does Not Compute! Does Not Compute! Does Not Compute!"
case .imSorryDave:
return "I'm sorry Dave, I'm afraid I can't do that."
case .mustSterilize:
return "Error! Must Sterilize! Must 
Steeeiiiizzeee"
case .irrelevant:
return "Irrelevant. Resistance is futile."
case .endOfLine:
return "End of Line!"
}
}
}

func trySomething(shouldWork: Bool, completionHandler: (Result) -> ()) {
if shouldWork {
completionHandler(.success("It worked!"))
} else {
completionHandler(.failure(Error.imSorryDave))
}
}
}

let thing = MyThing()

let completionHandler = { (result: Result) in
switch result {
case let .success(value):
print("returned '\(value)'")
case let .failure(error):
print("error: \(error.localizedDescription)")
}
}

thing.trySomething(shouldWork: true, completionHandler: completionHandler)
thing.trySomething(shouldWork: false, completionHandler: completionHandler)

returned 'It worked!'
error: The operation couldn’t be completed. I'm sorry Dave, I'm afraid I can't 
do that.
Program ended with exit code: 0

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Jon Shier via swift-evolution
Sorry Charles, I should’ve been more specific. This isn’t about some 
other type named Error being usable, but about our doubly generic Result and 
other types being usable with Error as the generic error type. If we have 
Result defined as:

public enum Result {
case success(Value)
case failure(ErrorType)
}

then attempting to create the type Result results in the error 
message I posted. For methods that previously returned Result, where the NSError is either a system error or an Alamofire one, this 
is something of a problem. Of course, removing the generic error type fixes 
this but may have an undesirable usability impact, as making Result double 
generic was the primary reason behind the quick upgrade between Alamofire 2 and 
3. I think it’s less of a problem now, as having to enumerate all of the 
different expected error types is how user’s are supposed to interact with 
Error in the first place, but at the time it wasn’t desirable to try and force 
everything through ErrorProtocol for that reason. Perhaps this is a good 
compromise, where instead of returning all NSErrors from the framework and 
allowing consumers to add their own to the mix we’ll just create our own 
AFError type (whether enum or struct) and then anything coming back will have 
to be checked for that type in addition to the system types. From my testing it 
looks like users could still wrap everything coming in by capturing the 
underlying Error.



Jon

> On Aug 14, 2016, at 3:03 AM, Charles Srstka  wrote:
> 
>> On Aug 14, 2016, at 1:18 AM, Jon Shier via swift-evolution 
>> > wrote:
>> 
>>  An immediate problem I’m seeing is the error: using 'Error' as a 
>> concrete type conforming to protocol 'Error' is not supported, which means 
>> we can’t use Error in our Result or Response types, as both the value and 
>> error types are generic there. I’m guessing we’ll have to either remove the 
>> generic error type, which would greatly impact consumer’s ability to use our 
>> APIs with their own custom errors, or wrap all errors in our own error type, 
>> which is terrible for a few reasons. Or just keep using NSError I guess. Any 
>> clever solutions here?
> 
> Works fine when I try it:
> 
> import Foundation
> 
> struct MyThing {
> enum Error: Swift.Error, LocalizedError {
> case doesNotCompute
> case imSorryDave
> case mustSterilize
> 
> var failureReason: String? {
> switch self {
> case .doesNotCompute:
> return "Does Not Compute! Does Not Compute! Does Not Compute!"
> case .imSorryDave:
> return "I'm sorry Dave, I'm afraid I can't do that."
> case .mustSterilize:
> return "Error! Must Sterilize! Must 
> Steeeiiiizzeee"
> }
> }
> }
> 
> func trySomething() throws {
> throw Error.doesNotCompute
> }
> }
> 
> let thing = MyThing()
> 
> do {
> try thing.trySomething()
> } catch {
> print(error.localizedDescription)
> }
> 
> Outputs:
> 
> The operation couldn’t be completed. Does Not Compute! Does Not Compute! Does 
> Not Compute!
> 
> Charles
> 

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Charles Srstka via swift-evolution
> On Aug 14, 2016, at 1:18 AM, Jon Shier via swift-evolution 
>  wrote:
> 
>   An immediate problem I’m seeing is the error: using 'Error' as a 
> concrete type conforming to protocol 'Error' is not supported, which means we 
> can’t use Error in our Result or Response types, as both the value and error 
> types are generic there. I’m guessing we’ll have to either remove the generic 
> error type, which would greatly impact consumer’s ability to use our APIs 
> with their own custom errors, or wrap all errors in our own error type, which 
> is terrible for a few reasons. Or just keep using NSError I guess. Any clever 
> solutions here?

Works fine when I try it:

import Foundation

struct MyThing {
enum Error: Swift.Error, LocalizedError {
case doesNotCompute
case imSorryDave
case mustSterilize

var failureReason: String? {
switch self {
case .doesNotCompute:
return "Does Not Compute! Does Not Compute! Does Not Compute!"
case .imSorryDave:
return "I'm sorry Dave, I'm afraid I can't do that."
case .mustSterilize:
return "Error! Must Sterilize! Must 
Steeeiiiizzeee"
}
}
}

func trySomething() throws {
throw Error.doesNotCompute
}
}

let thing = MyThing()

do {
try thing.trySomething()
} catch {
print(error.localizedDescription)
}

Outputs:

The operation couldn’t be completed. Does Not Compute! Does Not Compute! Does 
Not Compute!

Charles

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


Re: [swift-evolution] [Accepted] SE-0112: Improved NSError Bridging

2016-08-14 Thread Jon Shier via swift-evolution
An immediate problem I’m seeing is the error: using 'Error' as a 
concrete type conforming to protocol 'Error' is not supported, which means we 
can’t use Error in our Result or Response types, as both the value and error 
types are generic there. I’m guessing we’ll have to either remove the generic 
error type, which would greatly impact consumer’s ability to use our APIs with 
their own custom errors, or wrap all errors in our own error type, which is 
terrible for a few reasons. Or just keep using NSError I guess. Any clever 
solutions here?



Jon
 
> On Aug 14, 2016, at 1:41 AM, Jon Shier  wrote:
> 
> Doug, et. al.:
>   Thanks for the discussion so far; I think I understand the new error 
> model from a user’s perspective. However, now I’m looking for some guidance 
> for framework developers. While the proposal laid out the system types would 
> wrap imported Objective-C errors, I don’t see anything for the desired 
> patters for Swift native errors. For instance, in Alamofire we currently 
> either pass through the NSErrors we receive from underlying frameworks or 
> generate our own, usually in our own domain, with unique error codes and 
> such. I can see my way to translating most of these directly to an AFError 
> type that conforms to Error, but some of them require associated values (e.g. 
> the content type validation error needs to know the expected and actual 
> content types). In these cases I’m having a hard time see how these things 
> should be stored, especially when only some cases need this data. Of course, 
> I’m away of the LocalizedError protocol, but that doesn’t seem applicable 
> here, as I’m mostly wondering about storage. Rather than creating types 
> similar to the system error types, perhaps a basic enum based error would 
> work, where only the cases that need it capture values? I’m mostly curious 
> what the anticipated pattern was here.
> 
> 
> 
> Jon
> 
>> On Aug 6, 2016, at 1:15 AM, Kevin Ballard via swift-evolution 
>> > wrote:
>> 
>>> 
>>> On Aug 5, 2016, at 7:36 PM, Erica Sadun >> > wrote:
>>> 
>>> On Aug 5, 2016, at 8:10 PM, Kevin Ballard >> > wrote:
 
> 
> On Aug 5, 2016, at 5:16 PM, Erica Sadun  > wrote:
> 
> 
>> On Aug 5, 2016, at 4:19 PM, Douglas Gregor via swift-evolution 
>> > wrote:
>> 
>>> 
>>> On Aug 5, 2016, at 12:59 PM, Kevin Ballard via swift-evolution 
>>> > wrote:
>>> 
>>> If all you want to do is get the localized description, then you can 
>>> just say `(error as NSError).localizedDescription`.
>> 
>> Just ‘error.localizedDescription’ works now. That was part of SE-0112.
>> 
>>  - Doug
> 
> Would it kill to allow:
> 
> let err = NSError()
> err.localizedDescription = "bad things happen"
> throw err
> 
> or even
> 
> throw NSError("Bad things happen")
> 
> for lightweight use? I ended up refactoring entirely to enum : Error 
> because Swift yelled at me for using NSError(): "this results in an 
> invalid NSError instance. It will raise an exception in a future release. 
> Please call errorWithDomain:code:userInfo: or 
> initWithDomain:code:userInfo:. This message shown only once."
> 
> enum Errors: Error {case bad}
> Errors.bad._code // 0
> Errors.bad._domain // "Errors"
> Errors.bad._userInfo // Optional({})
> Errors.bad.localizedDescription // "The operation couldn’t be completed. 
> (Errors error 0.)"
> 
> Bleh.
 
 NSErrors need a domain/code. It doesn’t make much sense to throw one 
 without it. And besides, there’s a fairly trivial solution for doing what 
 you want to do:
 
 struct GenericError: LocalizedError {
 let message: String
 init(_ message: String) {
 self.message = message
 }
 var errorDescription: String? {
 return message
 }
 }
 
 Now you can just say `throw GenericError(“Bad things happen”)`.
 
 -Kevin Ballard
>>> 
>>> I know I can build workarounds but if we're going to have the 
>>> error.localizedDescription, making it an initializable/assignable property 
>>> just seems like a nice thing™. Why can't we have nice things™?
>> 
>> I don’t actually think it’s a nice thing™ to have it be assignable like you 
>> ask, because we should be encouraging people to use typed errors. You may as 
>> well just ask for String to conform to Error (in fact, you could just add 
>> that conformance yourself and skip the GenericError wrapper entirely).
>> 
>> -Kevin
>> ___
>>