Unfortunately in static languages this leads to an unholy amount of boilerplate:
public Result<SomethingGood, SomethingBad> PerformUpdate(int goodThingId, UpdateForm form) { ... return new Result<SomethingGood, SomethingBad>(error); ... return new Result<SomethingGood, SomethingBad>(obj); }
The type annotations were hell. Sometimes there were three cases we wanted to consider. We went back to using exceptions, and are keeping a keen eye on the new C# features.
So ultimately - I agree with the author that throwing exceptions is fine, when things actually go wrong. It's also not that bad when things kinda went wrong, but sometimes the effort required to fix it isn't worth it.