For me it's mostly "collections" in the loose sense, not necessarily things which are RangeReplaceableCollections or even Collections. e.g. a Cache type. But not just collectiony types.
Yeah, I gave a bad example. I wish I'd started this topic a few weeks ago when I last hit this need and the details were fresh in my mind. I know it revolved around collections (as in Collection), but I don't recall how I was expecting to get over that missing universal add method. I might have been envisioning additional new protocols in concert, like an ExtendableCollection or somesuch.
Maybe a better example is a Swift version of Python's defaultdict.
struct DefaultDict<Key: Hashable, Value: UnconditionallyInitialisable> {
…
subscript(_ key: Key) -> Value {
guard let value = storage[key] else {
return storage.insert(key, Value())
}
return value
}
…
}
It's not a particularly compelling example because there's simple workarounds (e.g. have the caller manually provide a constructor closure, or keypath to init), but it's just off the top of my head as one case I recall hitting. Also, I'm not sure how well those workarounds 'compose' with additional layers of generic types, without violating abstractions (some code somewhere has to know the concrete type, or near-to, in every instance in order to provide the necessary type-specific initialisation code…?).
(I know there's a "default:" parameter to Dictionary's subscript, which is very useful sometimes but usually I want the default defined at the object level, not at every lookup)
I agree that there's potential pitfalls to such a broadly-applicable concept. I know some people might not like the idea of Int conforming to this, for example, but there's strong precedence for essentially this in various languages, including Swift with how value types implicitly gain this behaviour. e.g.:
var a: Int // No complaints - defaults to 0.
struct Foo {
let x: Int
}
var b: Foo // No complaints - defaults to { x: 0 }
// _even though_ you can't do `Foo()` explicitly.
Sometimes. I've used ExpressibleByIntegerLiteral before for very similar purposes, for example. But that approach only works for a limited set of types.
Anyway, the purpose of this topic thread is just to see if anyone else has ever had similar desires. I want to see if this is just a me 'problem' or actually appealing to the community, before giving it serious consideration. The solution might not be a truly generic "has-init()" protocol - I want to see what kind of similar use-cases people have. If any.