Author: Matthew Johnson
// Created by Matthew Johnson on 5/28/16. | |
// Copyright © 2016 Anandabits LLC. All rights reserved. | |
// | |
// This is a minimalist implementation of a responder chain in pure Swift. | |
// | |
// It is not intended to demonstrate the best way to | |
// implement event processing in Swift. | |
// | |
// The intent is to show how little code is necessary to acheive behavior | |
// similar to Cocoa's responder chain in pure Swift. |
Author: Matthew Johnson
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 { |
/// 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 } | |
} |
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/
/// - 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) | |
} |
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.
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:
// 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` |