exowos/subject_text/index.md
2025-03-15 10:50:05 +01:00

1.9 KiB

revision = "0.3.0" parts = ["errors", "vec", "string"]
revision = "0.3.0" parts = ["errors", "vec", "string"]

When it comes to programming, it's all fun and games until the real world comes in and sends weird unexpected inputs to your little protege. So you better handle those cases as best as you can. There are 3 main ways of handling errors.

  • Returning some value (usualy an integer) alongside the data to notify there was an error (C, Go)
  • Throwing exceptions, effectively hijacking the program's control-flow (C++, Java, C#, Python...)
  • Encode good and bad paths in the type

The first approach is obviously a thing of the past considering how evolved compilers have become and the need of safety in our apps. You want to give humans as little responsibility as possible when it comes to error checking.

The second approach is more common in mainstream languages, and the third in functional languages, more precisely languages with so called "Algebraic Data Types" (aka "tagged unions"). The second approach is usualy less verbose because it handles error propagation for you, but this approach has many downsides that make languages slowly adopt the third approach (C++, Python), mainly because of control-flow.

Rust took the third approach, as it is simple to reason about for the compiler and of course makes it easy to prove the soundness of you program. It even helps modeling your application such that "no invalid state can be represented" but it's a topic we won't cover in this course.

This training session will cover the two main types of error (Option and Result) in Rust, and use them in the context of collections and strings.