Skip to content

Instantly share code, notes, and snippets.

@tesch
Last active September 16, 2024 10:06
Show Gist options
  • Save tesch/9842445cc491dd1d77800f4f0d75503d to your computer and use it in GitHub Desktop.
Save tesch/9842445cc491dd1d77800f4f0d75503d to your computer and use it in GitHub Desktop.
// Given a `protocol P: AnyObject { ... }`, it would be useful to be able to express
// a heterogeneous set of weak references to instances of classes that fulfill the given protocol.
// This would allow to ergonomically maintain bi-directional many-to-one object relations,
// such as e.g. in cases where various `Thing`s need to serve as delegates of a central `ThingManager`,
// without being owned by it.
// In order to implement such a collection, one would need to be able to write code that is generic
// over a "protocol parameter," so to speak, instead of a type parameter. Swift's generics system
// doesn't currently have such a concept.
// I haven't given much thought to how such a feature should be represented syntactically.
// It might be worth differentiating generic type vs. protocol parameters in a similar manner to
// how concrete types `T` are differentiated from existential types `any P`.
struct WeakObjectSet<any P: AnyProtocol & AnyObject> {
private var table: Dictionary<ObjectIdentifier, () -> (any P)?> = [:]
mutating func insert(_ object: any P) {
let identifier = ObjectIdentifier(object)
table[identifier] = { [weak object] in object }
}
func forEach(_ block: (any P) throws -> ()) rethrows {
try table.forEach { _, object in
guard let object = object() else { return }
try block(object)
}
}
}
@mattmassicotte
Copy link

This area is really not my strength. But, I think I'm following. And, I also think that improves to the type system are things that can sometimes have surprising benefits outside of the original motivating problem. So totally worth it!

Have you ever tried discussing this in the forums?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment