Both Rust and C# provide throwing/failing interfaces for parsing, it's just that Rust's is written:
let foo: u32 = "3".parse().unwrap();
and C#'s is written:
var foo = uint.Parse("3");
Both require familiarity with the stdlib (Parse throws, TryParse doesn't, unwrap fails).
I agree that TryParse is worse than Rust's ADT approach, but that's a different issue, much like nullable references. The author is asserting that results are superior to exceptions and I am asserting that no, that is just a bad application of exceptions. Additionally, I am asserting that without exceptions, you limit what programmers are willing to propagate through their interfaces because errors become viral.
Both exceptions and results are important for software architecture. The lack of the former leads to an oversimplification of interfaces in languages with only the latter. The author hit upon an example that is probably better written using results. But guess what? A C# programmer would write it that way too. See the TryParse methods found all over the C# standard library. On the other hand, what would a Rust programmer do to handle an out of memory situation? That would be too pervasive with the result approach so it has been culled from all interfaces. Also, nullable reference types are a separate issue.
and C#'s is written:
Both require familiarity with the stdlib (Parse throws, TryParse doesn't, unwrap fails).
I agree that TryParse is worse than Rust's ADT approach, but that's a different issue, much like nullable references. The author is asserting that results are superior to exceptions and I am asserting that no, that is just a bad application of exceptions. Additionally, I am asserting that without exceptions, you limit what programmers are willing to propagate through their interfaces because errors become viral.