# How about: subtypealias Farenheit = Double

**URL:** <https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513>\
**Category:** Pitches\
**Created:** [November 17, 2023, 11:50am UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513 "2023-11-17T11:50:55Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![johnno1962](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johnno1962/32/6805_2.png) [@johnno1962](https://forums.swift.org/u/johnno1962)\
**Post date:** [November 17, 2023, 11:50am UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/1 "2023-11-17T11:50:55Z")

</div>

Hi S/E,

I've been wondering if we could introduce a sibling to the `typealias` declaration of Swift as a lightweight way to declare a "sub-type" of an existing type. It seems so obvious this would be useful I'm sure it's been suggested before and I'd be curious what fate any discussion met.

In the example below `Celsius` is a distinct identifier that **`is`** a `Double` and acquires all its attributes and behaviour but a `Double` is not always always a `Celsius` as with an existing `typealias`. As such, a `Double` or a `Farenheit` cannot be passed to a function expecting a `Celsius` without an explicit cast (which would always succeed). Conversely in good sub-type tradition a `Celsius` can always be passed to a function expecting a `Double`. Ideally you could extend the new "sub-type" without polluting the original type and perhaps even dynamic casting could be supported at runtime though that wouldn't be essential.

In this way, not just the storage of the type but the significance of its contents could be type checked in a lightweight way and in the example below the function call that would likely destroy the kettle wouldn't even compile.

```plaintext
subtypealias Celsius = Double
subtypealias Farenheit = Double

let boilingPoint: Farenheit = 212.0

func britishKettle(heatTo: Celsius) {
    // ...
}

britishKettle(heatTo: boilingPoint) 🍿

```

```swift
// Other potential uses 
subtypealias FilePath = String
subtypealias URLString = String
subtypealias NewsURL = URLString
subtypealias Email = String
subtypealias UUID = String
etc...

```

---

<div class="post-metadata">

**Author:** ![jeremyabannister](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeremyabannister/32/10143_2.png) [@jeremyabannister](https://forums.swift.org/u/jeremyabannister)\
**Post date:** [November 17, 2023, 12:23pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/2 "2023-11-17T12:23:17Z")

</div>

I believe the term "new-type" is used in reference to this feature. I don't think its utility could possibly be in doubt, and I'm not sure what may be the reason or reasons why it has not yet been added to Swift.

I have a package called [DistinctType-module](https://github.com/jeremyabannister/DistinctType-module) which I use like this:

```swift
// Celsius.swift
public typealias Celsius = DistinctType<Double, _Celsius>
public enum _Celsius { }

```

It's not as pretty as a built-in solution would be, and what's worse is that the diagnostics use the full type name `DistinctType<Dobule, _Celsius>` instead of the much more readable `Celsius`, but at least it does the job of keeping semantically incompatible values separate despite having the same underlying type.

My number one use case for this is with `UUID` as the underlying type. This approach continuously saves me from what would otherwise be insidiously subtle bugs caused by accidentally passing the wrong identifier.

P.S. I believe macros can improve significantly upon my `DistinctType` approach, I just haven't gotten around to implementing it yet.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [November 17, 2023, 1:12pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/3 "2023-11-17T13:12:58Z")

</div>

Whenever I've had a need for this, I just create a wrapper struct. I think that's the Swiftiest thing to do - one of the original tenets of the language was that these kinds of wrappers should be "zero cost".

So for your example, I'd do something like:

```swift
struct Temperature {
  var celsius: Double

  var fahrenheit: Double {
    get { 32 + (celsius * 9/5) }
    set { celsius = (newValue - 32) * 5/9 }
  }
}

```

And I find that it tends to pay off to look for those kinds of abstractions. For instance, I think it makes sense to have a `Temperature` value which is distinct from, say, a `Length` or `Mass` value, and to represent that in the type system. I don't think it makes as much sense to make temperatures in Celsius a distinct type from temperatures in Fahrenheit. Subtyping isn't really the relationship we want here.

IIRC, the one annoying thing about this pattern is that the synthesised `Codable` conformance uses a keyed container, so you need to override it and used a single-value container instead. It's easy enough to make a protocol which will do that for you, though.

And that extends to things like ID numbers. The language has long had synthesis for memberwise initialisers and common standard library protocols in structs; it's been optimised so these kinds of wrappers really do not require much code at all:

```swift
struct UserID: Equatable, Hashable /*... etc */ {
  var wrappedValue: UUID
}

```

---

<div class="post-metadata">

**Author:** ![jeremyabannister](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeremyabannister/32/10143_2.png) [@jeremyabannister](https://forums.swift.org/u/jeremyabannister)\
**Post date:** [November 17, 2023, 1:17pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/4 "2023-11-17T13:17:30Z")

</div>

The problem with making a simple wrapper type like this is that you have to reference the underlying value explicitly.

```swift
massOfRocket.value + massOfFuel.value

```

You can of course make your wrapper type conform to `AdditiveArithmetic`, but that's a big burden if you're creating many of these wrapper types for various semantically distinct `Double`-like types.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [November 17, 2023, 1:26pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/5 "2023-11-17T13:26:16Z")

</div>

Yeah I'm (personally) not really bothered by that.

And sometimes it can be quite useful - for instance, types which represent physical quantities can often give meaningful names to the properties which provide numeric values. So it isn't just `.value`, but rather `.kilograms`, `.celsius`, etc.

For things like `UserID`, there isn't really a meaningful name for the wrapped property, but that also doesn't tend to be a big problem in practice because you generally want to _keep_ the value wrapped, and operations on the underlying value tend to be domain-specific and best written as member functions on the wrapper itself (e.g. `UserID.redactedDescription`).

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [November 17, 2023, 2:03pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/6 "2023-11-17T14:03:07Z")

</div>

It's somewhat telling that every time people request this feature, they choose an example for which it should absolutely not be used. E.g. `Fahrenheit = Double` is semantically bogus, because it would allow you to multiply two temperatures and get a temperature, take the square root of a temperature, etc. Like Karl said, this example is much better modeled with a wrapping struct, and some good tools to reduce the amount of boilerplate needed for that would be most welcome.

FWIW, I think this would be genuinely useful to have this, but we would have to be pretty careful not to encourage people to use it as commonly suggested.

---

<div class="post-metadata">

**Author:** ![hassila](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hassila/32/22647_2.png) [@hassila](https://forums.swift.org/u/hassila)\
**Post date:** [November 17, 2023, 2:10pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/7 "2023-11-17T14:10:55Z")

</div>

Agree this would be useful at times, I just did a few wrapper structs, e.g.

```swift
// We need type-specific property identifiers here to allow for proper type completion in the IDE for the auto codegen
public typealias PropertyIdentifier = UInt64

public struct InstrumentPropertyIdentifier: Hashable, Equatable {
    var value: PropertyIdentifier
}

public struct TransactionPropertyIdentifier: Hashable, Equatable {
    var value: PropertyIdentifier
}

public struct PluginPropertyIdentifier: Hashable, Equatable {
    var value: PropertyIdentifier
}

...

```

But then need to add boilerplate like this:

```swift
extension InstrumentPropertyIdentifier {
    init(_ value: UInt64) {
        self.value = value
    }
}

```

To allow for convenient init, e.g.

```swift
    static let testIdentifier: InstrumentPropertyIdentifier = InstrumentPropertyIdentifier(xxx.propertyIdentifier)
/// xxx.propertyIdentifier is a PropertyIdentifier

```

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [November 17, 2023, 3:02pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/8 "2023-11-17T15:02:13Z")

</div>

I like it. For class types it would be equivalent to subclassing:

```swift
// bike-shedding:
class C {}
subtype D: C
class D: C {} // equivalent for all intents and purposes
var c = C()
var d = D()
c = d // ✅
d = c // 🛑

```

for value types it would be a new feature we didn't have before:

```swift
class S {}
subtype D: S
var c = S()
var d = D()
c = d // ✅
d = c // 🛑

```

Extending a subtype:

```swift
extension D {
    func foo() {}
}
d.foo() // ✅
s.foo() // 🛑

```

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [November 17, 2023, 3:24pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/9 "2023-11-17T15:24:48Z")

</div>

You don't generally want the subtyping, though, since as Steve noted there are almost always operations on the original type that don't make semantic sense on the newtype. To me, this seems like an ideal case for a macro, now that we have them: there's no reason in Swift for newtype to exist as a new kind of type, since single-field structs and enums already take on the exact layout of their one field, so a macro that takes an original type name and a set of protocols and/or individual methods to forward onto the newtype seems like it should be able to create the single-field struct type, the initializers to convert to and from the new type, and forwarding protocol conformance implementations for the chosen protocols.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [November 17, 2023, 3:31pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/10 "2023-11-17T15:31:20Z")

</div>

I do not think that Steve example should be used as a reason to not have subtyping in the language. Similarly we do not rule out subclassing just because someone somewhere might write:

```swift
class Number {
    func sqrt() -> Self { ... }
}

class Fahrenheit: Number {}

var fahrenheit = Fahrenheit()
let fahrenheit2: Fahrenheit = fahrenheit.sqrt()
// how odd. let's not have subclassing at all!

```

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [November 17, 2023, 3:36pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/11 "2023-11-17T15:36:19Z")

</div>

But no one should use subclassing for that either, since that's just bad design no matter how you express it. Imagine if you had two of these subtypes, `Fahrenheit` and `Kilometers`. If they are both subtypes of some number type, then `fahrenheit * kilometers` is valid because they are both still the plain number type, despite it making no sense.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [November 17, 2023, 3:38pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/12 "2023-11-17T15:38:48Z")

</div>

Right. My point is: just because someone can misuse it doesn't mean we should not have it in the language at all. There could be other reasons why not to have it, a potential of misuse is just not one of those as my example with the "wrong" subclassing shows.

---

<div class="post-metadata">

**Author:** ![nnnnnnnn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nnnnnnnn/32/264_2.png) [@nnnnnnnn](https://forums.swift.org/u/nnnnnnnn)\
**Post date:** [November 17, 2023, 3:41pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/13 "2023-11-17T15:41:06Z")

</div>

This is another example where it seems like a macro _would_ be a great solution, but unfortunately, our current syntax-only macros don't actually get us very far toward completing the job. Right now, a macro wouldn't have access to:

- the wrapped type's initializers to mimic on the new type's declaration
- a protocol's members for forwarding the implementation to the wrapped type
- whether or not the wrapped type already conforms to the given protocols, resulting in wonky errors when the macro speculatively tries to forward those implementations

It would be great to use this use case as a guide toward macros that would let us expand the language in this way.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [November 17, 2023, 3:43pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/14 "2023-11-17T15:43:37Z")

</div>

> [@tera](#):
>
> Right. My point is: just because someone can misuse it doesn't mean we should not have it in the language at all. There could be other reasons why not to have it, a potential of misuse is just not one of those as my example with the "wrong" subclassing shows.

Right. But when you suggest subclassing, people immediately come forward with a bunch of examples where it (at least sort of) makes sense (Cat: Animal, Car: Vehicle, whatever). Whereas, when you suggest this feature, experience shows the first few examples people use are pretty much always semantically bunk. Again, that's not to say that it's not a good feature--rather it's to say that it's a feature that does not actually solve the problems that usually motivate it.

---

<div class="post-metadata">

**Author:** ![stuchlej](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stuchlej/32/7751_2.png) [@stuchlej](https://forums.swift.org/u/stuchlej)\
**Post date:** [November 17, 2023, 3:49pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/15 "2023-11-17T15:49:11Z")

</div>

To be honest, I'm more and more reluctant to see any such additions (like subtyping) as a benefit to Swift.

If there is _a trick_ to achieve the desired purpose, we should use it. In my view, the `DistinctType-module` is just the right thing for the job.

> [@jeremyabannister](#):
>
> I have a package called [DistinctType-module](https://github.com/jeremyabannister/DistinctType-module) which I use like this:

In distant past, I have been using

```swift
struct ID<Parent>: ... {
  let id: Int
}

struct User {
  let id: ID<User>
}

```

I think these solutions are even superior to using some subtyping.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [November 17, 2023, 3:51pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/16 "2023-11-17T15:51:19Z")

</div>

The subclassing example I used was deliberately bonkers to prove the single point: _just because I can come up with a bonkers example doesn't mean we should not have the feature at all_. Here's another one for you:

```swift
typealias Fahrenheit = Double
let fahrenheit: Fahrenheit = 100
let fahrenhet2: Fahrenheit = sqrt(fahrenheit)

```

Does that mean that we should not have "typealias" feature in the language (if we didn't have it already)? No!

As for a more sane cat/dog example, here you go:

```swift
struct Animal {}
subtype Cat: Animal
extension Cat {
    func meow() {...}
}
subtype Dog: Animal
extension Dog {
    func bark() {...}
}
let cat = Cat()
cat.meow() // ✅
cat.bark() // 🛑

```

---

<div class="post-metadata">

**Author:** ![johnno1962](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/johnno1962/32/6805_2.png) [@johnno1962](https://forums.swift.org/u/johnno1962)\
**Post date:** [November 17, 2023, 4:05pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/17 "2023-11-17T16:05:08Z")

</div>

> [@Joe\_Groff](#):
>
> then `fahrenheit * kilometers` is valid because they are both still the plain number type, despite it making no sense

This would have type `Double` so you wouldn't be able to pass it to something expecting `Fahrenheit` or `Kilometers`. Reuse of abstractions is not zero cost but it is also generally far from zero benefit.

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [November 17, 2023, 4:06pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/18 "2023-11-17T16:06:20Z")

</div>

Maybe better than having a specific macro - or otherwise requiring bespoke macros for each sort of construct like this - we could have a way to declare that a given type forwards (statically) to an underlying stored property? e.g.:

```swift
struct Celsius {
    let value: Double supplies AdditiveArithmetic,
                               Comparable,
                               CustomStringConvertible,
                               etc
}

```

That's probably not the best syntax, and I don't really care what the syntax is - the point is that this would be super handy. I often need this kind of functionality and I don't think a macro is a sufficiently flexible or elegant way to solve it. e.g. there might be multiple properties and more than one of them might provide conformances:

```swift
struct User {
    let id: UUID supplies Equatable, Comparable, Hashable
    let name: String supplies CustomStringConvertible
    let admin: Bool
}

```

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [November 17, 2023, 4:06pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/19 "2023-11-17T16:06:39Z")

</div>

> [@Joe\_Groff](#):
>
> Imagine if you had two of these subtypes, `Fahrenheit` and `Kilometers`. If they are both subtypes of some number type, then `fahrenheit * kilometers` is valid because they are both still the plain number type, despite it making no sense.

BTW, this is not true with multiply:

```swift
Q = C x M x dT
Q/C = M x dT

```

The left and right parts of the equation here are measured in [K x kg] which or equivalently to [Fahrenheit x kg] units.

Your example would read better with addition or subtraction.

---

<div class="post-metadata">

**Author:** ![wadetregaskis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wadetregaskis/32/8494_2.png) [@wadetregaskis](https://forums.swift.org/u/wadetregaskis)\
**Post date:** [November 17, 2023, 4:13pm UTC](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513/20 "2023-11-17T16:13:48Z")

</div>

> [@johnno1962](#):
>
> This would have type `Double` so you wouldn't be able to pass it to something expecting `Fahrenheit` or `Kilometers`. Reuse of abstractions is not zero cost but it is also generally far from zero benefit.

Which is helpful but I think not sufficiently protective, because lots of things would accept that `Double` without complaint, like string interpolation. I think the point is valid that you want the type system to enforce either:

1. You can't do multiplication of two units that are (arbitrarily) considered "incompatible".

2. The type of the result is _not_ a dangerously generic underlying type (`Double` in this case) but the correct third type that represents the combination, in this case `FahrenheitMeters` or somesuch.

Tangentially, the `Measurement` types in Foundation try to accomodate this particular use case, although they're crippled by some nasty behaviour (for a start, there's _two_ `Measurement` types, one a generic and one the Objective-C class, and the Swift compiler is readily confused about the two).

[Next page](https://forums.swift.org/t/how-about-subtypealias-farenheit-double/68513.md?page=2)
