Skip to content

Instantly share code, notes, and snippets.

Avatar

Matthew Johnson anandabits

View GitHub Profile
@anandabits
anandabits / ClosedProtocol.swift
Created Feb 11, 2018
Emulating closed protocols in Swift
View ClosedProtocol.swift
// This example shows how closed protocols can be emulated in Swift today.
// The technique leverages Swift's support for public (but not open) classes.
// First, it's worth observing that there is an almost trivial technique that can be used when
// it is possible to specify a (possibly abstract) superclass for all conforiming types.
// Simply declare a public (not open) base class and a protocol with a Self inheritance constraint.
// Swift does not support open subclasses of a public superclass so no classes outside the module
// will be able to meet the self inheritance constraint.
public class FooBase {}
public protocol Foo where Self: FooBase {}
@anandabits
anandabits / swift-value-semantics-and-pure-functions.md
Created Sep 7, 2017
Value semantics and pure functions: referential transparency for Swift
View swift-value-semantics-and-pure-functions.md
@anandabits
anandabits / list-overlay-clipping.swift
Last active Nov 17, 2020
SwiftUI List overlay clipping
View list-overlay-clipping.swift
// NOTE: behavior is exhibited in the 14.1 simulator and previews in Xcode 12.1
struct OverlayRowClipping: View {
let rowData = (1...50).map { "row \($0)" }
@State var alertIsOpen = false
var body: some View {
List {
Section(header: Text("The Header")) {
@anandabits
anandabits / Safer SwiftUI Environment.md
Last active Nov 8, 2020
Towards a safer SwiftUI environment
View Safer SwiftUI Environment.md

Towards a safer SwiftUI environment

Swift UI's @EnvironmentObject is currently prone to runtime errors. If a view uses an environment object of a type that was not injected using environmentObject a fatalError occurs. This document sketches a design that would support compile-time checking of environment object usage. It requires a few language enhancements.

Tuple intersection types

Swift's protocol composition types such as Protocol1 & Protocol2 are a form of intersection types. Other forms of intersection types are possible. For example, Flow has object intersection types. Tuple intersection types for Swift would be very similar to these.

Below, you can see the examples in the Flow documentation converted to Swift's tuples:

@anandabits
anandabits / Identifiable.swift
Last active Nov 2, 2020
Implementation of the Swift Identifiable protocol
View Identifiable.swift
/// A class of types whose instances hold the value of an entity with stable identity.
protocol Identifiable {
/// A type representing the stable identity of the entity associated with `self`.
associatedtype ID: Hashable
/// The stable identity of the entity associated with `self`.
var id: ID { get }
}
@anandabits
anandabits / HKT.swift
Last active Sep 29, 2020
Emulating HKT in Swift
View HKT.swift
// This example shows how higher-kinded types can be emulated in Swift today.
// It acheives correct typing at the cost of some boilerplate, manual lifting and an existential representation.
// The technique below was directly inspired by the paper Lightweight Higher-Kinded Polymorphism
// by Jeremy Yallop and Leo White found at http://ocamllabs.io/higher/lightweight-higher-kinded-polymorphism.pdf
/// `ConstructorTag` represents a type constructor.
/// `Argument` represents an argument to the type constructor.
struct Apply<ConstructorTag, Argument> {
/// An existential containing a value of `Constructor<Argument>`
/// Where `Constructor` is the type constructor represented by `ConstructorTag`
View areEquatablyEqual.swift
/// - returns: `true` when dynamic type is `Equatable` and `==` returns `true`, otherwise `false`.
func areEquatablyEqual(_ lhs: Any, _ rhs: Any) -> Bool {
func receiveLHS<LHS>(_ typedLHS: LHS) -> Bool {
guard
let rhsAsLHS = rhs as? LHS
else { return false }
return areEquatablyEqual(typedLHS, rhsAsLHS)
}
return _openExistential(lhs, do: receiveLHS)
}
View isBidirectional.swift
func testIsBidirectional() {
func assert<C: Collection>(_ collection: C, isBidirectional: Bool) {
XCTAssertEqual(collection.isBidirectional, isBidirectional)
}
assert([1, 2, 3], isBidirectional: true)
assert(Set([1, 2, 3]), isBidirectional: false)
}
extension Collection {
View ValueSemantics.md
View ValueSubtypeManifesto.md

Value Subtypes and Generalized Enums, a manifesto

The goal of this document is to provide a comprehensive view of what value subtyping might look like in Swift and demonstrate how generalized enums play a significant role in this future.

Note: All syntax used in this document that is not currently valid Swift syntax is only intended to serve the purpose of demonstrating ideas and to serve as a point of reference for future proposals. The intent is not to propose that this exact syntax be used.

Acknowledgement: some of the ideas in this document have been inspired by Niko Matsakis' blog post exploring similar ideas in the context of Rust: http://smallcultfollowing.com/babysteps/blog/2015/08/20/virtual-structs-part-3-bringing-enums-and-structs-together/

Definition