@@ -708,42 +708,53 @@ XXX OUTLINE XXX
708708 However, you can write ` throws(SomeErrorType) `
709709 to throw errors of a specific concrete type.
710710
711- - What is a boxed protocol (aka existential) error type?
712-
713- - What is a concrete error type?
714-
715711- Because you write a type after ` throws `
716712 this syntax is also called "typed throws".
717713
714+ - A boxed protocol (aka existential) type matches the reality of most code.
715+ At compile time, you don't know every possible way things could go wrong.
716+ In particular, some errors will come from calling other throwing functions.
717+
718+ - In contrast, a concrete error type is useful:
719+
720+ * When the code that throws errors
721+ and the code that handles those errors
722+ are all part of the same larger unit,
723+ like a package or module or library.
724+ These errors are an implementation detail
725+ that users of the library don't see or recover from.
726+
727+ * In code that only rethrows errors,
728+ especially when the throwing code comes from a closure the caller provided.
729+ Example: ` map ` in the stdlib.
730+ Xref to reference section -- this chapter doesn't discuss rethrows
731+
732+ * In an environment where runtime memory allocation isn't possible,
733+ like a constrained embedded system.
734+ Throwing an instance of ` any Error ` requires allocation.
735+ The type isn't known at compile time -- allocation happens at run time.
736+ (Aside: The performance cost of allocation is small.)
737+
738+ * In code that has no dependencies, and only ever throws its own errors.
739+ TR: Does this include not depending on the stdlib?
740+
718741- You can also use opaque types like ` throws(some MyErrorProtocol) ` --
719742 this is still "concrete" in sense that
720743 the errors are all instances of the concrete type
721744 that's hidden behind the opaque type.
722745
723- - When should I use concrete error types?
724- (See SE-0413 for a list.)
725- Why shouldn't I just use this everywhere?
726-
727- - How do I write a concrete error type for a ` do ` block?
728-
729- - How do I write a concrete error type for a throwing function?
730-
731- - What's the type-system relationship
732- between plain ` throws ` and ` throws(SomeErrorType) ` ?
733- When can I interchange them?
746+ - To specify the error type for a ` do ` block or a throwing function,
747+ write ` throws(E) ` where ` E ` is an error type.
748+ For example -- insert ` summarize ` from RUNNING EXAMPLE below.
734749
735750- If a function or ` do ` block throws only errors of a single type,
736751 the compiler infers that as the concrete error type.
737- You can explicitly write ` throws(any Error ` to suppress that.
752+ You can explicitly write ` throws(any Error) ` to suppress that.
738753
739- - How do I exhaustively handle errors of a concrete type in a ` catch ` block?
740-
741- <!--
742- The outline above doesn't discuss
743- the similarity and comparison between throws(E) and rethrows
744- because this chapter doesn't discuss rethrows.
745- That information will go in the reference.
746- -->
754+ - For a normal error (of boxed protocol type)
755+ the ` catch ` clause needs to either include a general catch/default
756+ or to propagate the errors it doesn't handle.
757+ For a typed error, the catch clause can be exhaustive.
747758
748759XXX RUNNING EXAMPLE XXX
749760
@@ -770,7 +781,7 @@ func summarize(_ ratings: [Int]) throws(StatisticsError) {
770781}
771782
772783func printSummary (_ ratings : [Int ]) {
773- do {
784+ do throws (StatisticsError) {
774785 try summarize (ratings)
775786 } catch {
776787 switch error {
0 commit comments