Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112184 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 70455 invoked from network); 4 Nov 2020 20:57:29 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 4 Nov 2020 20:57:29 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id EDA0C180502 for ; Wed, 4 Nov 2020 12:18:11 -0800 (PST) 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-il1-f174.google.com (mail-il1-f174.google.com [209.85.166.174]) (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 ; Wed, 4 Nov 2020 12:18:11 -0800 (PST) Received: by mail-il1-f174.google.com with SMTP id y17so20489910ilg.4 for ; Wed, 04 Nov 2020 12:18:11 -0800 (PST) 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=lFDznNEwzpmchEYnYsRTmKI7f76a+t+nsJvrLqIH0ss=; b=cyA9BlVRsZHGPevz1hyAQKxxd6Ao9sgyO9wKkai1tWE3svbHxJBIn/9+/aO4bYKW7S ziv1LdreutxbtUMxAdgH9Xu4W44O3SJylk4qfdjdpT0jk404Bp48D9EgIJVghbwHD/Mu NsUaPsP/ru3ciX5iBnCNQUdFPgKO5oEuifoEG+ZmPmAhHxubI4U+ioogQBEOJuerVOA6 q7YgMJ73Y8+WgiJZHcnfrWb3tSsCMD9BCKt349HucQn+zL4CzYjzI3XWs98Bw4vyzhK6 LXjLXeYdE1/pswLJ3+FAzHkuClKZpNn5QWajaARGUWGNwkZp3s6uuknl73nxnynJX0b7 qZ6w== 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=lFDznNEwzpmchEYnYsRTmKI7f76a+t+nsJvrLqIH0ss=; b=gHc+hroWEE/p0nXPhWzji6fUKICFKAq7QlH39C81RUli8ZV7EB0S0LmtkFWmTTeYfE tnw2QdClJ0fxmQAWc4bQdozxY+ykhcauUnaFeiu/GHewkaP5NcmRt13Cwmyn1IYB9ypw RKtqpT8daqdJO982mI2espTQL+Ll2D8vltGzVPwAWfSMv6FFxsXLX1fFt9DBqGaP4cmz HSKZEQFTyOu6m5umndxl6x/2r9K63x1jSVisRH9Y/vK8oAYA7d/YVwEl1xnbq/Xg9WJt v8BPkCqa6GIF4lSOii5i3y+SRgEj+6IN4t5Cjb9UOs3sVfZUzCMdRXkdvPSU3zc586CW josw== X-Gm-Message-State: AOAM530ej9Aa2GXhIYN/LL2MRe24FW6yh61jmzysgF5etjyXbvRhOBAP OKZBdXsbeKAL+qGTJdGXPf4j6fRs5DEmeu5sB1c= X-Google-Smtp-Source: ABdhPJwJHuXokBJbC43GoQlF084wmlfNdtB/QIsPRNx24f4kUzzSIxdqbtsOPfovJ82rj/8mYv3g/ED3xdpwbigpulQ= X-Received: by 2002:a92:a808:: with SMTP id o8mr17977840ilh.35.1604521090016; Wed, 04 Nov 2020 12:18:10 -0800 (PST) MIME-Version: 1.0 References: <3BFB4833-2419-420B-9A34-F2DB36BF6FD3@cschneid.com> In-Reply-To: Date: Wed, 4 Nov 2020 21:17:58 +0100 Message-ID: To: Eugene Sidelnyk Cc: Christian Schneider , PHP Internals List Content-Type: multipart/alternative; boundary="0000000000009aed0505b34dad2b" Subject: Re: [PHP-DEV] Nullsafe From: ocramius@gmail.com (Marco Pivetta) --0000000000009aed0505b34dad2b Content-Type: text/plain; charset="UTF-8" Hey, On Wed, Nov 4, 2020, 20:39 Eugene Sidelnyk wrote: > Yeah... Creating null was a huge mistake. > Now it is probably too late to fix that (maybe some new language can > introduce that). > > Y'all confusing Java's `null` (billion dollar mistake) with PHP's `null`. * In Java, `null|object` passes the `object` property and parameter type declaration, but crashes on `.` (`->` operator in PHP). That means that the type system is fundamentally flawed. * In PHP, `null|object` does not pass the `object` property and parameter type declaration, and crashes on `->` The PHP `T|null` type is almost equivalent to `data Maybe T = Just T | Nothing` from typed functional languages, and does not present the same "billion dollar mistake" flaws of Java. It is also an accurate and sufficient representation of "absence of value". That's why I linked the `toString()` vs `(string)` example in https://github.com/ShittySoft/symfony-live-berlin-2018-doctrine-tutorial/pull/3#issuecomment-460441229 Also, this was previously discussed in a similar way in https://externals.io/message/108369#108386 But what do you think about introducing special class `NullObject`? > You can really only apply the null object pattern (you can use the one from https://github.com/Ocramius/ProxyManager/blob/2.9.1/docs/null-object.md, which is relatively type-safe) when interactions with such an object leading to no effect are valid. In the example I wrote above: Let's assume following repository signature: ```php interface Accounts { /** @throws AccountNotFoundException */ public function get(AccountHolder $id): Account; } ``` In following usage: ```php $accounts->get($receiver) ->addFunds( $accounts->get($sender) ->detractFunds($amount) ); ``` Assuming `->` were capable of operating with `object|null` (OP proposal), if (by accident) somebody decided to change this signature: ```diff interface Accounts { - /** @throws AccountNotFoundException */ - public function get(AccountHolder $id): Account; + public function get(AccountHolder $id): ?Account; } ``` In this scenario, what can happen is that money disappears, as I've written above: > In the above scenario, if the first `$accounts->get()` call returns `null` for any reason, you may actually destroy money (funds detracted, but never added to another account). The same would happen if a `NullObject` were used: ```diff interface Accounts { - /** @throws AccountNotFoundException */ - public function get(AccountHolder $id): Account; + public function get(AccountHolder $id): NullObject|Account; } ``` Same scenario (slight variation): > In the above scenario, if the first `$accounts->get()` call returns ` NullObject ` for any reason, you may actually destroy money (funds detracted, but never added to another account). I would say that embracing nullability **in a type-safe manner** (please use https://psalm.dev/ or https://phpstan.org/) leads to proper usage of `null`, where it correctly indicates cases where no value has been produced/found/calculated/etc. Null pointer exceptions are trivially avoided by using any of these relatively stable and well adopted static analysis tools, and we don't really need to fight windmills at all. --0000000000009aed0505b34dad2b--