Latest version as we zero in on what this is really about: https://bit.ly/php-0002 https://bit.ly/php-0002
Other threads:
- https://externals.io/message/110879 https://externals.io/message/110879
- https://externals.io/message/110881 https://externals.io/message/110881
Thanks for all the feedback so far! Definitely feels like progress.
Cheers,
Josh
Latest version as we zero in on what this is really about:
https://bit.ly/php-0002 https://bit.ly/php-0002Other threads:
- https://externals.io/message/110879 https://externals.io/message/110879
- https://externals.io/message/110881 https://externals.io/message/110881
Thanks for all the feedback so far! Definitely feels like progress.
Cheers,
Josh
Hi Josh. This is a big improvement, and I think focuses on the useful value-add a lot better. Basing it off of Countable rather than Stringable is, I think, a safer overall approach, especially as it then gets us toBool as effectively a side-effect.
There's 2 additional improvements I'd suggest:
-
The 2 places that you have lists of "this thing produces true/false" could likely stand to be turned into tables to make it clearer, especially when demonstrating that isEmpty() and __toBool() are effectively opposites of each other so we get a 2-for-1 deal.
-
Include some less-random examples of real "empty" objects.
Also, please be warned that the PHP wiki doesn't use Markdown. It uses some wonky proprietary ancient mess instead. Now that you have Wiki access you should probably start using the PHP Wiki instead of Github so that you don't have to convert a mess of nice formatting from Markdown to PHPWiki-down.
I like this idea and wish I had the skillz to help implement it. :-)
--Larry Garfield
Latest version as we zero in on what this is really about:
https://bit.ly/php-0002 https://bit.ly/php-0002
- The 2 places that you have lists of "this thing produces true/false" could likely stand to be turned into tables to make it clearer, especially when demonstrating that isEmpty() and __toBool() are effectively opposites of each other so we get a 2-for-1 deal.
I appreciate this idea - done.
- Include some less-random examples of real "empty" objects.
I’m having difficulty with this, to be honest. I think there are two reasons for this:
-
I avoid null to the point of going out of my way to make it not happen - including implementing “isEmpty” - simultaneously I’m having a hard time, which could mean it’s a solution looking for a problem (was thinking about a file cabinet with drawers that would accept folders).
-
I have a very specific use case where this would solve a problem for me. It mainly revolves around the ability in PHP to make an object in such a way that it “feels” like an array - and “feels” like a string - and can become an integer - but there’s no way to make the object feel like and be interacted with like a bool. I don’t want my use case to be the only reason a change like this is introduced to PHP - I want to make sure “it’s not just me” - you know??
Re the wiki: I can edit pages now, it doesn’t look like I can create them. There’s another thread I’ve been watching and I think I need more karma to make that a thing. I will continue working on this and if it generates enough pull then maybe I’ll be let in - I’ll also contribute where I can to start earning karma.
Updated: https://bit.ly/php-0002 https://bit.ly/php-0002
Cheers,
Josh
Re the wiki: I can edit pages now, it doesn’t look like I can create them. There’s another thread I’ve been watching and I think I need more karma to make that a thing. I will continue working on this and if it generates enough pull then maybe I’ll be let in - I’ll also contribute where I can to start earning karma.
You have RFC karma now.
--
Christoph M. Becker
Re the wiki: I can edit pages now, it doesn’t look like I can create them. There’s another thread I’ve been watching and I think I need more karma to make that a thing. I will continue working on this and if it generates enough pull then maybe I’ll be let in - I’ll also contribute where I can to start earning karma.
You have RFC karma now.
Christoph: Wow, okay. Thank you!
All: I’ve decided to go ahead and do one more round using GitHub (big changes - kind of a synthesis of directions so far based on feedback).
Then I’ll spend time transferring it to a draft (or discussion??) and making sure I understand the process more than I do at present.
Nikita:
Re falsiness: Switching back to being more about truthiness and falsiness. Thanks for the feedback.
Re nullsafe: I agree that nullsafe handles the issue of null being returned and it’s a welcomed workaround, but it doesn’t address the problem of null being returned instead of a false (empty) object of the desired type that can be acted upon - even if limited.
Brings up the new question again: Under what circumstances would PHP return null without a developer explicitly asking it to (somewhere in the call chain) or without PHP error?
Cheers,
Josh
Re the wiki: I can edit pages now, it doesn’t look like I can create them. There’s another thread I’ve been watching and I think I need more karma to make that a thing. I will continue working on this and if it generates enough pull then maybe I’ll be let in - I’ll also contribute where I can to start earning karma.
You have RFC karma now.
Christoph: Wow, okay. Thank you!
All: I’ve decided to go ahead and do one more round using GitHub (big changes - kind of a synthesis of directions so far based on feedback).
Then I’ll spend time transferring it to a draft (or discussion??) and making sure I understand the process more than I do at present.
Nikita:
Re falsiness: Switching back to being more about truthiness and falsiness. Thanks for the feedback.
Re nullsafe: I agree that nullsafe handles the issue of null being returned and it’s a welcomed workaround, but it doesn’t address the problem of null being returned instead of a false (empty) object of the desired type that can be acted upon - even if limited.
Brings up the new question again: Under what circumstances would PHP return null without a developer explicitly asking it to (somewhere in the call chain) or without PHP error?
Cheers,
Josh
ps. Link: https://bit.ly/php-0002 https://bit.ly/php-0002 - sorry
Latest version as we zero in on what this is really about:
https://bit.ly/php-0002 https://bit.ly/php-0002Other threads:
- https://externals.io/message/110879 <
https://externals.io/message/110879>- https://externals.io/message/110881 <
https://externals.io/message/110881>Thanks for all the feedback so far! Definitely feels like progress.
I have a really hard time understanding what is actually being proposed
here. You mention the introduction of the Emptiable interface, but not how
it influences empty() or (bool) casts. There's some examples in "Usage"
that are possibly intended to illustrate this -- I suspect that a "return
true" vs "return false" mixup has made them impossible to understand though.
Some thoughts on the general domain:
-
I don't like the idea of decoupling empty() and (bool). empty($x) is
currently the same as !$x (modulo notices), and changing that will make
PHP's already messy implicit type conversion matrix even messier. -
Coupling boolean casts to an "emptiness" concept seems somewhat dubious
to me. That works for container structures, but what about something like
new Bigint(0)? It would be quite odd to declare an integer "empty" to make
it evaluate to false. -
I'm generally not a fan of overloadable bool casts. We have exactly one
object with an overloaded bool cast in PHP, and that's SimpleXMLElement. As
far as I know, this has only caused issues. A big reason for that is that
using "if ($foo->bar)" is a common idiom for checking "if ($foo->bar !==
null)" -- one that works very reliably, with the exception of
SimpleXMLElement. -
I think if ($container->isEmpty()) is much clearer than if ($container)
-- why would we want people to use the latter instead?
Regards,
Nikita
Latest version as we zero in on what this is really about: https://bit.ly/php-0002 https://bit.ly/php-0002 <https://bit.ly/php-0002 https://bit.ly/php-0002>
I have a really hard time understanding what is actually being proposed here. You mention the introduction of the Emptiable interface, but not how it influences empty() or (bool) casts. There's some examples in "Usage" that are possibly intended to illustrate this -- I suspect that a "return true" vs "return false" mixup has made them impossible to understand though.
Some thoughts on the general domain:
- I don't like the idea of decoupling empty() and (bool). empty($x) is currently the same as !$x (modulo notices), and changing that will make PHP's already messy implicit type conversion matrix even messier.
Thanks for the feedback! Not all incorporated in the latest, due to timing: https://bit.ly/php-0002
Initially this started as a desire to be able to declare an object casting to bool (__toBool or something). After a couple rounds the relationship between empty() and bool surfaced. The question I’m volleying there is are they different concepts (a non-answer compared to a lie) and does it matter given the established norm. (Sounds like you’re in the established norm camp - I tend to lean that way as well.)
- Coupling boolean casts to an "emptiness" concept seems somewhat dubious to me. That works for container structures, but what about something like new Bigint(0)? It would be quite odd to declare an integer "empty" to make it evaluate to false.
This seems counter to the first bullet point. They already are coupled. The result of empty() tends to be the opposite of casting bool - unless there’s an example I’m unaware of.
- I'm generally not a fan of overloadable bool casts. We have exactly one object with an overloaded bool cast in PHP, and that's SimpleXMLElement. As far as I know, this has only caused issues. A big reason for that is that using "if ($foo->bar)" is a common idiom for checking "if ($foo->bar !== null)" -- one that works very reliably, with the exception of SimpleXMLElement.
I wasn’t aware of this. Thank you! I will take a look and see what problems people are running into and how it’s implemented - at least from a developer perspective.
- I think if ($container->isEmpty()) is much clearer than if ($container) -- why would we want people to use the latter instead?
Fair question. This made me raise the question in the draft and I’ll raise it here…under what circumstances would PHP return null from new.
$instance = new MyClass();
If ($instance->isEmpty()) {}
$inner = $instance->innerObject();
If ($innnerObject->isEmpty()) {}
If I implement the innerObject() method to return null - and it does - then that call fails, because it’s null, which brings up your earlier point, I think.
If ($innerObject) {
// not null
If ($innerObject->isEmpty()) {
// two-step process with null-check
}
}
// with the language feature
If ($innerObject) {
// I know it can give and receive messages, and is not empty
} else {
// I know it can give and receive messages, but is empty
}
I remember hearing what sounds like hyperbole but it said something like 40% of code written is guarding against null. I can totally see that being real so didn’t look much further into it. If we can guarantee that an object is that type of object - just happens to be empty, maybe we reduce or remove the need null-checks??
Cheers,
Josh
Latest version as we zero in on what this is really about:
https://bit.ly/php-0002 https://bit.ly/php-0002I have a really hard time understanding what is actually being proposed
here. You mention the introduction of the Emptiable interface, but not how
it influences empty() or (bool) casts. There's some examples in "Usage"
that are possibly intended to illustrate this -- I suspect that a "return
true" vs "return false" mixup has made them impossible to understand though.Some thoughts on the general domain:
- I don't like the idea of decoupling empty() and (bool). empty($x) is
currently the same as !$x (modulo notices), and changing that will make
PHP's already messy implicit type conversion matrix even messier.Thanks for the feedback! Not all incorporated in the latest, due to
timing: https://bit.ly/php-0002Initially this started as a desire to be able to declare an object casting
to bool (__toBool or something). After a couple rounds the relationship
between empty() and bool surfaced. The question I’m volleying there is are
they different concepts (a non-answer compared to a lie) and does it matter
given the established norm. (Sounds like you’re in the established norm
camp - I tend to lean that way as well.)
- Coupling boolean casts to an "emptiness" concept seems somewhat dubious
to me. That works for container structures, but what about something like
new Bigint(0)? It would be quite odd to declare an integer "empty" to make
it evaluate to false.This seems counter to the first bullet point. They already are coupled.
The result of empty() tends to be the opposite of casting bool - unless
there’s an example I’m unaware of.
Yes, they are coupled. The problem here is more that empty() is a misnomer,
because it does not check emptiness, it checks falsyness. The big example
is that empty("0") returns true, even though "0" is very clearly not an
empty string.
- I'm generally not a fan of overloadable bool casts. We have exactly one
object with an overloaded bool cast in PHP, and that's SimpleXMLElement. As
far as I know, this has only caused issues. A big reason for that is that
using "if ($foo->bar)" is a common idiom for checking "if ($foo->bar !==
null)" -- one that works very reliably, with the exception of
SimpleXMLElement.I wasn’t aware of this. Thank you! I will take a look and see what
problems people are running into and how it’s implemented - at least from a
developer perspective.
- I think if ($container->isEmpty()) is much clearer than if ($container)
-- why would we want people to use the latter instead?Fair question. This made me raise the question in the draft and I’ll raise
it here…under what circumstances would PHP return null from new.$instance = new MyClass();
If ($instance->isEmpty()) {}
$inner = $instance->innerObject();
If ($innnerObject->isEmpty()) {}
If I implement the innerObject() method to return null - and it does -
then that call fails, because it’s null, which brings up your earlier
point, I think.If ($innerObject) {
// not nullIf ($innerObject->isEmpty()) {
// two-step process with null-check}
}// with the language feature
If ($innerObject) {
// I know it can give and receive messages, and is not empty} else {
// I know it can give and receive messages, but is empty}
The nullsafe operator proposal will allow you to write this as
if ($innerObject?->isEmpty()) {
}
That is both concise, and very explicit. Just If ($innerObject) is not --
it could be intended as just a null check, or as a null or empty check, or
only an empty check, under your proposal.
Nikita