Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:110181 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 5769 invoked from network); 16 May 2020 15:18:52 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 16 May 2020 15:18:52 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 308801804F2 for ; Sat, 16 May 2020 06:56:34 -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=-1.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RDNS_NONE,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS701 96.241.0.0/16 X-Spam-Virus: No X-Envelope-From: Received: from nebula.zort.net (unknown [96.241.205.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 16 May 2020 06:56:33 -0700 (PDT) Received: from [10.0.1.2] (pulsar.zort.net [96.241.205.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by nebula.zort.net (Postfix) with ESMTPSA id B637E2000955B; Sat, 16 May 2020 09:56:32 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.11.0 nebula.zort.net B637E2000955B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zort.net; s=zort; t=1589637392; bh=8gVr4BkxrOA4PXtqIAQ0corOG6g9bc7QWVy6ouSOeqE=; h=Subject:From:In-Reply-To:Date:Cc:References:To:From; b=emiy3Qv6vDaU3wj9bB3QneNRh8/viQCBwzFm0RIqsvMirrodcI+yH5iEtorWq9l1m M5VOYC3smiD9auW82h6Q44Qn+78vHXfMLbgqyHaHhkjdQff1hCPJXZVF0/oNAuXNrM r1AydPODWCjWE8EGGQfDjGnnkNQvcj9EiwYJ3F4Y= Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.80.23.2.2\)) In-Reply-To: Date: Sat, 16 May 2020 09:56:32 -0400 Cc: internals@lists.php.net Content-Transfer-Encoding: quoted-printable Message-ID: References: To: Pavel Patapau X-Mailer: Apple Mail (2.3608.80.23.2.2) Subject: Re: [PHP-DEV] [RFC] Guard statement From: jbafford@zort.net (John Bafford) Pavel, On May 16, 2020, at 05:13, Pavel Patapau wrote: >=20 > Hello everyone, >=20 > I want to propose new syntax addition - guard statement, that executes = code only if expression equals false and must contain control-flow = changing code, and written a respective RFC: >=20 > https://wiki.php.net/rfc/guard_statement > >=20 > Implementation in progress. >=20 > I started work before this proposal = https://externals.io/message/110107 and respected some moments in the = RFC. >=20 >=20 > Thanks for consideration, > Pavel Regarding this part of the proposal: > Body of statement must contain code that changes control flow: return, = throw, goto. Also, in a loop context, you can use break or continue. >=20 > If compiler doesn't find any of those statements, it will search = selection type statements(if with else|try/catch/finally|switch) and = ensures that every element of these statements contains return, throw, = goto. I feel that from an implementation standpoint, this could be fairly = complex, especially since code such as: guard (COND) else exit; guard (COND) else call_some_function_that_calls_exit(); ought to compile without warnings. (Exit was explicitly included in my = original proposal on the mailing list.) Some languages allow this by = marking functions with a noreturn attribute (C, Swift < 3). Swift >=3D 3 = solves this problem by having a "Never" return type, which is validated = by Swift's type checker, requiring all code paths to also call another = function returning Never. (As an implementation detail, Never is an enum = with no cases.) Otherwise, you would have to write guard (COND) else { exit; return; } to satisfy the parser, which is silly. I would suggest an alternative that is conceptually simpler and allows = for this use case. We can observe that if we slightly loosen the restriction that the = _compiler_ must be able to do a full call path analysis, a guard = statement can also be thought of as: guard (COND) else { STATEMENTS; =09 throw new \GuardFailureError; } That is, the else clause ends with a compiler-generated fatal error. = This means the compiler itself doesn't _have_ to do a full analysis of = every call path in the STATEMENTS to ensure proper exit; the runtime can = trap as well. This allows us to be a bit more flexible: if the compiler can prove one = way or the other, it can either fail compilation, or else omit = generating the opcodes for throwing the GuardFailureError. But code that = the compiler _can't_ prove (such as the previously mentioned = code-that-calls-exit) should still be allowed. If we later add language support for a noreturn attribute, or some other = mechanism to account for that, then we are in a position to allow for = that complexity in the parser and remove the runtime handling. It would = obviously be preferable if the compiler can catch errors in all cases, = but when it can't (and php's dynamicity makes this a hard problem), I = think it's acceptable that the runtime can serve as a fallback. -John