Hello all. > Yes. And even if it can be made faster (as it looks like Niels is doing, which is great), it will never be as fast as an empty constructor and a return. That's the level I'm proposing.
If the backtrace is generated only when needed, rather than at the moment the exception is created, there will be no difference or almost no difference (if a stack unwinding algorithm is used). The total number of CPU/memory operations will be approximately the same. The only difference is that deferred backtrace generation will require more complex frame return code, which may introduce pitfalls. However, if a backtrace is needed by itself, such overhead is unavoidable regardless of whether exceptions are used or not. > I somewhat glossed over this point, but let me expand on it here. So the exception hierarchy in PHP is far from ideal. Understood. The hierarchy can be improved to make it more logical and consistent. And as I understand it, changing the exceptions themselves is not required for that. > Moreover, all exceptions currently track: Yes. And the main problem among them is the trace property. Neither file nor line cause significant overhead, because file is a reference to a string constant, and line is an integer. > This is incorrect, as making the current exception system checked would be a ginormous BC break. > And having some throwables be checked and some not, but using the same syntax and class hierarchy... well, that's the reason everyone detests Java's exceptions. Let's not do that. While introducing a new entity, such as a "New Error Stream" with defined contract rules, is theoretically possible, it would not fundamentally change the current situation. In practice, this approach would introduce a second category of exceptions, requiring developers to manage: - the primary execution flow, - the standard exception flow, - a "special exception flow" that must be converted back into the standard one when necessary. This added complexity may outweigh the potential benefits, especially given that the primary value would be limited to preserving backward compatibility. It is worth carefully considering whether such a change justifies the additional mental and technical overhead. On the other side of the scale: - replacing @throws with a special syntax (or perhaps simply introducing a new attribute?), - defining the behavior in case of contract violation while preserving backward compatibility. For example, if an exception contract is violated, an error would not be thrown; instead, a warning would be issued, which would not break the program's execution flow but would help draw the developer’s attention to the issue. Later in the letter you explain in more detail that this is *not a special kind of exception*, nor a new execution flow, but rather a* special type of result*. But if this is a special type of result, then it should follow *the same rules as all PHP types*. In other words, this cannot be solved without generics. However, the benefit of the new syntax, which could make the code cleaner, does not depend on generics: For example: ```php $res = someFunction() catch ($err) {throw $err;} // Like Zig? ``` But then the return type must be Throwable. The advantage of generics like Result<> is that they do not create a separate return channel. Everything operates within a single flow. However, this approach is not yet possible in PHP. Introducing an additional return channel would mean increasing the overall complexity. Of course, this is a clean and useful syntax for such cases. Moreover, the catch block could be made mandatory if the function is marked with a contract — meaning the function cannot be called without a catch block at all. However, it seems to me that we can achieve the same result using throw, simply by adding new syntax and capabilities. Yes, there may be some backward compatibility issues, but is it really something to be afraid of?