Skip to content

Instantly share code, notes, and snippets.

@erica
Created November 15, 2016 03:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erica/3daa8ec77aef2feaefca3a3a19aedee3 to your computer and use it in GitHub Desktop.
Save erica/3daa8ec77aef2feaefca3a3a19aedee3 to your computer and use it in GitHub Desktop.

Introducing Unwrappable

  • Proposal: TBD
  • Author: TBD
  • Status: TBD
  • Review manager: TBD

Introduction

This proposal introduces an Unwrappable protocol and the supporting technology that allows associated-type enumerations to support unwrapping beyond the Optional type.

Swift-evolution thread: TBD

Motivation

Optional magic should not be limited to the Optional type. Removing unwrapping support from the compiler into the standard library will allow Swift to simplify compiler details and unify its optional-specific behaviors like chaining, nil coalescing (??), if let, forced unwrap (!), etc, enabling their repurposing for additional types as well as optionals.

Using a protocol for Unwrappable instead of a single generic enum or struct (as with Optional) supports more complex cases and greater overall flexibility.

Detailed Design

This protocol design allows a conforming type to unwrap a single associated value type.

protocol Unwrappable {
    associatedtype Element
    func unwrap() -> Element?
}

Unwrappable types declare their preference for a single unwrapped type like the some case for Optional and the success case in a (yet to be designed) result type, e.g. enum Result<T> { case success(T), failure(Error) }. Adopting Unwrappable allows conforming types to inherit many behaviors currently limited to optionals.

Conforming Result to Unwrappable would enable you to introduce if let binding and functional chaining that checks for and succeeds with a success case (type T) but otherwise discards and ignores errors associated with failure (conforming to Error). Unwrappable allows you to shortcut, coalesce, and unwrap-to-bind as you would an Optional, as there's always a single favored type to prefer.

Unwrappable enables code to ignore and discard an error associated with failure, just as you would when applying try? to convert a thrown value to an optional. The same mechanics to apply to Optional would apply to Result including features like optional chaining, forced unwrapping and so forth.

The design of Unwrappable should allow an unpreferred error case to throw on demand and there should be an easy way to convert a throwing closure to a Result.

// Any throwing call or block can become a `Result`:
let myResult = Result(of: try myThrowingCall()) 

// Later (this could even be in a different thread)
let value = try unwrap myResult // throws on `failure`

Impact on Existing Code

This proposal will largely impact the compiler instead of end-users, who should not notice any changes outside of new standard library features.

Alternatives Considered

Not adopting this proposal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment