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?

Reply via email to