Ehren Murdick
@rubyprogrammer
github.com/ehrenmurdick
Pyramid of errors
doc1 := entities.NewDocument("document 1") _, err := printDocument(doc1) if err != nil { printError(err) } else { _, err = saveDocument(doc1) if err != nil { printError(err) } }
Container!
type OptionalDocument interface { Try(func(Document) (Document, error)) OptionalDocument HandleErr(func(error) error) OptionalDocument }
func printDocument(d Document) (Document, error)
Using OptionalDocument
doc2 := entities.NewDocument("document 2") opt2 := optionals.WrapDocument(doc2) opt2. Try(printDocument). Try(saveDocument). HandleErr(printError)
Contain Anything
type OptionalAny interface { Try(f func(interface{}) (interface{}, error)) OptionalAny HandleErr(f func(error) error) OptionalAny }
func printAny(i interface{}) (interface{}, error)
Using OptionalAny
doc3 := entities.NewDocument("document 3") opt3 := optionals.WrapAny(doc3, nil) opt3. Try(printAny). Try(saveAny). HandleErr(printError)
An example in Swift
struct Stack<Item> { var items = [Item]() func pop() -> Item }
…is basically just generating…
struct StackInteger { var items = [Integer]() func pop() -> Integer }
struct StackString { var items = [String]() func pop() -> String }
We can generate too! (at build time)
//go:generate ./optional Document
type Optional<%= Item %> interface { Try(func(<%= Item %>) (<%= Item %>, error)) Optional<%= Item %> HandleErr(func(error) error) Optional<%= Item %> }
Using Optional<%= Item %>
doc3 := entities.NewDocument("document 2") opt3 := optionals.WrapDocument(doc2) opt3. Try(printDocument). Try(saveDocument). HandleErr(printError)