Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:106558 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 51841 invoked from network); 12 Aug 2019 15:55:23 -0000 Received: from unknown (HELO mail.nunninger.info) (87.106.55.207) by pb1.pair.com with SMTP; 12 Aug 2019 15:55:23 -0000 Received: from p5093df94.dip0.t-ipconnect.de ([80.147.223.148] helo=[192.168.178.25]) by mail.nunninger.info with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.69) (envelope-from ) id 1hxAII-0004ut-Cd; Mon, 12 Aug 2019 13:23:31 +0000 To: Nikita Popov , Nicolas Grekas Cc: PHP internals References: Message-ID: <6e1396e7-2839-2dc2-16a2-302e068acdf2@nunninger.info> Date: Mon, 12 Aug 2019 15:23:19 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit X-Spam-Score: 0.6 (/) X-Spam-Several-Recipients: Yes Subject: Re: [PHP-DEV] [RFC] Namespace-scoped declares, again From: thomas@nunninger.info (Thomas Nunninger) Hi, Am 12.08.19 um 10:26 schrieb Nikita Popov: > On Mon, Aug 12, 2019 at 10:17 AM Nicolas Grekas < > nicolas.grekas+php@gmail.com> wrote: > >> Le lun. 11 déc. 2017 à 14:44, Nikita Popov a >> écrit : >> >>> Some time ago I introduced the following proposal for namespace-scoped >>> declares: >>> >>> https://wiki.php.net/rfc/namespace_scoped_declares >>> >>> The idea is to allow specifying declare directives for a whole library or >>> project using: >>> >>> namespace_declare('Vendor\Lib', ['strict_types' => 1]); >>> >>> I've finally gotten around to implementing this proposal ( >>> https://github.com/php/php-src/pull/2972) and would like to move forward >>> with it. >>> >>> The reason why I'm picking it up again is some feedback I received for the >>> explicit call-time send-by-ref proposal. The main objection seems to be >>> that the feature has limited usefulness if it's optional rather than >>> required, because you still can't be sure that something is a by-value >>> pass, just because no & is present. At the same time, we can't make this >>> required anytime soon due to the large BC impact. >>> >>> Namespace-scoped declares are perfectly suited to resolve this problem. We >>> can introduce a require_explicit_send_by_ref declare directive to make the >>> call-site annotation required, and libraries/projects can easily opt-in to >>> it using namespace_declare(). There would be no BC impact, while at the >>> same time projects could benefit from the additional clarity and >>> performance improvements immediately. >>> >> >> I've read discussions about the notion of a "package" and the way we >> should define its boundaries. >> What about the following? >> >> Individual files could declare their package using this style: >> > >> That would be enough to group a set of files together and make them share >> eg some private classes, some optional PHP behaviors, etc. >> >> The right side "MyVendor\MyPackage" would also be a FQCN that PHP would >> autoload as a regular class. The corresponding class would then be the >> place where ppl would declare the engine behavior they want for their >> package (strict types, etc). To enforce this, the engine could require that >> the "MyPackage" class implements some interface/extend some base abstract >> class. >> >> Of course, one could hijack a package and declare an unrelated file as >> part of it, but I don't think that's an issue: the situation is the same as >> for namespaces, where one can hijack a third party vendor namespace. In >> practice, it proved not being an issue, and the original author's intent is >> clear: "this is my namespace/package, if you mess with it, fine, but you're >> on your own". >> >> Nicolas >> > > FTR I've created a draft-implementation for a package system here: > https://github.com/php/php-src/pull/4490 > > It uses a slightly different approach in that it keeps the package name a > string (that should usually match the Composer package name) and uses a > function to register the package. > > The main annoyance is that this requires declaring the package in every > file, something I would like to avoid. An alternative I played with is to > allow specifying the package at include time, which would allow the > autoloader to specify which package a file is part. However, while this is > more ergonomic for the user, I'm afraid that this will make static analysis > & IDE scenarios problematic, because they will not be able to easily know > what the package is in cases that fall outside convention. So in the end, > an explicit per-file package declaration may be the best we can do. I'm not sure if this was discussed/proposed before: Why not have a concept similar to autoloaders that resolves a given class name to some declare statements. That way you could implement a composer based resolver that takes a class name, (internally) resolves it to a package (based on the autoloader configuration in composer.json), and returns an array of the specified declare statements. Developers do not need to specify a package or any declare statements in PHP files at all, as PHP (or static analyzers) would be able to ask the class-name-to-declare-statements resolver which declare statements a PHP file defines. Alternatively, you could introduce the concept of a Package(Specification) class as proposed by Nicolas (but without the need to extend and implement it in each package). That way the resolver does not return the array of declare statements but an instance of the Package(Specification) class that was constructed by the composer-based resolver dynamically with the declare statements as defined in composer.json. Not sure: Perhaps you even do not need a new concept of a resolver but could extend the concept of autoloaders? Regards Thomas