Skip to content

Instantly share code, notes, and snippets.

@jemmons
jemmons / software_abstractions.md
Created January 15, 2023 17:43
From the Introduction of “Software Abstractions” by Daniel Jackson

Software is built on abstractions. Pick the right ones, and programming will flow naturally from design; modules will have small and simple interfaces; and new functionality will more likely fit in without extensive reorganization. Pick the wrong ones, and programming will be a series of nasty surprises: interfaces will become baroque and clumsy as they are forced to accommodate unanticipated interactions, and even the simplest of changes will be hard to make. No amount of refactoring, bar starting again from scratch, can rescue a system built on flawed concepts.

Abstractions matter to users too. Novice users want programs whose abstractions are simple and easy to understand; experts want abstractions that are robust and general enough to be combined in new ways. When good abstractions are missing from the design, or erode as the system evolves, the resulting program grows barnacles of complexity. The user is then forced to master a mass of spurious details, to develop workarounds, and to accept frequ

import Foundation
typealias Continuation<Ret> = (Ret) -> Void
typealias ContinuationMonad<Value> = (@escaping Continuation<Value>) -> Void
typealias Transform<T,U> = (T) -> ContinuationMonad<U>
func async<Value>(_ wrappedValue: Value) -> ContinuationMonad<Value> {
{ $0(wrappedValue) }
}
@jemmons
jemmons / ContinuationMonad.swift
Created March 23, 2021 21:10
Continuation Monad in Swift
import Foundation
//: Consider traditional Cocoa async calls with completion blocks like:
func prependHello(with i: Int, completion: (String) -> Void) {
completion("hello \(i)")
}
//: We could imagine this to be the CPS version of some standard call:
@jemmons
jemmons / Binding+Filter.swift
Created December 28, 2019 17:52
Allows us to filter `Binding`s while keeping everything bindable — so long as they wrap collections of `Identifiable` elements.
import SwiftUI
extension Binding where Value: MutableCollection, Value: RangeReplaceableCollection, Value.Element: Identifiable {
func filter(_ isIncluded: @escaping (Value.Element)->Bool) -> Binding<[Value.Element]> {
return Binding<[Value.Element]>(
get: {
// The binding returns a filtered subset of the original wrapped collection.
self.wrappedValue.filter(isIncluded)
},
set: { newValue in
@jemmons
jemmons / ForEachOrEmpty.swift
Created December 7, 2019 15:54
SwiftUI view that will either ForEach over data or display given view if empty.
import SwiftUI
struct ForEachOrEmpty<Data, ID, ForEachContent, EmptyContent>: View where Data: RandomAccessCollection, ID: Hashable, ForEachContent: View, EmptyContent: View {
let data: Data
let forEachBuilder: (Data.Element) -> ForEachContent
let emptyBuilder: () -> EmptyContent
let identityKeyPath: KeyPath<Data.Element, ID>
@jemmons
jemmons / Create Input with Block.swift
Last active November 17, 2022 07:04
Sample CoreMIDI code…
// See: https://forums.developer.apple.com/thread/65997
MIDIInputPortCreateWithBlock(midiClient, "Instrument" as CFString, &inPort, {
(unsafePacketList: UnsafePointer<MIDIPacketList>, pointer: UnsafeMutableRawPointer?) in
let packetList = unsafePacketList.pointee
if packetList.numPackets == 1 {
let packet = packetList.packet
if packet.length == 3 && packet.data.0 == 144 {
/* Note-On */
let note = packet.data.1
@jemmons
jemmons / curry.swift
Created January 20, 2019 00:54
Currying higher-order functions results in broken types.
import Foundation
// Given what seems to be a pretty standard definition of `curry`…
public func curry<T, U, Z>(_ ƒ: @escaping (T, U) -> Z) -> (T) -> (U) -> Z {
return { a in
return { b in
ƒ(a, b)
}
}
public enum Result<Value> {
case success(Value)
case failure(Error)
public init(_ value: Value) {
self = .success(value)
}
@jemmons
jemmons / BoolEncoder.swift
Created April 18, 2018 20:07
Simple Encoder
import Foundation
class BoolEncoder: SingleValueEncodingContainer {
var codingPath: [CodingKey]
private(set) var value: Bool?
init() {
codingPath = []
}
@jemmons
jemmons / .emacs
Last active November 5, 2017 21:41
Dot Files
;; PATH FOR LEININGEN
(add-to-list 'exec-path "/usr/local/bin")
;; FONTS
(add-to-list 'default-frame-alist
'(font . "Source Code Pro-18"))
;; PACKAGE STUFF
(require 'package)