[swift-evolution] [Pitch] Consistent bridging for NSErrors at the language boundary

Shawn Erickson shawnce at gmail.com
Mon Jun 20 12:51:16 CDT 2016


I am curious on the disposition of this discussion / proposal pitch. Has
any additional effort taken place since this email thread tampered off?

On Sat, May 14, 2016 at 2:40 AM Charles Srstka via swift-evolution <
swift-evolution at swift.org> wrote:

> On May 14, 2016, at 3:51 AM, Michael Peternell <michael.peternell at gmx.at>
> wrote:
>
>
> For interoperability, ErrorType and NSError should be toll-free-bridged,
> like CFStringRef and NSString. Converting between them should be a no-op at
> runtime.
>
>
> That would be technically infeasible without restricting ErrorType to
> reference types using the Objective-C runtime, which I don’t think anyone
> wants to do.
>
> 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")`.
>
>
> Adding a userInfo property to the protocol declaration (with a default
> implementation for those that don’t want to implement it) would solve this
> without any low-level hacking.
>
> And the key of a dictionary should really always be a String, not just an
> NSObject.)
>
>
> I actually agree; I used [NSObject : AnyObject] since that’s what
> NSError’s userInfo is currently defined as. Putting [String : AnyObject] in
> the protocol instead would be fine, although you’d have to do a little
> sanity checking in the bridging to filter out non-string keys from the
> dictionary.
>
> (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.
>
>
> Adding instance variables to enums is not necessary for this. The userInfo
> here can be implemented as a computed property, as it would be in enums (in
> classes and structs, of course, it would be up to the developer whether to
> make it a stored or computed property).
>
> 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.
>
>
> I think that creating wrappers for both directions could work pretty well
> if we had a userInfo property on ErrorType/Protocol. We’ve got one going in
> one direction already.
>
> Charles
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160620/76d74157/attachment.html>


More information about the swift-evolution mailing list