Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:113943 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 16148 invoked from network); 4 Apr 2021 02:09:17 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 4 Apr 2021 02:09:17 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 3FDF0180003 for ; Sat, 3 Apr 2021 19:07:41 -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-ua1-f53.google.com (mail-ua1-f53.google.com [209.85.222.53]) (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 ; Sat, 3 Apr 2021 19:07:40 -0700 (PDT) Received: by mail-ua1-f53.google.com with SMTP id h34so2568088uah.5 for ; Sat, 03 Apr 2021 19:07:40 -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=HYTRNd77tpoaT2j7KgrJlRxSo77GeVit0vF/ZPYN3zE=; b=YPdZZWEflEPo3SdOW/xfDYvnQYUKpN2pcv9eaOJctWWNESgluvWOpBt3nOTqAt7ZTh JXD5hIbdtThXfLcqidvWrzoSVwGjI05WR5W/QpUHRjf5uArEO7l6wLx4qjBJK+YFwspw u20N1WJ8ysV0VNQM5fBaaoUflxCFXciBAXagU6ulTDVtaTydGGjou2Tur0HzgzObUx0+ lJJlo0LkB5Mt6c2qQhwaYkpL33ZsRy5qDwMtEcx7FxFFtcYXgQNvUoO2zNq5JEeQUKX6 418y8CX5C1da400hjf+cNajYN/FeYvX1opFjDlvLh1T4dmxeoC0rZFzkSFpHGiexyo4Q 0x3g== 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=HYTRNd77tpoaT2j7KgrJlRxSo77GeVit0vF/ZPYN3zE=; b=bDURsdvGb0GthyNodKOhqPFqJmNY7q0J474iephxjRdTKNwfs0m87Ci4pBDYjH3i/o Qni+ToZ/0zDN69uPVFpDhIr2r1JlryCd2ZaY4koZJT2aGG/P7ZrwR9ptotErIE6CQiI7 e6BFtZIfPUPKDrUifWSbW7IEXrgpKeEuHv/6Yy8MJgIYoV4b2C3HJ6mlYW8vfToskCXt QPrv5UT0fXpY5cEgXyWynFII91YfFvJbnkWAAt9t2k6oUvkmarbrz9pWCyZNtKDfaFJk B7UtAcGfCAc48o8SbnGqCG624GPTHYTrnZamjchdSUA47/sK7IgysCqmOTrErp0zbQ1U g8BA== X-Gm-Message-State: AOAM533d4cjtjgchni3Rg2tJJvTw9Y4gsZbaxdqquw8USdtCLhwS+T6N z2eI0gsc6/2dx8w18N0dDOj0Yh/tScBZBls8Qp0= X-Google-Smtp-Source: ABdhPJwgh3yTNFk6ti7HTtYhQgJvEFhwlKnv1DyfuuKFboyQj50s5WuEDauV6Cmk5fOJCG/SjYKO4/7F+bRyfibtXnE= X-Received: by 2002:ab0:32cf:: with SMTP id f15mr10857157uao.68.1617502058367; Sat, 03 Apr 2021 19:07:38 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Sat, 3 Apr 2021 22:07:27 -0400 Message-ID: To: Benjamin Eberlei Cc: Aaron Piotrowski , Internals Content-Type: multipart/alternative; boundary="0000000000009cd02405bf1c0ba8" Subject: Re: [PHP-DEV] [VOTE] noreturn type From: matthewmatthew@gmail.com (Matthew Brown) --0000000000009cd02405bf1c0ba8 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sat, 3 Apr 2021 at 12:30, Benjamin Eberlei wrote: > > But adding a new keyword "noreturn" would not be necessary, it could just > be an Attribute as i said in my first e-mail explaining my no-vote: > > #[NoReturn] // sets a function flag modifying the void behavior > public function foo(): nothing { > return; // throws if it reaches this point > } > > This would be closer to what Psalm and PHP-Stan use at the moment if we > replace nothing with void. > > The problem is that "void" is already not perfect, since the callside > doesn't care about "return null" with no return type vs "return" + void > return type. > > If we had "nothing" and "null" instead of "void", and we'd say like PHP > works, "return;" actually means "return null;", then: > > function foo(): nothing { > return; // Error: cannot return null from a function that returns > nothing. > } > function bar(): null { > return; > // or return null; > } > > This would more consistently tie into union types where |null is allowed, > however on its own it is not: "foo() : null =3D> error". > > As Levi said, this noreturn/never just perpetuates/amplifies the existing > void mistake and feels off, given that other recent changes to PHP have > been more bold, towards removing inconsistencies. > > Clearly comparisons of "noreturn"/"never" to "void" are a bit of a minefield, because a number of contributors feel that void was a mistake, that its implementation doesn't feel PHP-like. While I disagree that our proposal is intrinsically connected with the void one =E2=80=93 noreturn/never could work equally well with a "null" return = =E2=80=94 our proposal does perpetuate one idea behind "void": that PHP can benefit from types found in other languages and type systems, and especially types found in Hack. It seems like some of the debate is over whether "noreturn"/"never" is a behaviour or a type. If it were purely a behaviour, with no meaning as a type, an Attribute would be a much more appropriate location. It's not just a behaviour, though =E2=80=94 it is a type that follows varia= nce rules, and it's a type that PHP can check. If "void" returns are too much of a distraction, think instead of "object" return type declarations: When executing the function function returnsObject($o) : object { if (rand(0, 1)) { return $o; } } Here PHP's engine checks two separate behaviours 1. when the function explicitly returns, does it return an object? 2. does the function ever finish without returning or throwing or exiting? Only the first actually involves a strict type check. The second is a generic behaviour check, triggered by the existence of a return type. This is essentially the same check that we want to trigger with "noreturn"/"never". In fact, as someone recently pointed out, running the following code *today* produces similar errors to the ones we propose: function php7Redirect() : noreturn { if (rand(0, 1)) { return "bad"; // Fatal error: Uncaught TypeError } header("Location: https://php.net"); exit; // OK } Our RFC makes this code explicitly legal, and adds covariance. Indeed our implementation is small because it correctly treats "noreturn"/"never" as a type, allowing us to use the existing return type handling. --0000000000009cd02405bf1c0ba8--