Skip to content

Instantly share code, notes, and snippets.

View JensAyton's full-sized avatar

Jens Ayton JensAyton

View GitHub Profile
@JensAyton
JensAyton / I-can-infer-that-but-I'd-rather-not.swift
Created March 9, 2022 15:20
Reduced case where Swift produces a warning with a fix-it that removes its ability to infer types in otherwise working code.
// Yes, this is reduced from code that works and does something arguably useful.
protocol P1 {
associatedtype A1
func f(_: A1)
}
protocol P2: P1 {
associatedtype A2: P2
var a2: A2 { get }
@JensAyton
JensAyton / pitch.md
Last active October 26, 2021 10:37
Pre-pitch: Capturing cases as closures

Pre-pitch: Capturing cases as closures

Ever since key paths were introduced, giving us a tool to abstract over members of structs and enums, I have felt that there should be an equivalent tool for enums – particularly enums with associated values. I’ve been assuming this would take a similar form to key paths, but another approach recently occurred to me.

Let’s start with a motivating example: event handling. If you used Swift for Mac or Windows application development in the 90s, your code would have contained something like this:

// AppController.swift

func handleEvent(_ event: Event) {
@JensAyton
JensAyton / AnyEquatable.swift
Created March 23, 2021 12:02
A stab at implementing AnyEquatable with implicit conversions, leveraging AnyHashable. Unfortunately it’s not possible to get the full magic of AnyHashable, in particular with type-erased types.
import Foundation
public struct AnyEquatable: Equatable {
private struct EquatableBox<T: Equatable>: Hashable {
let value: T
func hash(into hasher: inout Hasher) {
preconditionFailure("EquatableBox must never be hashed")
}
}
@JensAyton
JensAyton / Tristate.swift
Created February 25, 2021 09:02
A very useful type
enum Tristate: ExpressibleByNilLiteral, ExpressibleByBooleanLiteral {
case maybe
case no
case yes
init(nilLiteral: Void) {
self = .maybe
}
init(booleanLiteral value: Bool) {
@JensAyton
JensAyton / StringInits.swift
Created February 7, 2020 14:58
Surprising init resolution in Swift (5.1 and 5.2)
struct Test {}
extension Test: LosslessStringConvertible {
init?(_ description: String) {
print("unlabelled init")
}
var description: String { "Test" }
}
@JensAyton
JensAyton / BrinfArk.swift
Created October 17, 2019 11:21
How do you write Swift without using the A key? Reformulate the problem in terms of a language without pesky letters, of course. Unfortunately doesn’t tail recurse. :-(
let opIncr: UInt8 = 43 // +
let opDecr: UInt8 = 45 // -
let opPrev: UInt8 = 60 // <
let opNext: UInt8 = 62 // >
let opFwd: UInt8 = 91 // [
let opBck: UInt8 = 93 // ]
let opOutput: UInt8 = 46 // .
let opInput: UInt8 = 44 // ,
let opStop: UInt8 = 0
extern "C" {
// This is global, but you can call it what you like
inline void MyPrefixedCFShow(const void *object) {
// Redeclared system function is local scope and counts as extern "C"
extern void CFShow(const void * object);
CFShow(object);
}
}
class DumbThing {
@JensAyton
JensAyton / lolif.m
Created January 5, 2017 23:02
Something something named arguments
struct ifparams {
#if __has_feature(objc_arc)
__unsafe_unretained
#endif
dispatch_block_t then, otherwise;
};
static inline void iff(bool condition, struct ifparams params) {
((condition?params.then:params.otherwise)?:^{})();
}
@JensAyton
JensAyton / format.h
Created December 10, 2015 08:00
Macro for pasting ANSI escape codes together, based on https://twitter.com/velartrill/status/674797360774569984. This version requires GCC/Clang extensions for handling zero-length macro __VA_ARGS__es, because I’m lazy, but it could be done without. Note that this is an awful idea because sooner or later you’ll want to output to a text file and …
#ifndef format_h
#define format_h
#define reset "0"
#define bold "1"
#define red "31"
#define format(first, ...) \
"\e[" first join_format_codes(__VA_ARGS__) "m"
@JensAyton
JensAyton / gist:4c6df3f1ca7d32c15fef
Created June 9, 2014 07:13
try() for discriminated-union error handling in Swift
import Foundation
// Because the real thing crashes
enum Result {
case Value(Any)
case Error(NSError?)
}