> Am 14.05.2016 um 09:31 schrieb Charles Srstka via swift-evolution 
> <[email protected]>:
> 
> I don’t think Cocoa is going away for a very, very long time. Even if it did, 
> you’d still need some consistent way to turn an ErrorType into something 
> human-readable, and currently we don’t have that. NSError’s userInfo field 
> actually does a fairly decent job, aside from the absurdly long constant 
> names.

I think Apple's Chief Deprecating Officer is already getting nervous and that 
point in time may be sooner. IMHO it's one of the big pains of Apple 
development that you have to learn new stuff every year, because oftentimes 
APIs are changed for no convincing reasons. Or one API is removed and a new API 
introduced, with no migration time. It's one of the reasons why I sometimes 
think about leaving the Apple platform as a developer (where I could go to is 
another question..). Having to adapt a program every two years at least just to 
keep it compiling is not programmer friendly. It's a good playground for 
language developers though. With Swift 3 it's a similar problem. At a company I 
work, we decided not to use Swift yet, because of Swift 3. Because with Swift 3 
everything has to be re-done, so we better wait until Swift 3 comes out. And 
even after Swift 3 will be released, we will probably wait until the mid of 
2017, just to be really sure that no breaking changes are planned and no "Swift 
4" is coming. Until that point I'm going to use Swift only for small or 
educational projects (I'm currently writing a game in Swift on iOS). IMHO it 
would be nice to have a language that is *stable* and that keeps stable for at 
least 10 years. But can Swift really ever become fully stable? Or will it be 
replaced with something else as soon as it becomes stable, in the same way it 
is happening to Objective-C now?</rant>

For interoperability, ErrorType and NSError should be toll-free-bridged, like 
CFStringRef and NSString. Converting between them should be a no-op at runtime. 
I prefer runtime/ABI consistency over syntax/language consistency. MyErrorType2 
should be represented as an NSError with domain @"MyErrorType2", whatever code 
is defined in that error type, and if you want userInfo you have to create the 
beast as an NSError object in the first place. I think userInfo is not visible 
in the Swift-enum-representation. If you want to have a Swift Error 
representation that includes userInfo, you'd have to either change the 
architecture or introduce special support on the language level (e.g. a magic 
`er.userInfo` of type `Dictionary<String,AnyObject>` for every `er: ErrorType` 
and a `er.withUserInfo(userInfo)` to add a userInfo dictionary to an error 
type: e.g. 
`MyErrorType2.fooConditionFound.withUserInfo([NSLocalizedDescriptionKey: "that 
was really bad"])` and maybe even a convenience method as a protocol extension 
like `MyErrorType.fooConditionFound.withLocalizedDescription(localizedString: 
"ReallyBad")`. And the key of a dictionary should really always be a String, 
not just an NSObject.)

(I know if you have something like `case SpecialError(Int)` in your ErrorType 
declaration, the above method does not work; you'd have to create an 
NSError-subclass for it. Or maybe not? Just add a "SpecialError_arg0" key to 
userInfo, value can be an NSNumber? There are more edge cases here but they are 
all solvable.)

On the other hand, I don't think that enumerations in general should support 
instance variables. One of the nice things for an enum is that I as a 
programmer can always be sure that it *is* just an enum, and nothing else. 
Adding iVars to enums would effectively turning enums to structs, and each time 
I see a switch statement I'll have to think "is this really all? or is there 
some stealth value attached to this enum? is every .MadeAMistake object always 
the same?" Keeping the inconsistency constrained to the ErrorType is much nicer 
than turning every enum into a struct.

There will always be rough edges when converting between two languages, that's 
unavoidable. Try to translate a text that contains a lot of the words "safety" 
and "security" into German. Good luck, they both translate to the same word. 
And so there also cannot be a perfectly consistent translation between 
ErrorType and NSError. If you want to achieve a good translation, you'd have to 
change the ErrorType to something different. E.g. a special language construct 
`def-error MyErrorType { case MadeAMistake; case RanOutOfCake }` - matching 
works the same as now and you have a userInfo property. And on 
non-objc-platforms, the NSError() name becomes unavailable and .userInfo always 
returns `[:]`. I'm not saying that this would be a beautiful solution; I'm 
saying that there is no beautiful solution to this problem.

Regards,
Michael

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to