Honestly I really like C#'s outvar and return success idiom. It's soooo ugly and yet slick at the same time. C does the same thing but I think the inline out var declarations make a huge difference to using them. Of course you miss out on error context an Exception or Result<T, Err> gives you but for many of the Try* functions it really doesn't matter.
In a lot of cases Try* is the outright right approach, too. Like `IDictionary.TryGetValue(key, out var value)` is better than try { var value = IDictionary.GetValue(key); } catch (KeyNotFoundException) {}` and has no race like `if (IDictionary.ContainsKey(key)) IDictionary.GetValue(key);`.
Try* functions are still free to throw in actually exceptional cases, just not on generic not-so-exceptional errors.
If you really need context, there is nothing from stopping you from implementing Try* functions in your own APIs that either have another out param for the error information, return the error information instead of a bool or use a Result<T, Err> kind of type (or a tuple), either.