Possible errata in Chapter 1: Implementing a language feature: Using expressions that can fail

The paragraph after defining ifelseThrows states the following (emphasis mine):

This code works, but the situation is worse than initially described. Suppose only the first expression throws or suppose only the second throws. Do you need to make four versions of the same function to handle all the cases? Because the keyword throws does not figure into the signature of a Swift function, you would need to have four flavors of ifelse, all with slightly different names.

Because the keyword throws does not figure into the signature of a Swift function

However, throws does have an impact on a function’s type signature. That is, all non-throwing functions can be case as a throwing function:

func convert<A, B>(_ f: @escaping (A) -> B) -> (A) throws -> B {
	f
}

This function compiles and so (A) -> B is a subtype of (A) throws -> B.

you would need to have four flavors of ifelse, all with slightly different names

As the above convert function shows, we can call ifelseThrows with non-throwing functions. However, throws requires try no matter what, but rethrows does not.

1 Like

These are good points. You are correct. The thing that is confusing, and, indeed, what tripped me up here is that the following does not compile:

func blob() {}
func blob() throws {}
test.swift:2:6: error: invalid redeclaration of 'blob()'
func blob() throws {}
     ^
test.swift:1:6: note: 'blob()' previously declared here
func blob() {}

This diagnostic led me to believe that it is not part of the signature. However, the mangled names are different:

For blob() it is _$s4test4blobyyF and for blob() throws it is _$s4test4blobyyKF. Note the extra K at the end.

So it does figure into the signature, but there is a special rule that doesn’t allow it.

The situation isn’t as bad as I had imagined because the compiler will allow non-throwing closures to be passed in where it accepts throwing ones, as you show. Also, a single try should be able to handle multiple expressions so you would only need the leading try.

I will rework the paragraph (possibly just delete it?) to reflect your correction and update the errata accordingly over the next couple of days. Thanks for pointing this out!

1 Like