Monday, January 12, 2015

SwiftFilePath

Norihiro Sakamoto’s SwiftFilePath provides Path objects with methods for functionality from NSFileManager (via Swift Toolbox). I’ve long used a similar pattern, creating Objective-C categories on NSString and then NSURL. The idea potentially works even better in Swift, although Sakamoto’s code regrettably converts all the NSError objects to strings.

4 Comments RSS · Twitter

"Sakamoto’s code regrettably converts all the NSError objects to strings."

Even worse: it returns a Result object, on which you must call isSuccess/isError and pull out the relevant value after that. Ugh.

These sorts of anti-patterns are why we don't deserve nice things, like sum types.

Actually, looks like the SwiftFilePath documentation is wrong: it describes Result as an Object, but from examining the code itself it is actually defined as an enum - but then bogged full of cruddy "helper" methods like init, isSuccess, isFailure, etc. instead of just using the language as it was designed to be used.

So it's basically as bloated and brain-damaged as using an Object, without actually using an Object. Which I think is even worse. Whatever Java diploma mill reject initially invented this anti-pattern really deserves to be shot, although I think the Swift designers themselves are also heavily to blame for not clearly establishing a standard pattern (and appropriate built-in Result type) to begin with, and for not nipping this crap in the bud as soon as it first appeared.

One of the trickiest and most crucial parts of language design isn't choosing and implementing features, it's ensuring that users will clearly and correctly understand how those features can and should be used; and making damn sure any user misconceptions are addressed and eliminated before they can escape to the wild to become standard community "wisdom".

The popular computing world is already full of such out-of-control horrors (e.g. see every C buffer overrun ever, or the entire unholy screwup that is today's Web); it'd be a shame to see Swift fall into the same History of Fail as well.

@has Result is declared as a sum type (enum). However, there is an extra layer where both sides of the Result are ResultContainer objects, rather than the actual value and error. I think he’s doing this to work around a current limitation of the Swift compiler where it needs the enum type parameters to be of known sizes. The helper methods are then needed to hide this extra layer from the user.

Incidentally, one of the things I really like is the ability to return either a result or an error value without being required to explicitly handle the error case every time. Where the user doesn't provide their own error handling code, the compiler should automatically insert behavior to raise that error to a permanent exception, thus terminating the program with a suitable error message and trace. This'd be particularly useful both during program development and when doing quick-n-dirty "scripting", where you don't want to waste lots of time implementing comprehensive error handling on code that's still highly unstable or essentially throwaway.

Leave a Comment