# Throw on nil

**URL:** <https://forums.swift.org/t/throw-on-nil/39970>\
**Category:** Pitches\
**Created:** [September 2, 2020, 7:47pm UTC](https://forums.swift.org/t/throw-on-nil/39970 "2020-09-02T19:47:09Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![woolsweater](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/woolsweater/32/2402_2.png) [@woolsweater](https://forums.swift.org/u/woolsweater)\
**Post date:** [September 4, 2020, 6:52pm UTC](https://forums.swift.org/t/throw-on-nil/39970/21 "2020-09-04T18:52:41Z")

</div>

> [@anon9791410](#):
>
> As I showed above, that's what I do!

Oops; sorry for missing that!

---

<div class="post-metadata">

**Author:** ![Ray\_Fix](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ray_fix/32/1479_2.png) [@Ray\_Fix](https://forums.swift.org/u/Ray_Fix)\
**Post date:** [September 4, 2020, 7:55pm UTC](https://forums.swift.org/t/throw-on-nil/39970/22 "2020-09-04T19:55:36Z")

</div>

Some really cool ideas. This is a lot of fun.

As @Jon_Shier points out, there is not really a precedent for or\* operations so it is probably not a very good name! Sorry! On the other hand, a throwing `unwrapped()` on `Optional` seems very natural to me, and if you said its been there since Swift 2, I would have believed you. 🙂

Because `unwrapped()` feels like such an obvious and natural abstraction to me now, I think it can (and should?) be considered independently of making throws a bottom type that can be used with `??`. If I understand the issues correctly, I don't think that having this unwrapped function walls off this improvement to the type checker as a future feature, and it addresses an existential, day-to-day problem.

I like the nested name `Missing` error the best. Great observation from Rob @mayoff that it's going to be generic and harder to catch. I kind of feel like in this case where you want to be real specific, though, the caller should be handling the optional differently, either with a tried and true `guard let` or throwing a custom, remapped error that is more "catchable." Fortunately, though, you can still catch it if you have to.

The overload solution from @noremac is pretty great because it makes errors immediately useful to those just starting out. It encourages playgrounders to embrace error handling instead of try! or compact mapping away errors the name of, "hey, this is just test playground code" only to have it copy and pasted into production code and then shipped! 😅

---

<div class="post-metadata">

**Author:** ![toph42](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/toph42/32/7807_2.png) [@toph42](https://forums.swift.org/u/toph42)\
**Post date:** [September 5, 2020, 1:11am UTC](https://forums.swift.org/t/throw-on-nil/39970/23 "2020-09-05T01:11:51Z")

</div>

I do not understand what the term “bottom type” means, but if it turns `throws` into being used at the end of `??` for nil coalescing, I support this, though maybe only if it’s inside an appropriate context, like only inside a `do` block.

---

<div class="post-metadata">

**Author:** ![CTMacUser](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ctmacuser/32/1802_2.png) [@CTMacUser](https://forums.swift.org/u/CTMacUser)\
**Post date:** [September 5, 2020, 7:05am UTC](https://forums.swift.org/t/throw-on-nil/39970/24 "2020-09-05T07:05:43Z")

</div>

The bottom type concept, where `Never` is an example, is how we can use `preconditionFailure` or `fatalError` to end a value-returning function without screwing up the type checker.

---

<div class="post-metadata">

**Author:** ![CTMacUser](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ctmacuser/32/1802_2.png) [@CTMacUser](https://forums.swift.org/u/CTMacUser)\
**Post date:** [September 5, 2020, 7:09am UTC](https://forums.swift.org/t/throw-on-nil/39970/25 "2020-09-05T07:09:00Z")

</div>

I think all the argument-specific versions of `Optional.MissingValueError` should directly refine `Error`, but of a general `Optional` error.

```
protocol MissingOptionalValueError: Error {}

extension Optional {
    struct MissingValueError: MissingOptionalValueError, CustomStringConvertible { /*...*/ }
    //...
}

```

This way people who want per-`Wrapped` and `Wrapped`-agnostic handling of `Optional` screw-ups can be happy.

---

<div class="post-metadata">

**Author:** ![toph42](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/toph42/32/7807_2.png) [@toph42](https://forums.swift.org/u/toph42)\
**Post date:** [September 5, 2020, 1:57pm UTC](https://forums.swift.org/t/throw-on-nil/39970/26 "2020-09-05T13:57:53Z")

</div>

Can `throw` (or a new function that throws) be turned into a pseudo bottom type like this `undefined<A>` generic function is in [this StackOverflow](https://stackoverflow.com/questions/34150907/bottom-type-in-swift) response? I don’t really understand how that works. What even is the return type of `fatalError()` anyway?

---

<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:** [September 5, 2020, 2:29pm UTC](https://forums.swift.org/t/throw-on-nil/39970/27 "2020-09-05T14:29:47Z")

</div>

`@noreturn` is an old concept that got replaced by `Never` in [SE-0102](https://github.com/apple/swift-evolution/blob/master/proposals/0102-noreturn-bottom-type.md). So `fatalError` is now just a normal `() -> Never` function.

If we have `Never` as the bottom type (meaning `Never` is a subtype of every type), we could replace the `throw` with something similar to:

```swift
// Note that this declaration compiles succesfully today.
func throwOnly(_ error: Error) throws -> Never {
  throw error
}

```

We can then do something like: `value ?? throwOnly(error)` as `Never` will be the subtype of `Value`. Currently it doesn't work as `Never` is unrelated to `Value` (except for when `Value` is `Never`).

Not that I particularly like the concept of bottom type, though.

---

<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:** [September 5, 2020, 3:44pm UTC](https://forums.swift.org/t/throw-on-nil/39970/28 "2020-09-05T15:44:30Z")

</div>

I think we need to make `throw` an expression (currently it’s a statement) which should allow you to do `a ?? throw b` for example.

---

<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:** [September 5, 2020, 3:55pm UTC](https://forums.swift.org/t/throw-on-nil/39970/29 "2020-09-05T15:55:57Z")

</div>

We also need to figure out the type of `throw`. Since throwing `Never` (my `throwOnly`) is apparently not coerced properly.

---

<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:** [September 5, 2020, 3:58pm UTC](https://forums.swift.org/t/throw-on-nil/39970/30 "2020-09-05T15:58:57Z")

</div>

Right, we would also need to give it a `Never` type if we decide to make `Never` a bottom type.

---

<div class="post-metadata">

**Author:** ![Ray\_Fix](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ray_fix/32/1479_2.png) [@Ray\_Fix](https://forums.swift.org/u/Ray_Fix)\
**Post date:** [September 5, 2020, 4:08pm UTC](https://forums.swift.org/t/throw-on-nil/39970/31 "2020-09-05T16:08:09Z")

</div>

Curious if people agree

```swift
// requires a small library change
let url = try URL(string: location).unwrapped() // throws Missing<URL> with FILE:LINE
let url = try URL(string: location).unwrapped(orThrows: InvalidURL(location))

```

and

```swift
// requires a deeper change to compiler
let url = URL(string: location) ?? throw InvalidURL(location)

```

Can live together? I think `unwrapped()` or `unwrap()`? is a nice API for optional.

---

<div class="post-metadata">

**Author:** ![pyrtsa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pyrtsa/32/740_2.png) [@pyrtsa](https://forums.swift.org/u/pyrtsa)\
**Post date:** [September 5, 2020, 4:10pm UTC](https://forums.swift.org/t/throw-on-nil/39970/32 "2020-09-05T16:10:58Z")

</div>

One minor point which I'm not sure was mentioned, if we can make `x ?? throw e` to work, I think it would be convenient if that expression didn't require prefixing it with `try`, even if the `throw` is technically buried inside the `autoclosure` expression.

---

<div class="post-metadata">

**Author:** ![jpmhouston](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jpmhouston/32/4045_2.png) [@jpmhouston](https://forums.swift.org/u/jpmhouston)\
**Post date:** [September 5, 2020, 5:08pm UTC](https://forums.swift.org/t/throw-on-nil/39970/33 "2020-09-05T17:08:20Z")

</div>

Paraphrasing [freak4pc](https://forums.swift.org/u/freak4pc), I'm not a fan of `optional ?? throw Error` and strongly disagree that it "makes sense" from a language feel perspective.

This operator is currently is always like "value or value", and used like `let a = wrapped ?? value` or sometimes `let b = wrapped ?? otherWrapped ?? value`. In those cases `a` and `b` always end up being assigned values.

A throw or call to `fatalError` (etc) is an action not a value. Allowing `Never` types in `??` would then permit it to mean "value otherwise action" sometimes. To me, this is a significant change to the mental model of this operator. Changes it negatively by making it less clear and more blurry, which distracts when reading (which sense of `??` is this?), and detracts from learning (which actions can go after `??` and why).

_EDITS: completed after accidentally submitting mid-sentence :^/, corrected some unquoted code, added final sentence justifying my argument, reworded this list of edits._

---

<div class="post-metadata">

**Author:** ![mayoff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mayoff/32/613_2.png) [@mayoff](https://forums.swift.org/u/mayoff)\
**Post date:** [September 5, 2020, 5:20pm UTC](https://forums.swift.org/t/throw-on-nil/39970/34 "2020-09-05T17:20:10Z")

</div>

> [@jpmhouston](#):
>
> Allowing `Never` types in `??` would then permit it to mean "value otherwise action" sometimes.

As pointed out by others (such as [Nevin, here](https://forums.swift.org/t/throw-on-nil/39970/14)), `??` can _already_ mean “value otherwise action”, if you write a throwing expression with the appropriate type on the right-hand side of `??`. I've used a function like Nevin's `throwError` in my projects in exactly this way.

Changing `throw` to be an expression simply standardizes the spelling of that throwing expression. I don't know that doing so requires making `Never` a bottom type, as opposed to just special casing the type of a `throw` expression.

---

<div class="post-metadata">

**Author:** ![Jon\_Hull](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_hull/32/678_2.png) [@Jon\_Hull](https://forums.swift.org/u/Jon_Hull)\
**Post date:** [September 6, 2020, 10:19am UTC](https://forums.swift.org/t/throw-on-nil/39970/35 "2020-09-06T10:19:37Z")

</div>

I don't think I have had a project where I haven't needed `?? {throw MyError.errorType}()`

I fully agree with @Nevin's spelling of making throw act like a bottom type.

I would also like to see `throws?` added to the language, which would act exactly like `throws` except instead of requiring `try`, the compiler would add an implicit `try?` before any call to the function.

```swift
func myThrowingFunc() throws? -> Int {
    //Do stuff
    if problem {
        throw MyError.errorType
    }
    return answer
}

```

This would say that there is throwing information, but you usually don't care about it

```swift
let x:Int? = myThrowingFunc() ///This has an implicit try? in front of it

```

But in cases where you actually do want it to throw, you would just call with the `try` keyword, and it will use that instead of `try?`

```swift
let x:Int = try myThrowingFunc()

```

The end result is that you can provide throwing for those who want it, without burdening the API with it when it isn't useful most of the time.

As an example, I have a packrat parser where I use the throwing information while developing/debugging a parser ruleset, but in actual production I always use `try?` because it lets me use `if let`, which simplifies the algorithm quite a bit from `do catch`, and the reason for the error doesn't matter... just that it failed.

---

<div class="post-metadata">

**Author:** ![Jon\_Hull](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_hull/32/678_2.png) [@Jon\_Hull](https://forums.swift.org/u/Jon_Hull)\
**Post date:** [September 6, 2020, 10:26am UTC](https://forums.swift.org/t/throw-on-nil/39970/36 "2020-09-06T10:26:25Z")

</div>

I'd also like to see `throws!` which is the same, but with trapping.

It would be great to have a way to say "I know you normally trap, but in this case, if you would trap, just give me a nil result or throw instead"...

---

<div class="post-metadata">

**Author:** ![toph42](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/toph42/32/7807_2.png) [@toph42](https://forums.swift.org/u/toph42)\
**Post date:** [September 6, 2020, 5:26pm UTC](https://forums.swift.org/t/throw-on-nil/39970/37 "2020-09-06T17:26:29Z")

</div>

I’m not sure I understand what you mean, but the fact that you’re saying that something with `throws!` could return `nil` without crashing makes me inclined to dislike it, as it seems to run counter to the way the bang works for `Optional`. If I am misunderstanding, could you maybe give an example of usage?

Overall, I think `throws?` could be useful (like in the case you mentioned previously) but at the same time I wonder if it might be a siren’s call for making poor design choices in cases that _should_ normally throw.

---

<div class="post-metadata">

**Author:** ![Jon\_Hull](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_hull/32/678_2.png) [@Jon\_Hull](https://forums.swift.org/u/Jon_Hull)\
**Post date:** [September 6, 2020, 6:23pm UTC](https://forums.swift.org/t/throw-on-nil/39970/38 "2020-09-06T18:23:41Z")

</div>

`throws!` would be just like `throws?` except it has an implicit `try!` in front of any call which isn't otherwise marked with try. Thus it will trap if you call it normally:

```swift
func myTrappingFunc() throws! -> Int {
    guard !problem else {throw MyError.errorType}
    return answer
}

let x = myTrappingFunc() ///This has an implicit try! and will trap if it throws

```

But if you want it to throw instead, you would put `try` in front of it:

```swift
let x = try myTrappingFunc() ///Now it will throw instead of trap

```

Or if you wanted it to return an optional, and return nil when it throws:

```swift
let x = try? myTrappingFunc() ///Now it returns an optional instead

```

So both `throws?` and `throws!` work just like `throws`, but have a default which allows them to act like the other types of error handling by default. You can override that default behavior by explicitly marking it.

---

<div class="post-metadata">

**Author:** ![CTMacUser](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ctmacuser/32/1802_2.png) [@CTMacUser](https://forums.swift.org/u/CTMacUser)\
**Post date:** [September 7, 2020, 6:37pm UTC](https://forums.swift.org/t/throw-on-nil/39970/39 "2020-09-07T18:37:51Z")

</div>

> [@Jon\_Hull](#):
>
> I would also like to see `throws?` added to the language, which would act exactly like `throws` except instead of requiring `try` , the compiler would add an implicit `try?` before any call to the function.
> 
> ```swift
> func myThrowingFunc() throws? -> Int {
> //Do stuff
> if problem {
> throw MyError.errorType
> }
> return answer
> }
> 
> ```
> 
> This would say that there is throwing information, but you usually don't care about it
> 
> ```swift
> let x:Int? = myThrowingFunc() ///This has an implicit try? in front of it
> 
> ```
> 
> But in cases where you actually do want it to throw, you would just call with the `try` keyword, and it will use that instead of `try?`
> 
> ```swift
> let x:Int = try myThrowingFunc()
> 
> ```
> 
> The end result is that you can provide throwing for those who want it, without burdening the API with it when it isn't useful most of the time.

As I understand it, making calls to a throwing function look different to calls to a non-throwing function was an _intentional design point_. This suggestion completely defeats that. Plus the return type of such functions is partially a lie; it jumps between to `MyReturnType` when you prepend "`try`" or `MyReturnType?` without it. Transforming exception handling to `nil` return via a decision at the caller's side was also a design point.

---

<div class="post-metadata">

**Author:** ![saeta](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/saeta/32/6264_2.png) [@saeta](https://forums.swift.org/u/saeta)\
**Post date:** [September 13, 2020, 6:20pm UTC](https://forums.swift.org/t/throw-on-nil/39970/40 "2020-09-13T18:20:25Z")

</div>

> [@Nevin](#):
>
> Personally, my preferred solution would be to make `throw` behave as if it were a bottom type. Then you could simply write:
> 
> ```swift
> let result = try someOptional ?? throw MyError()
> 
> ```
> 
> The same treatment for `Never` would allow the use of `fatalError` and any other non-returning functions in arbitrary locations that expect a typed value.

The desire to treat `throw X` as an expression dovetails with other calls to make `if` and `switch` also be expressions, and definitely has my support.

[Previous page](https://forums.swift.org/t/throw-on-nil/39970.md?page=1)

[Next page](https://forums.swift.org/t/throw-on-nil/39970.md?page=3)
