3 ms·
Swift 2 is fantastic except (har har) for exceptions. Optional<T> has been hanging out, monad-y and all, since v1. Why not Result<T, E>? You can't flatMap excep
by gorena 11y ago
Swift 2 is fantastic except (har har) for exceptions. Optional<T> has been hanging out, monad-y and all, since v1. Why not Result<T, E>? You can't flatMap exceptions, and the Swift 2 implementation even throws away type data (or hides it, at least). Huh?
- fyolnish 11y agoThere are no exceptions in swift.
- ridiculous_fish 11y agoI guess you mean the new do-try-catch syntax? IMO it's quite lovely, and strikes exactly the right balance between the checked exception tyranny of Java, and the strap-in-and-good-luck wild west of C++. My favorite feature of Swift's exceptions is the 'try' syntax required at the call site. This isn't like Java's try syntax: every call that may raise an exception needs a try, even if all you want to do is rethrow the exception. But the syntax is lightweight: just preface the call with 'try', it doesn't make a new scope. This makes the abnormal control flow explicit, addressing one of the strongest critiques of Java-style exceptions. My second favorite features is the 'try!' syntax. This is the escape hatch: Swift's version of the empty-catch-block pattern of Java, except that it's 1. much more lightweight, because it doesn't introduce a new scope, and 2. the default behavior is to abort instead of swallow. It's perfect for non-production code like tests. Regarding "you can't flatMap exceptions," I would respond that exceptions are meant to be exceptional, and this is what justifies the abnormal control flow. The do-try-catch syntax is an adequate substitute for flatMap, and more lightweight than requiring explicit unpacking of every return value ala Go. But as you say, the hiding of type data is definitely weird. For those following along at home, Swift requires explicitly annotating functions that may throw errors, but not what those errors are, so you have to refer to the documentation. Also the compiler will complain if you don't have a backstop exception handler. Lastly, it introduces a magic variable 'error' that is defined within catch blocks: convenient but it feels ad-hoc.
- gorena 11y agoWell, for example, try/catch don't work asynchronously, so you can't pass it to a callback (or use it in a SignalProducer in RAC). If failure/success is Just Another Value, it works everywhere that values work. That they already use an ADT for nullability it what confuses me - ".None, but with an error" isn't a far off concept from that. antitypical/Result already provides Result.init(() throws -> T) -> Result<T, E>, so it's easy enough to work around, at least. The magic variable stuff exists in didSet as well, weird and sketchy to use. Would prefer it to be explicit in all cases.