On Mon, Jul 13, 2020 at 5:33 PM Josh Bruce <j...@joshbruce.dev> wrote:

>
>
>> Latest version as we zero in on what this is really about:
>> 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:
>
> 1. 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.)
>
> 2. 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.

>
> 3. 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.
>
> 4. 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
>
> }
>

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

Reply via email to