4 ms·
It's not exactly the same as railway programming as in Swift it's typically not used to connect functions together but rather to replace separate callbacks with
by dep_b 8y ago
It's not exactly the same as railway programming as in Swift it's typically not used to connect functions together but rather to replace separate callbacks with one "result" function and to hard type certain results. One typical case in Objective-C style API's would be:
- (void)fetchData whenDone finished: [a block] ifFails failed: [another block]
Or:
- (void)fetchData whenDone finished: [a block that has nullable Data and nullable error as parameters]
Both approaches had problems. The first one uses two result blocks, but you want to do a lot of the same stuff usually, like:
* Stop the spinner
* Enable the send button again
This often lead to repetitive code or a maze of function calls.
The second one made you basically duck type for the kind of response it really was. Does it have an error? It probably failed. Does it have data? It probably worked. But what if it has both data and an error (error data?) or simply both values were nil? Brittle code.
While I really like the railroad approach the typical problem area Swift is applied to (often web API driven iOS and macOS applications) simply don't lead to these huge chains of functions. I'm definitely going to try it for backend code though.
- nine_k 8y agoYou don't need huge chains. Also, compare it to the interface of Futures.
- bonesss 8y ago> web API driven iOS and macOS applications) simply don't lead to these huge chains of functions I agree you don't see them collected together, as a rule, but if you follow Results<> like this in those domains you see them being used multiple times on the backend before being yeilded to the frontend for further handling, resulting in chains that are just spread out a little bit more. Personally I've started exposing them through JSON at the API level to further extend the systems explicitness and idempotency.