Morning internals,
The expectations RFC is now in voting phase:
https://wiki.php.net/rfc/expectations#vote
Cheers
Joe
Hi,
Morning internals,
The expectations RFC is now in voting phase:
-
I somehow miss information what the exact differences are to the
current implementation, to better judge the impact. -
how does zend.assertions and assert.exceptions work with
"assert_options()" , i.e. isn't the exception behavior meant to be an
addition toassert_options()
too ? -
the RFC says: "enabled (zend.assertions=1) on development machines,
and disabled (zend.assertions=0) in production"; a few paragraphs above
it says "-1 - don't generate any code (zero-cost, production mode)".
Shouldn't be -1 the default value for production then? -
the RFC says: "A call to
assert()
, without a fully qualified namespace
will call assert in the current namespace, if the function exists. An
unqualified call to assert is subject to the same optimization
configured by zend.assertions. ". Does this mean I can control whether a
function in a namespace is being optimized-away with when zend.assertion
equals -1 and otherwise do my own stuff in there and need to raise an
AssertException on my own to signal assertion fails?
thank you,
- Markus
Hi,
Morning internals,
The expectations RFC is now in voting phase:
- I somehow miss information what the exact differences are to the
current implementation, to better judge the impact.
The implementation introduces ZEND_ASSERT_CHECK instruction that will jump
around calls to assert()
depending on zend.assertions ini option. (call and
constraint evaluation may be expensive).
It's also possible to avoid compilation of asset() at all (setting
zend.assertions=-1)
This will allow using assert()
for program testing, without performance
degradation in production.
- how does zend.assertions and assert.exceptions work with
"assert_options()" , i.e. isn't the exception behavior meant to be an
addition toassert_options()
too ?
zend.assertions control assert()
compilation and execution
zend.assertions=-1 zero-cost, assert()
won't be compiled at all (including
inner code)
zend.assertions=0 low-cost, assert()
will be compiled but won't be
executes (including inner code)
zend.assertions=1 assert()
wiil be compiled and executed as now
- the RFC says: "enabled (zend.assertions=1) on development machines,
and disabled (zend.assertions=0) in production"; a few paragraphs above
it says "-1 - don't generate any code (zero-cost, production mode)".
Shouldn't be -1 the default value for production then?
With zend.assertions=0 in production, you'll able to switch to
zend.assertions=0 at any time.
With zend.assertions=-1 of course not.
- the RFC says: "A call to
assert()
, without a fully qualified namespace
will call assert in the current namespace, if the function exists. An
unqualified call to assert is subject to the same optimization
configured by zend.assertions. ". Does this mean I can control whether a
function in a namespace is being optimized-away with when zend.assertion
equals -1 and otherwise do my own stuff in there and need to raise an
AssertException on my own to signal assertion fails?
Yes. you are able to eliminate your own assert()
functions in namespaces.
Thanks. Dmitry.
thank you,
- Markus
- how does zend.assertions and assert.exceptions work with
"assert_options()" , i.e. isn't the exception behavior meant to be an
addition toassert_options()
too ?zend.assertions control
assert()
compilation and executionzend.assertions=-1 zero-cost,
assert()
won't be compiled at all (including
inner code)
zend.assertions=0 low-cost,assert()
will be compiled but won't be
executes (including inner code)
zend.assertions=1assert()
wiil be compiled and executed as now
Pardon me, but it doesn't explain what the role of the existing
"assert_options()" function will or does play?
- the RFC says: "enabled (zend.assertions=1) on development machines,
and disabled (zend.assertions=0) in production"; a few paragraphs above
it says "-1 - don't generate any code (zero-cost, production mode)".
Shouldn't be -1 the default value for production then?With zend.assertions=0 in production, you'll able to switch to
zend.assertions=0 at any time.
With zend.assertions=-1 of course not.
I don't understand this. "With 'foo' in production, you will be able to
switch to 'foo' at any time. With 'bar' of course not" ?
Maybe I was unclear. What I meant:
- a few paragraphs above it says that "-1 doesn't generate any code
(zero cost)" - so why isn't THAT '-1' promoted to be the default in production
php.ini instead of '0' setting?
- the RFC says: "A call to
assert()
, without a fully qualified namespace
will call assert in the current namespace, if the function exists. An
unqualified call to assert is subject to the same optimization
configured by zend.assertions. ". Does this mean I can control whether a
function in a namespace is being optimized-away with when zend.assertion
equals -1 and otherwise do my own stuff in there and need to raise an
AssertException on my own to signal assertion fails?Yes. you are able to eliminate your own
assert()
functions in namespaces.
Wow. The RFC doesn't explain this very well but I wrote this based on
assumption and guesswork.
This sounds two-folded to me: "very cool" (albeit I can't see a use-case
right now) on one hand and "utter magic" on the other.
With utter magic I mean: suddenly a function named 'assert' in a
namespace is eligible to rules before ever only applied to a global
existing function.
I'm not saying it's bad. It's just very magic, sounds cool but could be
a real PITA. Maybe just a documentation problem after all.
As Pierre already mentioned, the RFC really lacks some more details. But
in general, it looks good.
thank you,
- Markus
This sounds two-folded to me: "very cool" (albeit I can't see a use-case
right now) on one hand and "utter magic" on the other.
Inclined to agree.
@Joe what use-case prompted this feature?
I work on a massive codebase, 3m loc, the ability to document that we throw
SomeAssertionException in insert circumstance is extremely appealing. It
would allow us to structure the documentation and the code in a way that
really makes sense especially for new developers. The alternatives are not
nice, in my opinion. It's not about runtime, and the ability to catch
specific exceptions by name, at all, there shouldn't be any catch blocks
for AssertionExceptions in deployed code.
Cheers
Joe
This sounds two-folded to me: "very cool" (albeit I can't see a use-case
right now) on one hand and "utter magic" on the other.Inclined to agree.
@Joe what use-case prompted this feature?
Am 20.02.2015 um 12:27 schrieb Joe Watkins:
I work on a massive codebase, 3m loc, the ability to document that we throw
SomeAssertionException in insert circumstance is extremely appealing. It
would allow us to structure the documentation and the code in a way that
really makes sense especially for new developers. The alternatives are not
nice, in my opinion. It's not about runtime, and the ability to catch
specific exceptions by name, at all,
there shouldn't be any catch blocks for AssertionExceptions in deployed code
Hello Joe,
can you please explain a bit more how you would achieve this in 3m loc?
Thanks!
The alternatives are not nice, in my opinion.
What are this alternatives? What are the drawbacks of "warning" in
production code?
can you please explain a bit more how you would achieve this in 3m loc?
AssertionExceptions are not intended to be caught, they are intended to be
seen, in a specific environment.
It doesn't really make sense to commit/deploy code that catches
AssertionExceptions knowing that the code is actually dead in production.
So you just don't deploy catch blocks for AssertionException, you might
write one while debugging locally, but deploying them doesn't make sense.
Cheers
Joe
On Fri, Feb 20, 2015 at 1:05 PM, Crypto Compress <
cryptocompress@googlemail.com> wrote:
The alternatives are not nice, in my opinion.
What are this alternatives? What are the drawbacks of "warning" in
production code?
AssertionExceptions are not intended to be caught, they are intended
to be seen, in a specific environment.
Joe, your argumentation is around how (not) to use exceptions. I can see
your point and it's valid.
My point is about not to implement exceptions at all.
If exceptions are not intended to be caught, they don't need to be
thrown (even if the context is different).
If exceptions are not thrown and not caught, we can use "error" in dev
and some easing severity (warning, zero cost nothing) in prod.
Freely adapted from Murphy: If assertion exception can be catched, it
will be even in production.
On Fri, Feb 20, 2015 at 3:02 PM, Crypto Compress <
cryptocompress@googlemail.com> wrote:
AssertionExceptions are not intended to be caught, they are intended to
be seen, in a specific environment.
Joe, your argumentation is around how (not) to use exceptions. I can see
your point and it's valid.
My point is about not to implement exceptions at all.If exceptions are not intended to be caught, they don't need to be thrown
(even if the context is different).
If exceptions are not thrown and not caught, we can use "error" in dev and
some easing severity (warning, zero cost nothing) in prod.Freely adapted from Murphy: If assertion exception can be catched, it will
be even in production.
The point behind AssertionException is that
a) It will leave the scope where with the failed assertion immediately. A
warning would continue running the code, even though some precondition is
violated, which doesn't make sense.
b) It can still be gracefully handled (unlike a fatal error). E.g. the unit
testing framework can catch it, so you can continue running all your tests
even if one causes an assertion failure.
When Joe says "not intended to be caught" this is referring to "normal"
code. Catching them at the top-level still makes sense, e.g. for the unit
testing case mentioned or even just to print a nice error message with
extra information. Using an exception instead of a fatal error also means
that things like "finally" will still run, so your code can still release
locks etc even if an assertion failure occurred.
Nikita
Am 20.02.2015 um 15:09 schrieb Nikita Popov:
On Fri, Feb 20, 2015 at 3:02 PM, Crypto Compress
<cryptocompress@googlemail.com mailto:cryptocompress@googlemail.com>
wrote:AssertionExceptions are not intended to be caught, they are intended to be seen, in a specific environment. Joe, your argumentation is around how (not) to use exceptions. I can see your point and it's valid. My point is about not to implement exceptions at all. If exceptions are not intended to be caught, they don't need to be thrown (even if the context is different). If exceptions are not thrown and not caught, we can use "error" in dev and some easing severity (warning, zero cost nothing) in prod. Freely adapted from Murphy: If assertion exception can be catched, it will be even in production.
The point behind AssertionException is that
a) It will leave the scope where with the failed assertion
immediately. A warning would continue running the code, even though
some precondition is violated, which doesn't make sense.
Assumed context is wrong here.
- exception in development: error
- no exception in production: warning, zero cost nothing
Rephrased: A zero-cost non-existing exception would continue running the
code, ...
In a previous email you brought up the point if or not derive
AssertionEx from Exception. I argue that all child exception MUST BE
derived from Exception. Any exception to this is not an Exception. (my
english is too limited to explain this, sorry)
b) It can still be gracefully handled (unlike a fatal error). E.g. the
unit testing framework can catch it, so you can continue running all
your tests even if one causes an assertion failure.
Unit test frameworks do this already. No change here.
When Joe says "not intended to be caught" this is referring to
"normal" code. Catching them at the top-level still makes sense, e.g.
for the unit testing case mentioned or even just to print a nice error
message with extra information. Using an exception instead of a fatal
error also means that things like "finally" will still run, so your
code can still release locks etc even if an assertion failure occurred.
In production this will never happen. We go round in circles here. I am
aware of you preference on "exceptions everywhere".
Nikita
However I think it is pre
mature to vote on as there was (sorry) not explicit discussions about
it.
I haven't heard that from anyone else, the RFC is plenty old.
A couple of things are unclear. See the numerous questions in this thread.
I also do not like other things.
These don't seem like valid reasons to hold off progress.
zend.assertions:
Having a more general debug setting might be a good idea, but is outside of
the scope of this RFC.
assert.exceptions:
Delay isn't necessary, exceptions are not used by default, and there is
plenty of time for Engine Exceptions to make necessary changes.
Cheers
Joe
On Fri, Feb 20, 2015 at 2:55 PM, Crypto Compress <
cryptocompress@googlemail.com> wrote:
Am 20.02.2015 um 15:09 schrieb Nikita Popov:
On Fri, Feb 20, 2015 at 3:02 PM, Crypto Compress <
cryptocompress@googlemail.com mailto:cryptocompress@googlemail.com>
wrote:AssertionExceptions are not intended to be caught, they are intended to be seen, in a specific environment. Joe, your argumentation is around how (not) to use exceptions. I can see your point and it's valid. My point is about not to implement exceptions at all. If exceptions are not intended to be caught, they don't need to be thrown (even if the context is different). If exceptions are not thrown and not caught, we can use "error" in dev and some easing severity (warning, zero cost nothing) in prod. Freely adapted from Murphy: If assertion exception can be catched, it will be even in production.
The point behind AssertionException is that
a) It will leave the scope where with the failed assertion immediately. A
warning would continue running the code, even though some precondition is
violated, which doesn't make sense.Assumed context is wrong here.
- exception in development: error
- no exception in production: warning, zero cost nothing
Rephrased: A zero-cost non-existing exception would continue running the
code, ...In a previous email you brought up the point if or not derive AssertionEx
from Exception. I argue that all child exception MUST BE derived from
Exception. Any exception to this is not an Exception. (my english is too
limited to explain this, sorry)b) It can still be gracefully handled (unlike a fatal error). E.g. the
unit testing framework can catch it, so you can continue running all your
tests even if one causes an assertion failure.Unit test frameworks do this already. No change here.
When Joe says "not intended to be caught" this is referring to "normal"
code. Catching them at the top-level still makes sense, e.g. for the unit
testing case mentioned or even just to print a nice error message with
extra information. Using an exception instead of a fatal error also means
that things like "finally" will still run, so your code can still release
locks etc even if an assertion failure occurred.In production this will never happen. We go round in circles here. I am
aware of you preference on "exceptions everywhere".Nikita
However I think it is pre
mature to vote on as there was (sorry) not explicit discussions about
it.I haven't heard that from anyone else, the RFC is plenty old.
A couple of things are unclear. See the numerous questions in this thread.
I also do not like other things.These don't seem like valid reasons to hold off progress.
zend.assertions:
Having a more general debug setting might be a good idea, but is outside of
the scope of this RFC.
So it is fine to have one setting doing the exact same thing? Sorry, I
disagree. We know we need that in other areas. Like other recent RFCs,
we have solved them bottom-up. This one is no different.
assert.exceptions:
Delay isn't necessary, exceptions are not used by default, and there is
plenty of time for Engine Exceptions to make necessary changes.
So basically what you say is that this RFC, relying on things we
should clarify and define clearly so it will be consistent across the
engine and language, are not relevant to this RFC? I totally disagree
and hence my point that this RFC needs more (public) discussions and
things that are prerequisites for this RFC should be designed,
discussed and implemented before this RFC.
I will certainly be the only one voting no at this stage, or maybe not
even voting because I simply feel like you discussed that already no
matter where and came to this RFC and say take it or leave it. I am
not a fan of this approach or we can rename "Request For Comments" to
"Request to Accept" as any kind of comments or feedback is simply not
taken into accounts.
Cheers,
Pierre
@pierrejoye | http://www.libgd.org
To be harsh: All comments in favour of throwing exceptions here,
substantiate theirs needs with dead, never reached and potentially buggy
code.
The changed code flow in production is the big pitfall of this RFC and
an absolute no-go. I like zero-cost assertions but throwing exceptions
is wrong.
my 2 cents
...exceptions are not used by default...
Can't find this point in RFC.
So it is fine to have one setting doing the exact same thing? Sorry, I
disagree. We know we need that in other areas. Like other recent RFCs,
we have solved them bottom-up. This one is no different.
It's fine for an RFC to be focused on one thing. This is another subject.
So basically what you say is that this RFC, relying on things we
should clarify and define clearly so it will be consistent across the
engine and language, are not relevant to this RFC? I totally disagree
and hence my point that this RFC needs more (public) discussions and
things that are prerequisites for this RFC should be designed,
discussed and implemented before this RFC.
I'm saying that this isn't a subject for this RFC, deciding if we're going
to have multiple exception trees is simply not in scope.
I will certainly be the only one voting no at this stage, or maybe not
even voting because I simply feel like you discussed that already no
matter where and came to this RFC and say take it or leave it. I am
not a fan of this approach or we can rename "Request For Comments" to
"Request to Accept" as any kind of comments or feedback is simply not
taken into accounts.
I'm sorry that you don't remember the discussion, but it did happen, the
RFC has been in (more or less) it's current form for more than a year.
The current form is the result of discussion.
Please stop saying it hasn't been discussed, it has, a lot.
Cheers
Joe
On Fri, Feb 20, 2015 at 3:48 PM, Crypto Compress <
cryptocompress@googlemail.com> wrote:
To be harsh: All comments in favour of throwing exceptions here,
substantiate theirs needs with dead, never reached and potentially buggy
code.
The changed code flow in production is the big pitfall of this RFC and
an absolute no-go. I like zero-cost assertions but throwing exceptions is
wrong.my 2 cents
...exceptions are not used by default...
Can't find this point in RFC.
So it is fine to have one setting doing the exact same thing? Sorry, I
disagree. We know we need that in other areas. Like other recent RFCs,
we have solved them bottom-up. This one is no different.It's fine for an RFC to be focused on one thing. This is another subject.
So basically what you say is that this RFC, relying on things we
should clarify and define clearly so it will be consistent across the
engine and language, are not relevant to this RFC? I totally disagree
and hence my point that this RFC needs more (public) discussions and
things that are prerequisites for this RFC should be designed,
discussed and implemented before this RFC.I'm saying that this isn't a subject for this RFC, deciding if we're going
to have multiple exception trees is simply not in scope.
Why I use the word "prerequisite" and not "part of this RFC".
I will certainly be the only one voting no at this stage, or maybe not
even voting because I simply feel like you discussed that already no
matter where and came to this RFC and say take it or leave it. I am
not a fan of this approach or we can rename "Request For Comments" to
"Request to Accept" as any kind of comments or feedback is simply not
taken into accounts.I'm sorry that you don't remember the discussion, but it did happen, the
RFC has been in (more or less) it's current form for more than a year.The current form is the result of discussion.
Please stop saying it hasn't been discussed, it has, a lot.
Some stuff covered by this RFC have part of a bigger discussions about
many different things.
Did we have a [RFC][Discuss] thread to actually discuss this exact
RFC? No, we did not. And it is cruelly needed.
Cheers,
Pierre
@pierrejoye | http://www.libgd.org
No, we did not
Yes, we did, which you could have found out, if you were really bothered:
https://marc.info/?l=php-internals&m=138213285708117&w=2
Cheers
Joe
On Fri, Feb 20, 2015 at 8:24 AM, Joe Watkins pthreads@pthreads.org
wrote:So it is fine to have one setting doing the exact same thing? Sorry, I
disagree. We know we need that in other areas. Like other recent RFCs,
we have solved them bottom-up. This one is no different.It's fine for an RFC to be focused on one thing. This is another subject.
So basically what you say is that this RFC, relying on things we
should clarify and define clearly so it will be consistent across the
engine and language, are not relevant to this RFC? I totally disagree
and hence my point that this RFC needs more (public) discussions and
things that are prerequisites for this RFC should be designed,
discussed and implemented before this RFC.I'm saying that this isn't a subject for this RFC, deciding if we're
going
to have multiple exception trees is simply not in scope.Why I use the word "prerequisite" and not "part of this RFC".
I will certainly be the only one voting no at this stage, or maybe not
even voting because I simply feel like you discussed that already no
matter where and came to this RFC and say take it or leave it. I am
not a fan of this approach or we can rename "Request For Comments" to
"Request to Accept" as any kind of comments or feedback is simply not
taken into accounts.I'm sorry that you don't remember the discussion, but it did happen, the
RFC has been in (more or less) it's current form for more than a year.The current form is the result of discussion.
Please stop saying it hasn't been discussed, it has, a lot.
Some stuff covered by this RFC have part of a bigger discussions about
many different things.Did we have a [RFC][Discuss] thread to actually discuss this exact
RFC? No, we did not. And it is cruelly needed.Cheers,
Pierre
@pierrejoye | http://www.libgd.org
No, we did not
Yes, we did, which you could have found out, if you were really bothered:
You are kidding me here and I already answered to that:
2013-10-18 21:46:45
So no, it has not given what is presented.
Anyway, I see no point arguing about the lack of discussions as you
obviously won't change your mind nor go back to discussion for this
RFC. Pointless and waste of time.
Hi Crypto,
On Fri, Feb 20, 2015 at 11:02 PM, Crypto Compress <
cryptocompress@googlemail.com> wrote:
AssertionExceptions are not intended to be caught, they are intended to be
seen, in a specific environment.
Joe, your argumentation is around how (not) to use exceptions. I can see
your point and it's valid.
My point is about not to implement exceptions at all.If exceptions are not intended to be caught, they don't need to be thrown
(even if the context is different).
If exceptions are not thrown and not caught, we can use "error" in dev and
some easing severity (warning, zero cost nothing) in prod.Freely adapted from Murphy: If assertion exception can be catched, it will
be even in production.
Assertion is only for development and testing.
We need errors or exceptions during development and testing, but
not in production. Therefore, errors/exception should not be catched
by code in general. Isn't assertion nature?
I don't insist not to enable assertion in production environment.
There might be software that needs extreme reliability and stability.
For these softwares, it makes sense to enable assertions and catch
errors/exceptions to do some cleanups.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Crypto,
On Fri, Feb 20, 2015 at 11:02 PM, Crypto Compress <
cryptocompress@googlemail.com> wrote:AssertionExceptions are not intended to be caught, they are intended to be
seen, in a specific environment.
Joe, your argumentation is around how (not) to use exceptions. I can see
your point and it's valid.
My point is about not to implement exceptions at all.If exceptions are not intended to be caught, they don't need to be thrown
(even if the context is different).
If exceptions are not thrown and not caught, we can use "error" in dev and
some easing severity (warning, zero cost nothing) in prod.Freely adapted from Murphy: If assertion exception can be catched, it will
be even in production.Assertion is only for development and testing.
We need errors or exceptions during development and testing, but
not in production. Therefore, errors/exception should not be catched
by code in general. Isn't assertion nature?I don't insist not to enable assertion in production environment.
There might be software that needs extreme reliability and stability.
For these softwares, it makes sense to enable assertions and catch
errors/exceptions to do some cleanups.
This last paragraph makes me wonder why in the world assert in PHP is
still anything valid. If anything it should be removed, to be honest.
Which softwares do not require to be reliable and stable? Most if not
all PHP written software interact with external inputs, be from APIs
point of view or from actual users. Per se, they have to be validated
and errors handling is part of this validation.
I do see some values for asserts in unit tests, but that's pretty much
all I can think about it.
All in all, I stay with my initial comment, this RFC needs more
discussion and some other critical questions must be answered before
this RFC.
Cheers,
Pierre
@pierrejoye | http://www.libgd.org
Hi Pierre,
Assertion is only for development and testing.
We need errors or exceptions during development and testing, but
not in production. Therefore, errors/exception should not be catched
by code in general. Isn't assertion nature?I don't insist not to enable assertion in production environment.
There might be software that needs extreme reliability and stability.
For these softwares, it makes sense to enable assertions and catch
errors/exceptions to do some cleanups.This last paragraph makes me wonder why in the world assert in PHP is
still anything valid. If anything it should be removed, to be honest.Which softwares do not require to be reliable and stable? Most if not
all PHP written software interact with external inputs, be from APIs
point of view or from actual users. Per se, they have to be validated
and errors handling is part of this validation.I do see some values for asserts in unit tests, but that's pretty much
all I can think about it.All in all, I stay with my initial comment, this RFC needs more
discussion and some other critical questions must be answered before
this RFC.
We don't put test code checks in production code, do we?
Testing and assertion is to prevent simple bugs, to help finding bugs.
Once development/testing is done, these code will not be needed.
You may think assertion as contracts of code. Once developers ensured
all contracts were kept, contract validations are not needed anymore.
By this proposal, developers can check contracts anywhere in code,
any number of times during development without sacrificing production
code efficiency. This helps to write solid code. Assertion would be
great tool for library/framework developers to prevent users to
abuse/misuse
it also.
Even if we test software with comprehensive manner, software has bugs.
Assertion may help to detected/prevent "unexpected" software behavior.
It's users choice if they enable assertions. Assertions are supposed not
to do any useful checks in production, but it may help.
I agree that users may abuse/misuse assertion, but most tools can be
abused/misused like require()/include(). I agree that users must
validate all input/output (and PHP should help it). These validations must
be done as usual code, not assertion.
I hope I could explain well enough.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Pierre,
Assertion is only for development and testing.
We need errors or exceptions during development and testing, but
not in production. Therefore, errors/exception should not be catched
by code in general. Isn't assertion nature?I don't insist not to enable assertion in production environment.
There might be software that needs extreme reliability and stability.
For these softwares, it makes sense to enable assertions and catch
errors/exceptions to do some cleanups.This last paragraph makes me wonder why in the world assert in PHP is
still anything valid. If anything it should be removed, to be honest.Which softwares do not require to be reliable and stable? Most if not
all PHP written software interact with external inputs, be from APIs
point of view or from actual users. Per se, they have to be validated
and errors handling is part of this validation.I do see some values for asserts in unit tests, but that's pretty much
all I can think about it.All in all, I stay with my initial comment, this RFC needs more
discussion and some other critical questions must be answered before
this RFC.We don't put test code checks in production code, do we?
Testing and assertion is to prevent simple bugs, to help finding bugs.
Once development/testing is done, these code will not be needed.You may think assertion as contracts of code. Once developers ensured
all contracts were kept, contract validations are not needed anymore.
By this proposal, developers can check contracts anywhere in code,
any number of times during development without sacrificing production
code efficiency. This helps to write solid code. Assertion would be
great tool for library/framework developers to prevent users to
abuse/misuse
it also.Even if we test software with comprehensive manner, software has bugs.
Assertion may help to detected/prevent "unexpected" software behavior.
It's users choice if they enable assertions. Assertions are supposed not
to do any useful checks in production, but it may help.I agree that users may abuse/misuse assertion, but most tools can be
abused/misused like require()/include(). I agree that users must
validate all input/output (and PHP should help it). These validations
must
be done as usual code, not assertion.I hope I could explain well enough.
I pretty well know what assertions are. Thanks for the refreshing
explanation anyway :)
I do not see much gain today to "improve" them while I do not see why we
should not. It does not hurt.
My issue is more on the exception part of it and the relative unreadiness
of this rfc as well as the prerequisites, see what I wrote in my past
replies.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
I do not see much gain today to "improve" them while I do not see why we
should not. It does not hurt.
The gain is simple - today, assertions have costs so people that are
performance-conscious (rightly or wrongly) use them less than they
could. We can make them cost-less in production, while preserving their
advantages in the test environments (also makes code easier to follow
btw if asserts show which invariants are being enforced). Unit tests
only provide for assertions in test code, but cost-less asserts can help
you ensure that code works the way you intended all the way through,
without paying for that with performance.
Stas Malyshev
smalyshev@gmail.com
Am 21.02.2015 um 04:10 schrieb Yasuo Ohgaki:
Hi Crypto,
On Fri, Feb 20, 2015 at 11:02 PM, Crypto Compress
<cryptocompress@googlemail.com mailto:cryptocompress@googlemail.com>
wrote:AssertionExceptions are not intended to be caught, they are intended to be seen, in a specific environment. Joe, your argumentation is around how (not) to use exceptions. I can see your point and it's valid. My point is about not to implement exceptions at all. If exceptions are not intended to be caught, they don't need to be thrown (even if the context is different). If exceptions are not thrown and not caught, we can use "error" in dev and some easing severity (warning, zero cost nothing) in prod. Freely adapted from Murphy: If assertion exception can be catched, it will be even in production.
Assertion is only for development and testing.
We need errors or exceptions during development and testing, but
not in production. Therefore, errors/exception should not be catched
by code in general. Isn't assertion nature?I don't insist not to enable assertion in production environment.
There might be software that needs extreme reliability and stability.
For these softwares, it makes sense to enable assertions and catch
errors/exceptions to do some cleanups.Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net mailto:yohgaki@ohgaki.net
Hi Yasuo,
sorry for the late answer. My point is about throwing exceptions
(assert.exceptions=1). I think it is wrong to allow to change code-flow
by ini-setting and in current context it is wrong to throw exceptions
altogether. Let's assume this code example in dev-mode with exceptions:
class BankAccount {
function Add($amount) {
assert($amount > 0);
// ... code block ...
}
}
Now the programmer implementing "code block" to gracefully handle
$amount > 0 has a problem. There is no way to (Unit)test failing path on
development machine. Code after assertion is never called for failing
contitions. What to do? Delete assertion is out of question. Disable
zend.assertions on development machine seems to be the wrong way too.
The only way to handle this is to disable exceptions
(assert.exceptions=0) so expected code flow is restored. This, if
allowed to be changed, should be at least the default.
IMO ability to run and test code broadly outweighs "provides stacktrace
by default" argument and for some reason i fear assert.exceptions=1 will
be the only case soon.
cryptocompress
Am 28.02.2015 19:32 schrieb "Crypto Compress" <cryptocompress@googlemail.com
:
class BankAccount {
function Add($amount) {
assert($amount > 0);
// ... code block ...
}
}Now the programmer implementing "code block" to gracefully handle $amount
0 has a problem. There is no way to (Unit)test failing path on
development machine. Code after assertion is never called for failing
contitions. What to do?
Put the assert AFTER handling the always-to-be-done validation, of course.
Doesn't make sense otherwise.
Patrick
Am 28.02.2015 um 20:08 schrieb Patrick Schaaf:
Am 28.02.2015 19:32 schrieb "Crypto Compress"
<cryptocompress@googlemail.com mailto:cryptocompress@googlemail.com>:class BankAccount {
function Add($amount) {
assert($amount > 0);
// ... code block ...
}
}Now the programmer implementing "code block" to gracefully handle
$amount > 0 has a problem. There is no way to (Unit)test failing path
on development machine. Code after assertion is never called for
failing contitions. What to do?Put the assert AFTER handling the always-to-be-done validation, of
course. Doesn't make sense otherwise.Patrick
if ($amount > 0) { ...code block... }
// else {
throw new WrongAmountEx();
// }
Frankly i can't see any point in using assertion after checked
expression thus duplicate the expression. It's simple a bug. As
situation is clearly wrong, throw/exit/die and change code flow as
desired. This is not the "conditionally unreachable code" case i argue
about.
Hi Crypto,
On Sun, Mar 1, 2015 at 3:32 AM, Crypto Compress <
cryptocompress@googlemail.com> wrote:
sorry for the late answer. My point is about throwing exceptions
(assert.exceptions=1). I think it is wrong to allow to change code-flow by
ini-setting and in current context it is wrong to throw exceptions
altogether. Let's assume this code example in dev-mode with exceptions:class BankAccount {
function Add($amount) {
assert($amount > 0);
// ... code block ...
}
}Now the programmer implementing "code block" to gracefully handle $amount
0 has a problem. There is no way to (Unit)test failing path on
development machine. Code after assertion is never called for failing
contitions. What to do? Delete assertion is out of question. Disable
zend.assertions on development machine seems to be the wrong way too. The
only way to handle this is to disable exceptions (assert.exceptions=0) so
expected code flow is restored. This, if allowed to be changed, should be
at least the default.IMO ability to run and test code broadly outweighs "provides stacktrace by
default" argument and for some reason i fear assert.exceptions=1 will be
the only case soon.
I understand that removing assert conditions may seem to increase bugs in
code.
Wrong usage of assertion actually creates bugs. I agree.
However, assertion is not for production checks, but development time
checks.
Code example you're presented requires "caller" to make sure "$amount > 0"
condition
is met. Unit tests has to make sure "$amount > 0" condition is kept without
assertion.
Assertion (as well as DbC) helps to make sure if conditions/expectations of
"callee"
are fulfilled by "caller". Since caller must fulfill condition in the first
place, removing
assertions should not be problem under production environment and
production
codes execute faster.
Under structured programming, developers tend error condition check
responsibility
to "callee", just like your example. Use of assertion is DbC style
programming
which forces error condition checks to "caller". It changes why of thinking
and
these changes may be difficult to adopt for some developers, but the basic
idea is simple enough to be understood by all developers. I hope.
What good about DbC is it can achieve both robust development and faster
execution at the same time if it is used properly. I understand your
concern.
Developers must think what/where is the error condition check
responsibility.
Without this, the result can be fatal. Even if assertion/DbC has cons, its
pros
outweigh cons, IMHO.
Assertion/DbC
- Promotes caller to validate inputs. Input validation is the most
important for secure code. - Underlying simple APIs that are called many times can omit various
condition checks in production. (Faster execution) - Prevents wrong usage of API during development by assert failure.
- Makes developers to think where/how to implement "defense in depth"
properly. (Since no assertion checks in production, developers have to
think where/how to implement additional systematic defense in their code.
This is good for better security.)
I fully agree that users can misuse. We must make effort that users
understand
proper usage and idea behind assertions/DbC.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Morning internals,
The expectations RFC is now in voting phase:
I totally miss the Expectation RFC announcement. Where the RFC was
actually proposed for discussions.
I have been following up the DbC thread, seeing some mentions but
that's it. The RFC itself popped up 3 days ago.
Also the RFC itself only point to various discussions, there is no
summary, details, docs, examples, etc in the RFC.
I am sorry but as much I like (for what I think it does) as I like the
concept, this RFC does not have, by far, the quality I would expect
for a RFC being voted on.
Cheers,
Pierre
@pierrejoye | http://www.libgd.org
On Thu, Feb 19, 2015 at 1:09 AM, Joe Watkins pthreads@pthreads.org
wrote:Morning internals,
The expectations RFC is now in voting phase:
I totally miss the Expectation RFC announcement. Where the RFC was
actually proposed for discussions.I have been following up the DbC thread, seeing some mentions but
that's it. The RFC itself popped up 3 days ago.
It's from 2013 and it was discussed actively during last week.
Thanks. Dmitry.
Also the RFC itself only point to various discussions, there is no
summary, details, docs, examples, etc in the RFC.I am sorry but as much I like (for what I think it does) as I like the
concept, this RFC does not have, by far, the quality I would expect
for a RFC being voted on.Cheers,
Pierre
@pierrejoye | http://www.libgd.org
On Thu, Feb 19, 2015 at 1:09 AM, Joe Watkins pthreads@pthreads.org
wrote:Morning internals,
The expectations RFC is now in voting phase:
I totally miss the Expectation RFC announcement. Where the RFC was
actually proposed for discussions.I have been following up the DbC thread, seeing some mentions but
that's it. The RFC itself popped up 3 days ago.It's from 2013
Yes, but....
and it was discussed actively during last week.
Still, no announce for a discussion about this specific RFC. And
really, the content of the RFC is almost empty, pointing to the ML
archive is really not the right way :)
On Thu, Feb 19, 2015 at 1:09 AM, Joe Watkins pthreads@pthreads.org
wrote:Morning internals,
The expectations RFC is now in voting phase:
I totally miss the Expectation RFC announcement. Where the RFC was
actually proposed for discussions.I have been following up the DbC thread, seeing some mentions but
that's it. The RFC itself popped up 3 days ago.It's from 2013
Yes, but....
and it was discussed actively during last week.
Still, no announce for a discussion about this specific RFC. And
really, the content of the RFC is almost empty, pointing to the ML
archive is really not the right way :)
So, back to more useful feedback.
I like the concept and idea but still not sure about the custom
exception vs AssertException.
My gut feeling tells me that it could be better to solve that prior
this vote, which actually asks to choose something we did not define
yet. It could be in the same RFC (and making it more complete while
being at it).
--
Pierre
@pierrejoye | http://www.libgd.org
Still, no announce for a discussion about this specific RFC. And
really, the content of the RFC is almost empty, pointing to the ML
archive is really not the right way :)
There was an RFC announce thread 3 days ago. I agree 3 days is a short
period of time, but the announce thread existed. Maybe it was a reply
to DbC with a changed subject and your mail client didn't show it as
new? I don't know, there was definitely a thread though.
I like the concept and idea but still not sure about the custom
exception vs AssertException.
Looking at the implementation, it seems that the custom exception
still has to descend from AssertException
https://github.com/php/php-src/pull/1088/files#diff-232f2dffbb06c0b6004724d8a498e7e7R248
That seems like a good restriction to me. You can still catch
everything with AssertException but you can make it more specific if
you want.
Still, no announce for a discussion about this specific RFC. And
really, the content of the RFC is almost empty, pointing to the ML
archive is really not the right way :)There was an RFC announce thread 3 days ago. I agree 3 days is a short
period of time, but the announce thread existed. Maybe it was a reply
to DbC with a changed subject and your mail client didn't show it as
new? I don't know, there was definitely a thread though.
I mentioned that thread in my comment. It is still way behind what
should be done when creating a new RFC, let alone pushing it to the
vote phase.
I like the concept and idea but still not sure about the custom
exception vs AssertException.Looking at the implementation, it seems that the custom exception
still has to descend from AssertExceptionhttps://github.com/php/php-src/pull/1088/files#diff-232f2dffbb06c0b6004724d8a498e7e7R248
That seems like a good restriction to me. You can still catch
everything with AssertException but you can make it more specific if
you want.
I did not comment on what should be done, while I do consider this
open question as a blocker to actually take a good decision for this
RFC. I do think it should be discussed, answered and voted either at
the same time or before this RFC.
--
Pierre
@pierrejoye | http://www.libgd.org
There isn't legitimate technical justification for or against using custom
exceptions.
Since it's entirely based on preference, and the kind of utilitarian
argument you can make for their use,
it's acceptable that this is resolved as part of the vote.
It's not a huge deal.
Cheers
Joe
Still, no announce for a discussion about this specific RFC. And
really, the content of the RFC is almost empty, pointing to the ML
archive is really not the right way :)There was an RFC announce thread 3 days ago. I agree 3 days is a short
period of time, but the announce thread existed. Maybe it was a reply
to DbC with a changed subject and your mail client didn't show it as
new? I don't know, there was definitely a thread though.I mentioned that thread in my comment. It is still way behind what
should be done when creating a new RFC, let alone pushing it to the
vote phase.I like the concept and idea but still not sure about the custom
exception vs AssertException.Looking at the implementation, it seems that the custom exception
still has to descend from AssertExceptionhttps://github.com/php/php-src/pull/1088/files#diff-232f2dffbb06c0b6004724d8a498e7e7R248
That seems like a good restriction to me. You can still catch
everything with AssertException but you can make it more specific if
you want.I did not comment on what should be done, while I do consider this
open question as a blocker to actually take a good decision for this
RFC. I do think it should be discussed, answered and voted either at
the same time or before this RFC.--
Pierre@pierrejoye | http://www.libgd.org
Morning internals,
The expectations RFC is now in voting phase:
I totally miss the Expectation RFC announcement. Where the RFC was
actually proposed for discussions.I have been following up the DbC thread, seeing some mentions but
that's it. The RFC itself popped up 3 days ago.Also the RFC itself only point to various discussions, there is no
summary, details, docs, examples, etc in the RFC.I am sorry but as much I like (for what I think it does) as I like the
concept, this RFC does not have, by far, the quality I would expect
for a RFC being voted on.
Coming back to this point.
I very much like what is presented here. However I think it is pre
mature to vote on as there was (sorry) not explicit discussions about
it.
A couple of things are unclear. See the numerous questions in this thread.
I also do not like other things.
zend.assertions:
I understand we need to be able to disable them. Is production vs
development/debug mode specific to assertion? I do not think so, we
should have a more general setting for that so other areas can be used
for it.
INI_SYSTEM
may also reduce the usage of this feature to local
development or dedicated hosts. Any shared hoster (those not allowing
to change php.ini) won't be able to test in similar tests environment.
It is not critical but it is something you may reconsider.
assert.exceptions:
Let solve the exception usages in the engine first and see how to deal
with them more globally, including naming, NS or where and how they
can be used. This is in my eyes a pre requise to this RFC.
INI_ALL
is used here. That means that just like error_reporting (which
is actually very painful), calling some random codes may makes my code
(caller) raised exceptions when I do not want to, or the other way
round? I am not too keen on that idea.
Cheers,
Pierre
@pierrejoye | http://www.libgd.org
Hey:
Morning internals,
The expectations RFC is now in voting phase:
sorry, the thread is too long to read.. I am not sure whether there
was some similar opinion before..
I voted without custom exception, that is because.
if all assertion exception is AssertException, then we can simply
optimized them away while zend.assert is disabled..
like:
try {
foo();
bar();
assert()
;
} catch (AssertException $e) {
//these statements can be optimized away.
}
but with custom exception..
try {
sqllitefunc(); // no threw
sqllitefunc1(); //no threw
assert("", new SqlLiteException());
} catch (SqlliteException $e) {
//we are not sure maybe sqllitefunc can throw SqliteException.
// thus we can not optimized these statements ayway
}
thanks
Cheers
Joe
--
Xinchen Hui
@Laruence
http://www.laruence.com/
The custom exception must derive from AssertionException, so the same
optimization is possible.
Cheers
Joe
Hey:
On Thu, Feb 19, 2015 at 5:09 PM, Joe Watkins pthreads@pthreads.org
wrote:Morning internals,
The expectations RFC is now in voting phase:
sorry, the thread is too long to read.. I am not sure whether there
was some similar opinion before..I voted without custom exception, that is because.
if all assertion exception is AssertException, then we can simply
optimized them away while zend.assert is disabled..like:
try {
foo();
bar();
assert()
;
} catch (AssertException $e) {
//these statements can be optimized away.
}but with custom exception..
try { sqllitefunc(); // no threw sqllitefunc1(); //no threw assert("", new SqlLiteException()); } catch (SqlliteException $e) { //we are not sure maybe sqllitefunc can throw SqliteException. // thus we can not optimized these statements ayway }
thanks
Cheers
Joe--
Xinchen Hui
@Laruence
http://www.laruence.com/
Also, we don't optimize those away, it would not be sensible, because it's
not sensible to deploy those catch blocks in the first place.
Cheers
Joe
The custom exception must derive from AssertionException, so the same
optimization is possible.Cheers
JoeHey:
On Thu, Feb 19, 2015 at 5:09 PM, Joe Watkins pthreads@pthreads.org
wrote:Morning internals,
The expectations RFC is now in voting phase:
sorry, the thread is too long to read.. I am not sure whether there
was some similar opinion before..I voted without custom exception, that is because.
if all assertion exception is AssertException, then we can simply
optimized them away while zend.assert is disabled..like:
try {
foo();
bar();
assert()
;
} catch (AssertException $e) {
//these statements can be optimized away.
}but with custom exception..
try { sqllitefunc(); // no threw sqllitefunc1(); //no threw assert("", new SqlLiteException()); } catch (SqlliteException $e) { //we are not sure maybe sqllitefunc can throw SqliteException. // thus we can not optimized these statements ayway }
thanks
Cheers
Joe--
Xinchen Hui
@Laruence
http://www.laruence.com/
Am 20.02.2015 09:47 schrieb "Joe Watkins" pthreads@pthreads.org:
Also, we don't optimize those away, it would not be sensible, because it's
not sensible to deploy those catch blocks in the first place.
So, do they become FATAL with production settings? Ideally a parse error
(ideally, because then my ordinary syntax check run before deployment,
could catch them :) ???
best regards
Patrick
The expectations RFC is now in voting phase:
Sorry, I had an e-mail backlog while this was in discussion, so I'm
only getting around to this now. Two thoughts:
-
This is awesome, particularly the BC aspects. Nice work. :)
-
For zend.assertions, is it worth defining constants with more
meaningful names that can be used in place of the magic values?
They're pretty arbitrary as it stands.
My vote's not conditional on that — I'm +1 even in its current form —
but I wonder if we can make this a little easier for users.
Thanks,
Adam
Le 19/02/2015 10:09, Joe Watkins a écrit :
The expectations RFC is now in voting phase:
https://wiki.php.net/rfc/expectations#vote
Hi,
While talking about this RFC with other people of AFUP, we discussed
about assert()
... And mostly ended up against "it".
Still, note we probably discussed more about the idea of using assert()
itself than about the RFC and the proposition of improving the existing
assert()
construct -- which means we probably didn't really answer the
question that was asked here.
Basically, the idea of adding code (assertions) directly into the code
of our application in order to test for "things" doesn't feel right:
we'd rather use (unit-)tests for that, alongside our application's code
and not interleaved with it.
Considering this, we kind of felt it wasn't really necessary to work on
assertions and that enhancing them might encourage people to use them
more -- adding more non-production code in the middle of the
production-code.
Also, using .ini directives to enable or disable the execution of
portions of code comes with a risk: there is always a chance someone
will mis-configure a server and assertions will run in production
environment. Or maybe in some edge cases, an assertion could have some
side-effect that would impact the code (even if it should not), making
it work in development and not work in production?
I hope I summarized our thoughts right -- and sorry if we didn't really
answer the question that was asked.
Thanks for your work!
--
Pascal MARTIN, AFUP - French UG
http://php-internals.afup.org/
The expectations RFC is now in voting phase:
This announcement doesn't say when voting will close and the RFC
doesn't either. When do you expect voting to close?
Morning Internals,
As mentioned on the RFC, voting finished last night at midnight.
The vote passed with a majority (50%+) in favour of custom exceptions,
however ...
When the patch was originally written assert (expect) was a language
construct, and so the exception message wasn't constructed if the assertion
passed.
In the current patch, assert is still a function call, so to use custom
assertions would cost considerably because the custom exception is a
parameter (so, +1 object per assertion regardless of result).
Because of this, we are not going to merge with custom exceptions
enabled, they should not be crippling, another RFC will have to be written
to deal with custom exceptions if that's something we want moving forward.
Cheers
Joe