Skip to content

Instantly share code, notes, and snippets.

View keehun's full-sized avatar

Keehun keehun

View GitHub Profile
@keehun
keehun / States-v3.md
Created March 27, 2023 18:12 — forked from andymatuschak/States-v3.md
A composable pattern for pure state machines with effects (draft v3)

A composable pattern for pure state machines with effects

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,

@keehun
keehun / resolve-firmlinks.py
Created February 5, 2021 16:02
Resolving Firmlinks in Python
@keehun
keehun / countdown.py
Created December 9, 2020 22:40
Python script to countdown to a specified datetime and write to a file. I use this for OBS countdown timers.
from time import sleep
from datetime import datetime, time
def date_diff(date1, date2):
timedelta = date2 - date1
return timedelta.days * 24 * 3600 + timedelta.seconds
def min_sec(seconds):
minutes, seconds = divmod(seconds, 60)
return minutes, seconds
@keehun
keehun / NSMutableDictionaryBug.swift
Created October 24, 2019 20:58
NSMutableDictionary(contentsOf:error:) Bug (Fixed on Catalina)
import Foundation
let url = FileManager.default.temporaryDirectory.appendingPathComponent("test.plist")
func crashes() throws {
try NSDictionary().write(to: url)
let returned = try NSMutableDictionary(contentsOf: url, error: ())
/// This will crash
returned.setValue("Hello", forKey: "World")
func getMoviePackage(for movieID: String, completion: MoviePackageFetchCompletion? = nil) {
var movieURL: URL?
var subtitleURL: URL?
var movieFile: File?
var subtitleFile: File?
/// The `DispatchGroup` for the parallel URL fetch operations
let urlFetchGroup = DispatchGroup()
async function getMoviePackageFor(movie_id) {
/// Get the URLs of the movie and subtitle file in parallel
const movie_url = await MovieDatabase.getURLFor(movie_id)
const subtitle_url = await SubtitleDatabase.getURLFor(movie_id)
/*
By the way, if you want those two async actions to run in
parallel, you can do this:
@keehun
keehun / dynamictype3-snippet6.swift
Last active February 15, 2019 21:11
Practical Dynamic Type, Part 3: Attributed Strings
import XCTest
@testable import AttributedDynamicLabelDemo
class AttributedDynamicLabelDemoTests: XCTestCase {
var subject: AttributedStringView!
override func setUp() {
super.setUp()
subject = AttributedStringView()
@keehun
keehun / dynamictype3-snippet5.swift
Last active February 18, 2019 14:56
Practical Dynamic Type, Part 3: Attributed Strings
// MARK: Event Handlers
/// Update the sizes of all contained fonts whenever the Dynamic Type size changes.
@objc func uiContentSizeCategoryChanged() {
/// Only continue if the `UILabel` has non-nil attributed text.
guard let attributedString = display.attributedText else {
return
}
@keehun
keehun / dynamictype3-snippet4.swift
Last active February 15, 2019 19:47
Practical Dynamic Type, Part 3: Attributed Strings
/// `FontSetterAttributeKey` is used to keep track of the custom Font assigned to a range within
/// an `AttributedString`.
static let FontSetterAttributeKey = NSAttributedString.Key.init("FontSetterAttributeKey")
/// A `UILabel` that will render the attributed string with Dynamic Type.
lazy var display: UILabel = {
let fontSetter1: FontSetter = { UIFont.customFont(weight: .bold, points: 18.0) }
let string1 = NSAttributedString(
string: "Jived fox nymph grabs quick waltz. ",
@keehun
keehun / dynamictype3-snippet3.swift
Last active February 18, 2019 14:44
Practical Dynamic Type, Part 3: Attributed Strings
@objc func uiContentSizeCategoryChanged() {
/// Only continue if the `UILabel` has non-nil attributed text.
guard let attributedString = display.attributedText else {
return
}
/// Get the NSRange of the plaintext string.
let fullTextRange = NSRange(location: 0, length: attributedString.string.count)