One thing I would like to bring up is my experience at my current client. For context, I will explain that we have an Identifier
type much like the Point Free Tagged
type. Mostly this is fine, because we use the type the identifier is for as the phantom type:
struct User {
typealias ID = Identifier<User, String>
let id: ID
}
Occasionally though we have to create a new type whose sole purpose is to be the phantom type because it's not really an identifier for some thing:
enum _RefreshToken {}
typealias RefreshToken = Identifier<_RefreshToken, String>
Most developers in the team I would say are skeptical of the benefits specialised types for these can bring – the compiler not allowing one to set a refresh token to someone's user ID for insance. Mostly they will say "well of course we wouldn't do that!" However, we've definitely had subtle bugs where a product ID is used in place of a SKU ID for instance.
The point I want to raise for this thread is that it is this second instance where people really push back against have a hard time adopting types. Although in this project we've made it possible to have a two line definition of a new type, the second example isn't elegant enough to convince people of the benefits and the former is still a difficult push.
So while we can define a type with not a huge amount of code it's not going to convince people who want a one liner. It would be easier to convince people to adopt the creation of new types, as newtype
itself would lend credence to the idea. With these two points therefore, I don't necessarily believe that newtype
has to provide a massive amount extra over a one line struct for teams and the community to benefit from its addition.
As an aside, I'm really liking Tim's suggestion for this which would allow the type to conform to only the protocols that the user specifies, in quite a nice compact way.
newtype RefreshToken: Hashable, Equatable, Codable = String
Initially, I felt as if I would be on the side of automatic protocol conformance for newtype
but we're already seeing problems with our Identifier
type which has some conditional conformances which is desirable for a large number of use cases (Codable is one such case), but is entirely inappropriate for some uses. Which means we then have to fall back to creating new structs for those types.