Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:110976 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 73425 invoked from network); 13 Jul 2020 17:58:36 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 13 Jul 2020 17:58:36 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 3840818054C for ; Mon, 13 Jul 2020 09:50:50 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-lf1-f50.google.com (mail-lf1-f50.google.com [209.85.167.50]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 13 Jul 2020 09:50:49 -0700 (PDT) Received: by mail-lf1-f50.google.com with SMTP id y13so9467971lfe.9 for ; Mon, 13 Jul 2020 09:50:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=u1sccwbpnzTtRZLnERc6fJDV4yDuSJyysE0l/O0sZ2Y=; b=P7E33ESmf3vHwKXgeyeC7GOLf02YO8ynbV+Fs92wv8q4kYuKp3uf6ogv6YQt7Tmlu0 zMhWEy2G1ln+Z72ez4UuUiedSLJcyF/SFYWoG03nFdOkWkmyEpyId7xWbrpsza+R+TvB LuwJKbMllDzBWTS4VydxLyyJzEXa0Fw77qT+LUYZwkHJOGXGOLbfwLFFRPX/ZisU/iYQ nqtxY7SJYUprnuHOxgmmxz2UKpaG2rqmxLhIa27LZIlnqhm1D5x8gnANfc2TrSpBCfqB nqOCsQo6f1KoLZ1efhki3kvLLm5PgP85xJw5eu99QizzhNX9YrD8T/KSwjW6HSHA29re iW9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=u1sccwbpnzTtRZLnERc6fJDV4yDuSJyysE0l/O0sZ2Y=; b=q0c6zI6ssHruu20bJqdkVTw/9TUCW00xnlg2+dUBYcFvcurUaWzGUabjgwROCJa4oE FiAwF63FHbqYkruXEitA6wXHMWv8j77ePsblE7qhzbsjh+eRLk0gwus3Km1BIRvawCUq gakBfggapiIZekE7IlaCCuLzxwWNG8Xa3YhwxsebhXjBtQyPA0GShq2iSOCy2Mwq+DaO lRtN0xq/qnCBqO1iqUkGhJO880V6ooOmygfIw8TRSxFlCwtSSa9qrsDvD7M/DDVXsaMO zh+CQTJ5q83fhuQRe/8ljqvKUF5xI22UacxnpdsfToG+dcTME9N6tXfpBxvFP3HapT3D IWaw== X-Gm-Message-State: AOAM532Owu68BOB0VdaGJ0pIG1jTyFKf3zkFAWmzMjvHPYxhaVvjao2T OfaIMlf5hDXTVdk8hX0WQTwdJ7FJ0KWV4a6EAUqz6FKaXJY= X-Google-Smtp-Source: ABdhPJw/wv6NhTsvn0g+hEJho3ubgFJzSrANSwQkKJgGX2Q3BFmS5rEE7WjNOey5Ko/gKdB9wg42s/gR/JHapbkoC84= X-Received: by 2002:ac2:4a83:: with SMTP id l3mr67423lfp.92.1594659045940; Mon, 13 Jul 2020 09:50:45 -0700 (PDT) MIME-Version: 1.0 References: <7238EFA9-8BE4-48E2-B6C6-6C3E14CFA208@joshbruce.dev> <820338EF-AD7C-4AD2-9305-8F814FA163D7@joshbruce.dev> In-Reply-To: <820338EF-AD7C-4AD2-9305-8F814FA163D7@joshbruce.dev> Date: Mon, 13 Jul 2020 18:50:30 +0200 Message-ID: To: Josh Bruce Cc: php internals Content-Type: multipart/alternative; boundary="000000000000f8a37205aa557ddc" Subject: Re: [PHP-DEV] [CONCEPT][DISCUSSION] Allow objects to declare emptiness and by extension truthiness From: nikita.ppv@gmail.com (Nikita Popov) --000000000000f8a37205aa557ddc Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Mon, Jul 13, 2020 at 5:33 PM Josh Bruce wrote: > > >> Latest version as we zero in on what this is really about: >> 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 ho= w > 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 thou= gh. > > 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 castin= g > to bool (__toBool or something). After a couple rounds the relationship > between empty() and bool surfaced. The question I=E2=80=99m volleying the= re is are > they different concepts (a non-answer compared to a lie) and does it matt= er > given the established norm. (Sounds like you=E2=80=99re in the establishe= d norm > camp - I tend to lean that way as well.) > > 2. Coupling boolean casts to an "emptiness" concept seems somewhat dubiou= s > 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 mak= e > 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=E2=80=99s an example I=E2=80=99m 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 on= e > 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 !=3D= =3D > null)" -- one that works very reliably, with the exception of > SimpleXMLElement. > > > I wasn=E2=80=99t aware of this. Thank you! I will take a look and see wha= t > problems people are running into and how it=E2=80=99s implemented - at le= ast 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=E2=80= =99ll raise > it here=E2=80=A6under what circumstances would PHP return null from new. > > $instance =3D new MyClass(); > > If ($instance->isEmpty()) {} > > $inner =3D $instance->innerObject(); > > If ($innnerObject->isEmpty()) {} > > If I implement the innerObject() method to return null - and it does - > then that call fails, because it=E2=80=99s null, which brings up your ear= lier > 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 --000000000000f8a37205aa557ddc--