but it needs to be in the language so that the tricky code is write once.
but it needs to be in the language so that the tricky code is write once.
In .NET and Java it costs at least 100x as much time to throw an exceptions as to return an error code.
Other languages may have cheaper exceptions, but for many mainstream languages, you pay a big performance price for exceptions.
That price is often offset by other positive things, so the tradeoff is made willingly and with eyes open.
Don't know about .NET but in Java it is not throwing exceptions that is heavy but filling in stack trace during construction of a Throwable. It can be made much more performant using constructor that disables stack trace: https://docs.oracle.com/en/java/javase/21/docs/api/java.base...
The conjecture is that if checks are always executed while exceptions are free when not thrown.
That said, predicted branches are also fairly free so arguing about this in the abstract is pointless.
Though profile guided optimization will probably catch this. And it might be that even without, compilers still optimize around this.