Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functions, A Love Story

Functions, A Love Story

Big, complex things are made out of many little, simple things—or least they should be. Simple things are easier to write, easier to debug, and easier to change. Functions are beautifully simple. Composing them lets us make big things out of small things. By thinking differently about app architecture, we can start to build our apps out of smaller, simpler things.

Josh Abernathy

September 18, 2015
Tweet

More Decks by Josh Abernathy

Other Decks in Programming

Transcript

  1. [...] a relation between a set of inputs and a

    set of permissible outputs with the property that each input is related to exactly one output. — Wikipedia
  2. class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow!

    func applicationDidFinishLaunching(notification: NSNotification) { let output = runMyApp(input: ???) doSomethingWithOutput(output) } } func runMyApp(input: ???) -> ??? { }
  3. State change ← renderApp State change ← renderApp State change

    ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp State change ← renderApp
  4. func renderLogin(state: LoginState) -> UI func renderPhotos(state: PhotosState) -> UI

    func renderButton(title: String) -> UI func renderVerticalList(UIs: [UI]) -> UI
  5. class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow!

    func applicationDidFinishLaunching(notification: NSNotification) { doSomeMagic(render: renderApp, view: window.contentView) } } func renderApp(state: Int) -> UI { return renderVerticalList([ renderLabel("Click count: \(state)"), renderButton("Click me!", action: { updateState(state + 1) }), ]) }
  6. let appComponent = Component(initialState: 0, render: renderApp) class AppDelegate: NSObject,

    NSApplicationDelegate { @IBOutlet weak var window: NSWindow! func applicationDidFinishLaunching(notification: NSNotification) { appComponent.addToView(window.contentView) } } func renderApp(component: Component<Int>, state: Int) -> Element { return View( backgroundColor: .orangeColor()) .justification(.Center) .childAlignment(.Center) .direction(.Column) .children([ Label("You've clicked \(state) times!"), Button(title: "Click me!", action: { component.updateState { $0 + 1 } }) .margin(Edges(uniform: 10)) .width(100), ]) }
  7. func renderApp(component: Component<Int>, state: Int) -> Element { return View(

    backgroundColor: .orangeColor()) .justification(.Center) .childAlignment(.Center) .direction(.Column) .children([ Label("You've clicked \(state) times!"), Button(title: "Click me!", action: { component.updateState { $0 + 1 } }) .margin(Edges(uniform: 10)) .width(100), ]) }
  8. Now

  9. struct Graph { let currentBranch: Branch? let compareBranch: Branch? ...

    } struct GraphUpdate { let type: GraphUpdateType init(oldGraph: GHComparisonGraph?, newGraph: GHComparisonGraph) ... }
  10. // Graph.swift let newGraph = calculateGraph(repository) let update = GraphUpdate(oldGraph:

    oldGraph, newGraph: newGraph) // GraphViewController.swift switch (update.type) { case .Append: // do the needful ... }
  11. See Also — "Boundaries" by Gary Bernhardt — "Tangible Functional

    Programming" by Conal Elliott — "Refactor the Mega-Controller" by Andy Matuschak — Most anything by Rich Hickey