Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Swift Poem: Why I prefer typed error (for

Typed error can be useful in certain cases, especially when accompanied with NoError type.

For example, in reactive programming, (typed error) allows us to create UI bindings only if Error is NoError, i.e.:

static func <~ <Source: BindingSource> (provider: Self, source: Source) -> Disposable? 
    where Source.Value == Value, Source.Error == NoError { ... }
// example
let alphaSignal: Signal<CGFloat, NoError> = ...
view.reactive.alpha <~ alphaSignal

This makes sense since UI binding only requires values to be sent, and not for errors. Signal<T, NoError> clearly defines that this instance will never send error during its lifetime.

On the contrary, in (untyped error) for example, we need some runtime check (e.g. fatalError("don't send error")) before making a safe(?) UI binding, since Observable<T> doesn't guarantee it doesn't emit error. That's why there are many attempts to ease the situation, e.g. Driver, PublishRelay, etc, but I don't think there could be any best compile-time solution for this problem without the help of type-system. (There's ongoing discussion in for more detail)

Obviously, this can be said for Result<T, E> type as well. Result<T, NoError> will express the success-only data, and this is also useful when there is a function that converts from Signal<T, NoError> to Result<T, NoError>, e.g. ReactiveSwift's SignalProducer.single().

Without Result<T, NoError>, the implementation of func single() -> Result<Value, Error>? will probably be splitted into 2 overloaded methods:

extension SignalProducer {
	public func first() -> Result<Value>? { ... }
extension SignalProducer where Error == NoError {
	// NOTE: We don't want to use `Result<Value>?` as return type 
	// because we already know it doesn't emit error.
	public func first() -> Value? { ... }

which will be :sadtroll:.


This comment has been minimized.

Copy link
Owner Author

@inamiy inamiy commented Nov 22, 2017

Slide (in Japanese): Result V.S. Result<T, E> // Speaker Deck

In the talk, I gave the above example code to illustrate:

  • How Result<T> fails the abstraction of parametric polymorphism by having boring overloaded code
  • Result<Value, NoError> is isomorphic to Value
  • How NoError is important for Non- Error-handling as well
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment