# Typed throw functions

**URL:** <https://forums.swift.org/t/typed-throw-functions/38860>\
**Category:** Discussion\
**Tags:** throw, swift, error\
**Created:** [July 29, 2020, 11:34am UTC](https://forums.swift.org/t/typed-throw-functions/38860 "2020-07-29T11:34:11Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![minuscorp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/minuscorp/32/8404_2.png) [@minuscorp](https://forums.swift.org/u/minuscorp)\
**Post date:** [July 29, 2020, 11:34am UTC](https://forums.swift.org/t/typed-throw-functions/38860/1 "2020-07-29T11:34:11Z")

</div>

Hi Swift Forums!

Nowadays, a throwing function is mean to throw anything that conforms to `Error`, which can make `catch` clauses unnecessarily complex.  
This is a proposal for let functions marked as `throws` to specify which `Error` will be throwing, and this will be compiler type-safety backed up such:

```swift
enum AuthenticationError: Error {
    case invalidCredentials
    case unknownReason
}

func authenticate(with username: String, and password: String) throws AuthenticationError {
    [...]
    throw .invalidCredentials // can be inferred by the compiler due to the function signature.
    throw NSError(domain: "my domain", code: -1, userInfo: nil) // error: NSError cannot be casted as an AuthenticationError
}

do {
    try authenticate(with: "foo", and: "bar")
} catch {
     print(error.localizedDescription) // error is a AuthenticationError
}

do {
    try authenticate(with: "foo", and: "bar")
} catch let error as NSError { // error: AuthenticationError cannot be casted to NSError
     // N/A
}

```

Maybe this is an old topic but seems interesting to revisit it and see how the type inference system is much stronger now and that error handling is somehow incomplete; in a language where the strong type system is one of its clutch, this topic seems very poorly treated and hard to follow when there's a heavy throwing reliant topic.

Much appreciated,

Jorge

Pitch draft: [swift-typed-throws/SE-XXX Typed throws.md at master · minuscorp/swift-typed-throws · GitHub](https://github.com/minuscorp/swift-typed-throws/blob/master/SE-XXX%20Typed%20throws.md)

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [July 29, 2020, 11:46am UTC](https://forums.swift.org/t/typed-throw-functions/38860/2 "2020-07-29T11:46:52Z")

</div>

IIRC, it started as [_"there's no reason for typed errors"_](https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst#error-types), not a problem with type checker, and see if users need more (which is precisely this thread).

* * *

Personally, I still feel that it's a burden to annotate error types Java-style.

---

<div class="post-metadata">

**Author:** ![minuscorp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/minuscorp/32/8404_2.png) [@minuscorp](https://forums.swift.org/u/minuscorp)\
**Post date:** [July 29, 2020, 11:54am UTC](https://forums.swift.org/t/typed-throw-functions/38860/3 "2020-07-29T11:54:19Z")

</div>

I have read the rationale, doesn't seem to cover this kind of cases. Also, I'd like to add that this is all backwards compatible so you, for example that you don't like this type of annotations can just use the current semantics without issues.

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [July 29, 2020, 12:50pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/4 "2020-07-29T12:50:34Z")

</div>

There’s been quite a lot of discussion on this topic already:

- [[Discussion] Analysis of the design of typed throws](https://forums.swift.org/t/discussion-analysis-of-the-design-of-typed-throws/5301)

- [[Pitch] Typed throws](https://forums.swift.org/t/pitch-typed-throws/5233)

- [typed throws](https://forums.swift.org/t/typed-throws/6501)

- [[Proposal] Typed throws](https://forums.swift.org/t/proposal-typed-throws/5245)

- [Proposal: Typed throws](https://forums.swift.org/t/proposal-typed-throws/64)

- [Proposal: Allow Type Annotations on Throws](https://forums.swift.org/t/proposal-allow-type-annotations-on-throws/623)

- [Type-annotated throws](https://forums.swift.org/t/type-annotated-throws/3875)

- [[PITCH] Add Ability To Specify Error Type On Throws](https://forums.swift.org/t/pitch-add-ability-to-specify-error-type-on-throws/3910)

It might be worth going over that before restarting the conversation.

---

<div class="post-metadata">

**Author:** ![minuscorp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/minuscorp/32/8404_2.png) [@minuscorp](https://forums.swift.org/u/minuscorp)\
**Post date:** [July 29, 2020, 6:45pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/5 "2020-07-29T18:45:45Z")

</div>

I've read all threads, from 2015 up to 2017. Swift has changed a lot in three years and I think that with Swift 3 on the future road, this could be a good moment too have a specific discussion on how would this be implemented, limits (does generics makes sense?), and congruent with the actual semantics.

It seems fair to raise this topic again in 2020 with a totally different Swift and a stronger community.

Also thank you for the recap of all of those threads, some of them inspired me to open this and go forward.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [July 29, 2020, 6:52pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/6 "2020-07-29T18:52:15Z")

</div>

Thanks for the effort! I think it'd be helpful/informative if you summarise the threads, and note how things have changed. The latter of which is quite important.

---

<div class="post-metadata">

**Author:** ![Sajjon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sajjon/32/12044_2.png) [@Sajjon](https://forums.swift.org/u/Sajjon)\
**Post date:** [July 29, 2020, 9:07pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/7 "2020-07-29T21:07:38Z")

</div>

A strong argument for introducing typed throws now is because Combine uses typed errors, and working with combine and non-typed throws is awkward and leads to annoying boilerplate. On my phone now, but can write som example code tomorrow.

---

<div class="post-metadata">

**Author:** ![SDGGiesbrecht](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sdggiesbrecht/32/4768_2.png) [@SDGGiesbrecht](https://forums.swift.org/u/SDGGiesbrecht)\
**Post date:** [July 29, 2020, 10:07pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/8 "2020-07-29T22:07:22Z")

</div>

For what it’s worth, I mostly stopped using `throws` when `Result` was added to the standard library, precisely because it self‐documents what can go wrong, and can be easily switched over to get the master list if the error is an enumeration.

The only time I still use `throws` is when I don’t even have information about the possible error types myself, because the method only passes on failures from `Foundation` or some other library with untyped errors.

---

<div class="post-metadata">

**Author:** ![Mordil](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mordil/32/5840_2.png) [@Mordil](https://forums.swift.org/u/Mordil)\
**Post date:** [July 29, 2020, 11:25pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/9 "2020-07-29T23:25:09Z")

</div>

I agree that `Result` in several cases is better in today's world - but I don't see it playing well with the language at a native level once we finally get `async`/`await` by Swift 6.

It'd be great if the type system itself absolves the need for an actual type, for both the asynchronous and synchronous worlds.

---

<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:** [July 29, 2020, 11:39pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/10 "2020-07-29T23:39:04Z")

</div>

Whenever I see things [like this](https://forums.swift.org/t/extensible-enumerations-for-non-resilient-libraries/35900), showing the versioning troubles people are _already_ having with errors, I’m glad we don’t have typed throws.

Specifically, things like this:

> - Using enumerations to represent `Error` s is inadvisable, as if new errors need to be introduced they cannot be added to existing enumerations. This leads to a proliferation of `Error` enumerations. "Fake" enumerations can be made using `struct` s and `static let` s, but these do not work with the nice `Error` pattern-match logic in `catch` blocks, requiring type casts.

At least they have the escape hatch of multiple enums! It’s not pretty, and the better approach is to use a struct, but people use enums anyway 🤷‍♂️

Could you imagine if we had this, and every library had been striving to include the error types of throwing functions as part of their signature? The ecosystem would be much more fragile.

I would consider the pitch I just linked a prerequisite for even considering typed throws. Otherwise it’s too dangerous to be made so easy. In the mean time, those who really want it have `Result`.

Additionally, as part of typed throws, I would consider making any enum which conforms to `Error` resilient by default (with an ability to opt-out by marking it `@frozen`). Thrown errors will be gaining ABI significance, so it’s important developers think about this.

---

<div class="post-metadata">

**Author:** ![minuscorp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/minuscorp/32/8404_2.png) [@minuscorp](https://forums.swift.org/u/minuscorp)\
**Post date:** [July 30, 2020, 8:12am UTC](https://forums.swift.org/t/typed-throw-functions/38860/11 "2020-07-30T08:12:16Z")

</div>

I don't see any issue with what your statement tells. Is therre any issue with making a switch? Even further, that issue, if it is, it can occur now with the standard error catching but multiplied to infinity enums that conform to Error, so I rather stick with just one.

---

<div class="post-metadata">

**Author:** ![minuscorp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/minuscorp/32/8404_2.png) [@minuscorp](https://forums.swift.org/u/minuscorp)\
**Post date:** [July 30, 2020, 8:15am UTC](https://forums.swift.org/t/typed-throw-functions/38860/12 "2020-07-30T08:15:25Z")

</div>

Can you describe how do you use `Result` when you have several result statements chained in a function? Do you unwrap all `.value`? what happens with the Errors? Are ignored? Doesn't feel like a safe approach but I'm open to have an example.

---

<div class="post-metadata">

**Author:** ![minuscorp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/minuscorp/32/8404_2.png) [@minuscorp](https://forums.swift.org/u/minuscorp)\
**Post date:** [July 30, 2020, 8:35am UTC](https://forums.swift.org/t/typed-throw-functions/38860/13 "2020-07-30T08:35:28Z")

</div>

Just to recap what some people with strong knowledge of the language thinks about this:

> [@"John\_McCall](#):
>
> I completely agree that what most programmers are looking for is just a blessed way to document that a function is likely to throw specific kinds of error, and that certain of them might be worth considering in the caller.
> 
> John.

> [@\[Pitch\] Typed throws](https://forums.swift.org/t/pitch-typed-throws/5233/49):
>
> I agree that overly specific API specs are a concern. There's still some documentational benefit to a typed error enum, even if it ultimately ends up containing a catch-all case, since it gives you the ability to also enumerate some number of discrete, realistically handleable cases. Sure, your network request running in an XPC service has infinitely many failure cases due to resource constraints or IPC failure or network chaos, but there's usually some number of domain-specific error cases too. And if we compare the proposed "you get to specify one error enum type" model to, say, Java or C++98's "you get to specify any number of error classes" model, I think that helps steer people away from the most grievous API mistakes in Java land, since instead of listing a closed set of concrete error classes directly in your API signature, you'll list those error cases in your enum definition, and in a resilient world, the enum will be "open" by default to external users, preventing it from being a permanent liability unless the user explicitly opted into closedness.
> 
> In the discussions around Rust's error handling conventions, they recognized this pattern of APIs either raising some number of layer-appropriate errors or carrying forward the failure modes of the layers below them, and they developed a convention for errors wrapping other errors. It would be reasonable to say we should do the same thing as part of the typed errors design. If we were to generalize enum subtyping beyond Optional, that might be one way to go about it, letting an enum wrap its underlying layers' failure cases as subtypes.
> 
> -Joe

> [@\[Pitch\] Typed throws](https://forums.swift.org/t/pitch-typed-throws/5233/57):
>
> As you know, I still think that adding typed throws is the right thing to do. I understand your concern about “the feature could be misused” but the same thing is true about many other language features.
> 
> One thing you didn’t mention is that boxing thrown values in an existential requires allocation in the general case. This may be unacceptable for some classes of Swift application (in the embedded / deep systems space) or simply undesirable because of the performance implication.
> 
> -Chris

> [@\[Pitch\] Typed throws](https://forums.swift.org/t/pitch-typed-throws/5233/41):
>
> > It’s expected that if you need resilience, then you will throw an “open” enum. Essentially, we pass resilience of typed throws on to those who will hopefully establish resilience of enums.
> > 
> > If you prefer separate error types, then declare a base protocol for all your error types and throw a protocol existential. You won’t even need default case in switches, if closed protocols make it into the language.
> > 
> > I don’t like any solution that is based on comments. I think that compiler should always ignore comments.
> 
> I agree. And in general, this sort of thing is exactly my core concern about adding typed throws to the language: I am completely certain that many programmers will add typed throws annotations because they're programmers and thus, well, probably a little obsessive/compulsive, and they're trying to precisely document the behavior of their function without necessarily thinking about the usefulness of that information for their clients and (if they're writing a library; and really you should almost always be writing code as if you're writing a library) whether they're actually willing to commit to that behavior in their interface. For those programmers, typed throws is just going to box them in and force them into anti-patterns in the long run.
> 
> In the vast majority of use-cases, clients are not going to exhaustively handle all errors — they will always have some generic fall-back. That is not pessimism, it's actually the natural result of the complicated world we live in, where code can fail for a huge host of reasons and most callers won't have meaningful special-case behavior for all of them. (On most operating systems, opening a file or a network connection can fail because you ran out of file descriptors. You're seriously telling me that you're going to add a special case to your error logic for that?) Go look at the actual error types that people use in most typed-throws situations and try to tell me I'm wrong — they probably have like twenty alternatives, and solidly a quarter or more of them will just be embedding some other arbitrarily-complex or stringly-typed error value.
> 
> The real use case for typed throws is when you have something like a parser library that really does only fail in a fixed number of semantically distinct ways, and you both (1) actually care about enforcing that in the implementation and making sure that other errors are handled internally and (2) you really do expect clients to exhaustively switch over the error at some point. That's important. But I continue to think that if adding better support for that use case misleads other programmers into thinking they should use typed throws, we will have made the language worse overall.
> 
> John.

> [@\[Pitch\] Typed throws](https://forums.swift.org/t/pitch-typed-throws/5233/35):
>
> +1
> 
> -Chris
> 
> ···
> 
> > On Feb 17, 2017, at 11:29 AM, Matthew Johnson via swift-evolution \<[swift-evolution@swift.org](mailto:swift-evolution@swift.org)\> wrote:
> > 
> > > On Feb 17, 2017, at 1:24 PM, Xiaodi Wu via swift-evolution \<[swift-evolution@swift.org](mailto:swift-evolution@swift.org) [mailto:swift-evolution@swift.org](mailto:swift-evolution@swift.org)\> wrote:
> > > 
> > > Let's not bring bikeshedding the commonly proposed and rejected union spelling into this.  
> > > Typed throws would be a nice addition, assuming that the core team finds it in scope for phase 2. It seems only logical that any type can be thrown (i.e. conforms to Error) should be permitted to be listed in `throws()`.
> > 
> > Agree. Typed throws should have a single thrown type. Making it more convenient to throw and catch more than one error type with typed throws without having to manually create a wrapper is an orthogonal issue. David Owens convinced me of this last year when we had a thread on the topic.

> [@\[Pitch\] Typed throws](https://forums.swift.org/t/pitch-typed-throws/5233/6):
>
> IMO, if we accept a single error type per function, there could be a simpler model for this. We could say that the `throws` type is a generic parameter of all function types, and it defaults to the uninhabited `Never` type for functions that don't throw.
> 
> () -\> () == () throws Never -\> ()  
> () throws -\> () == () throws Error -\> ()
> 
> In this model, you'd get many benefits:
> 
> - `rethrows` could become first-class, reducing down to just polymorphic `throws`:
> 
> func foo(_: () throws -\> ()) rethrows // Swift 3  
> func foo\<T: Error\>(_: () throws T -\> ()) throws T // Swift X  
> func foo\<T: Error\>(\_: () throws T -\> ()) throws Either\<MyErrors, T\>
> 
> - Protocols could abstract over error handling; for instance, we could support throwing sequences:
> 
> protocol IteratorProtocol {  
> associatedtype Element  
> associatedtype Error: Swift.Error = Never
> 
> mutating func next() throws Error -\> Element?  
> }

There're strong opinions on the fact that typed throws are a thing to include into the language and that even it could be ABI backwards compatible using the introduced semantics. For record that someone has it here to read and have more context about this.  
Also, I'd like to see more dos and don'ts with the proposal in **code** in order to see what issues the semantics would have so we can analyze edge cases and other maybe related topics.

All contributions and opinions are more than welcome!

Thank you.

Some topics to cover:

1. Generic throwing allowed
2. Protocol establishing Error type through `associatedtype`.
3. Extensibility of errors.
4. ABI compatibility
5. Semantics
6. Different `Error` `do` statement.

---

<div class="post-metadata">

**Author:** ![filip-sakel](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/filip-sakel/32/8697_2.png) [@filip-sakel](https://forums.swift.org/u/filip-sakel)\
**Post date:** [July 30, 2020, 1:17pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/14 "2020-07-30T13:17:35Z")

</div>

Would it make sense to introduce an ‘@unknown default:’ counterpart to catch blocks. That is, if a library offers an Error enumeration that is not marked ‘@frozen’ the compiler will require a typed throw to add an ‘@unknown catch’ clause:

```
func throwingFoo() throws Bar { ... }

do {
    try throwingFoo() 
} catch Bar.baz { 
    // Handle the baz error 
}

❌ Not all cases of ‘Bar’ are handled
      Add ‘@unknown catch’ clause

```

So to correct it we’d write:

```
do { 
    try throwingFoo()
} catch Bar.baz { 
    // Handle the baz error 
} @unknown catch { 
    // Handle unknown cases
}

✅ Compiles

```

Filip

---

<div class="post-metadata">

**Author:** ![minuscorp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/minuscorp/32/8404_2.png) [@minuscorp](https://forums.swift.org/u/minuscorp)\
**Post date:** [July 30, 2020, 1:26pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/15 "2020-07-30T13:26:42Z")

</div>

You can always fallback to `default` which is

```swift
do {
    try throwingFoo()
} catch {
   // You can switch on error: Bar
}

```

or

```swift
do {
    try throwingFoo()
} catch Bar.baz {
   // Handle Bar.baz
} catch {
   // You can switch on error, which has every case, even @unknown, except from Bar.baz because
  // it was previously catch'ed.
}

```

The main good thing here is that just an empty `catch` will gather all errors regarding `Bar`'s enum, and use a normal switch statement.

---

<div class="post-metadata">

**Author:** ![Dante-Broggi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dante-broggi/32/7955_2.png) [@Dante-Broggi](https://forums.swift.org/u/Dante-Broggi)\
**Post date:** [July 30, 2020, 4:16pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/16 "2020-07-30T16:16:40Z")

</div>

> [@\[Pitch\] Typed throws](https://forums.swift.org/t/pitch-typed-throws/5233/6):
>
> - `rethrows` could become first-class, reducing down to just polymorphic `throws` :
> 
> func foo( _: () throws -\> ()) rethrows // Swift 3  
> func foo\<T: Error\>(_ : () throws T -\> ()) throws T // Swift X  
> func foo\<T: Error\>(\_: () throws T -\> ()) throws Either\<MyErrors, T\>

Note that this equivalence between `rethrows` and generic thrown types is invalid, due to eg. this function, which is valid today:

```swift
struct Err: Error {}
func myMap<T, U> (x: T, f: (T) throws -> U) rethrows -> U {
  do {
    return try f(x)
  } catch {
    throw Err()
  }
}

```

---

<div class="post-metadata">

**Author:** ![minuscorp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/minuscorp/32/8404_2.png) [@minuscorp](https://forums.swift.org/u/minuscorp)\
**Post date:** [July 30, 2020, 4:31pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/17 "2020-07-30T16:31:30Z")

</div>

I don't see your point:

Your snippet does not include any type of typed throw clause, so your code will be able to throw and rethrow anything.

@Joe_Groff I think meant to say that error type indicated in the generic function signature as:

```swift
func foo<T>(_ block: () throws T -> Void) rethrows T

```

> I've updated the code to reflect the current Swift semantics.

---

<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:** [July 30, 2020, 4:32pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/18 "2020-07-30T16:32:39Z")

</div>

The issue is that the `catch` block throws an error with a potentially different dynamic type from the one thrown by `f`. It used to be that `rethrows` functions could not throw their own error at all, but it looks like that has since been fixed.

---

<div class="post-metadata">

**Author:** ![minuscorp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/minuscorp/32/8404_2.png) [@minuscorp](https://forums.swift.org/u/minuscorp)\
**Post date:** [July 30, 2020, 4:41pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/19 "2020-07-30T16:41:25Z")

</div>

So the signature in

> [@minuscorp](#):
>
> `func foo<T>(_ block: () throws T -> Void) rethrows T`

Could be potentially valid in the _new_ semantics.

> I've deleted that `T: Error` because T needs to be an `Error` by compile-check because is after a `throws` statement, same for `rethrows`

---

<div class="post-metadata">

**Author:** ![SDGGiesbrecht](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sdggiesbrecht/32/4768_2.png) [@SDGGiesbrecht](https://forums.swift.org/u/SDGGiesbrecht)\
**Post date:** [July 30, 2020, 8:18pm UTC](https://forums.swift.org/t/typed-throw-functions/38860/20 "2020-07-30T20:18:22Z")

</div>

> [@minuscorp](#):
>
> Can you describe how do you use `Result` when you have several result statements chained in a function? Do you unwrap all `.value` ? what happens with the Errors? Are ignored? Doesn't feel like a safe approach but I'm open to have an example.

The function ends up as a chain of [`map(_:)`](https://developer.apple.com/documentation/swift/result/3139400-map) calls.

I would say the majority of top‐level calling code that won’t pass on the error just hangs `.get()` onto the end of the operation to turn the whole thing back into a `throw`ing expression. However, a minority of call sites _do_ want to handle particular errors, and for those I’ve found the `Result` style to be valuable for several reasons:

- As the library author, you don’t have to separately document what can go wrong (or worry about forgetting to).
- As a client developer, you don’t have to search for documentation to find out how to spell what it is you are trying to catch; code completion and exhaustiveness fix‐its will just tell you.
- As the library author, you cannot accidentally forget to make the error type `public` (whereas `throws` will let you throw an internal type, which no one can catch).
- Adding, changing or removing an error identifier is still a source‐breaking change of semantics, even if it is just string identifier or an `NSError`’s, error code that changed. In my opinion, you may as well let the API reflect it.

Admittedly, I would probably see the whole thing differently if you couldn’t go back and forth between the two styles so easily. The only annoying thing I encounter sometimes is that `.get()` doesn’t inherit `@discardableResult`, forcing you to use `_ =` more than I would like.

[Next page](https://forums.swift.org/t/typed-throw-functions/38860.md?page=2)
