Author: Chris Lattner
import SwiftUI | |
import Combine | |
import PlaygroundSupport | |
// MARK: Data Model | |
struct Book: Identifiable, Equatable { | |
let id: Int | |
} | |
// Direct changes to DataModel should propagate |
// This is a re-implementation of the @Binding and @State property wrappers from SwiftUI | |
// The only purpose of this code is to implement those wrappers myself just to understand how they work internally and why they are needed | |
// Re-implementing them myself has helped me understand the whole thing better | |
//: # A Binding is just something that encapsulates getter+setter to a property | |
@propertyDelegate | |
struct XBinding<Value> { | |
var value: Value { | |
get { return getValue() } |
esphome: | |
name: garage | |
platform: ESP8266 | |
board: esp01_1m | |
wifi: | |
ssid: !secret wifi | |
password: !secret wifi_pw | |
# Enable logging |
#!/usr/bin/env swift | |
// This is a script for extracting all localizable strings from the Root.plist (Settings.bundle) | |
// | |
import Foundation | |
typealias Plist = [String: Any] | |
var currentGroup: String? | |
// Parameters |
State machines are everywhere in interactive systems, but they're rarely defined clearly and explicitly. Given some big blob of code including implicit state machines, which transitions are possible and under what conditions? What effects take place on what transitions?
There are existing design patterns for state machines, but all the patterns I've seen complect side effects with the structure of the state machine itself. Instances of these patterns are difficult to test without mocking, and they end up with more dependencies. Worse, the classic patterns compose poorly: hierarchical state machines are typically not straightforward extensions. The functional programming world has solutions, but they don't transpose neatly enough to be broadly usable in mainstream languages.
Here I present a composable pattern for pure state machiness with effects,
enum DataSourceState<D,E> { | |
case Empty | |
case Loading(Box<D?>) | |
case Ready(Box<D>) | |
case Error(Box<E>,Box<D?>) | |
func toLoading() -> DataSourceState { | |
switch self { | |
case .Ready(let oldData): | |
let value: D? = oldData.value |