Skip to content

Instantly share code, notes, and snippets.

View rnapier's full-sized avatar

Rob Napier rnapier

View GitHub Profile
@rnapier
rnapier / fix-xcode
Last active June 19, 2026 17:26
Links Xcode SDKs from the /SDKs directory (which you maintain yourself)
#!/usr/bin/python
# fix-xcode
# Rob Napier <robnapier@gmail.com>
# Script to link in all your old SDKs every time you upgrade Xcode
# Create a directory called /SDKs (or modify source_path).
# Under it, put all the platform directories:
# MacOSX.platform iPhoneOS.platform iPhoneSimulator.platform
# Under those, store the SDKs:
@rnapier
rnapier / NormalizedGaussianTests.swift
Last active September 29, 2025 13:43
Ziggurat algorithm ported from Java using Codex: https://mastodon.social/@cocoaphony/115282998859062341
/// Test to check sample distribution. Written by Codex.
/// Prompt:
/// Write unit tests for NormalizedGaussian with the goal of checking that it generates random values with a guassian normal distribution.
import XCTest
@testable import FinLib
final class NormalizedGaussianTests: XCTestCase {
private let sampleCount = 200_000
@rnapier
rnapier / MainActorRun.swift
Last active September 1, 2025 19:42
Regarding MainActor.run
// In regards to https://mastodon.social/@mattiem/112285978801305971
// MainActor class with synchronous methods
@MainActor final class M {
func methodA() {}
func methodB() {}
}
// Actor that relies on M.
actor A {
@rnapier
rnapier / SelectorNotifiction.swift
Last active September 1, 2025 19:40
Musings on Notifications and Actors
/// Some exploration into how selector-based notification interact with actors.
///
/// Or in the words of Brent Simmons (@brentsimmons@indieweb.social),
/// "Selector-based Notification Observers Are Actually Good"
/// Overall, I'm reasonably convinced, in that it avoids the headaches of `deinit` in actors.
/// However, Combine-based observation is also good at this, so I don't yet have a strong opinion
/// about old-school selectors vs Combine beyond my usual nervousness around Combine.
/// Whether "I'd like to reduce Combine" is more or less powerful than "I'd like to reduce @objc"
/// is yet to be seen.
public actor TaskBag {
private var tasks: [UUID: Task<Void, Never>] = [:]
func add(_ task: Task<Void, Never>) {
let id = UUID()
tasks[id] = Task { [weak self] in
await task.value
await self?.remove(id: id)
}
}
@rnapier
rnapier / Mutex.swift
Last active April 1, 2025 16:58
Mutex backport
// Version of Swift 6 Mutex, with minimal API (just withLock), portable to at least iOS 15, probably much earlier.
// I cannot yet promise it's actually correct.
@frozen
public struct Mutex<Value> {
private let buffer: ManagedBuffer<Value, os_unfair_lock>
public init(_ initialValue: Value) {
buffer = ManagedBuffer<Value, os_unfair_lock>.create(minimumCapacity: 1) { _ in initialValue }
buffer.withUnsafeMutablePointerToElements { lockPtr in
@rnapier
rnapier / stack_usage.py
Created March 29, 2025 17:04
stack_usage lldb script
import lldb
# put this in ~/.lldb/stack_usage/stack_usage.py.
# Load in .lldbinit with `command script import "~/.lldb/stack_usage/stack_usage.py"`
# At a breakpoint, you can then type `stack_usage` to get the current stats.
@lldb.command("stack_usage")
def _stack_usage(debugger, command, result, internal_dict):
"""Show current stack usage information"""
target = debugger.GetSelectedTarget()
@rnapier
rnapier / chonkystack.py
Created March 29, 2025 16:58
Read .o's and output stack allocations per-function
#! env python3
import os
import re
import subprocess
import argparse
parser = argparse.ArgumentParser(
description="Process .o files to output stack allocation info."
)
@rnapier
rnapier / GridView.swift
Last active March 5, 2025 16:55
GridView that makes me cry
// This GridView makes me cry. It is recreating an HTML-style bordered table, sized to
// its data, with a header. It requires a GeometryReader and Preferences, which might
// be unavoidable, but it also requires a *horrible* DispatchQueue.main.async in updateMaxValue.
// This means it doesn't work in Previews, and completely breaks the idea of "declarative" UI.
import SwiftUI
struct WidthPreferenceKey: PreferenceKey {
static var defaultValue: CGFloat = .zero
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
@rnapier
rnapier / AsyncFutureTests.swift
Last active January 11, 2025 19:54
AsyncFuture
import Testing
import Combine
// From https://stackoverflow.com/questions/78892734/getting-task-isolated-value-of-type-async-passed-as-a-strongly-trans/78899940#78899940
public final class AsyncFuture<Output, Failure: Error>: Publisher, Sendable {
public typealias Promise = @Sendable (Result<Output, Failure>) -> Void
private let work: @Sendable (@escaping Promise) async -> Void
public init(_ work: @Sendable @escaping (@escaping Promise) async -> Void) {