Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
I would like to make a wild proposal. ## Proposal Similar to spl_autoload_register(), we would provide a function that allows to register a callback to provide the declares / edition / compatibility information for a given file, before this file is loaded. To address performance concerns: - The result of the callback is cached per file, and per "application cache key". (*) - The callback has the option to additionally provide compatibility information for an entire directory, or a path pattern. Callback signature: - The primary parameter is the absolute path of the file, after symlinks are resolved. - Additional parameters could provide the version of the path that was passed to include / require. - An additional parameter could provide the class name, if we are currently doing autoload lookup (ouch, this could be complicated). - An additional parameter could contain the namespace. This would require that the parsing already begins, before the compatibility information is available. - An additional parameter could contain class names and function names declared in the file. This would imply that the file is already parsed before the compatibility information is available. (*) Caching mechanism: - Different PHP "applications" can have different cache keys, so that they do not poison each other. This could be provided in the initial function call along with the callback. - If no cache key is provided, the starting script path is used (e.g. /path/to/index.php) - There needs to be a function to clear this cache for the current application. - The opcache could contain different versions of a file for different compatibility levels. Combination with other proposals: There could still be functions to set compatibility information for an entire directory or namespace preemptively. There could also be ways to disable this special file-by-file callback for specific directories or namespaces. ## Motivation We saw proposals where the "edition" or "declares" would be on file level, on namespace level, on directory level, or on package level. The basic idea (mostly) was that the author provides compatibility information which is then picked up by PHP. The author of a package should be responsible for this, and it should be protected from side effects from other packages. Any file or package should have one definitive compatibility info, which should not be changed from outside. The proposal turns this on its head. It is now the responsibility of the package manager (e.g. Composer) or the framework to organize different compatibility levels in the application. Once some conventions have been established by the community (e.g. Composer), the IDE can extract information from e.g. composer.json to apply the appropriate checks on each file. Benefits: - Fine-grained control where needed, e.g. override the directory-level or namespace-level compatibility information for specific files. - Keep boilerplate out of the file header. No need to update all files when a new compatibility type / edition is released. - No verbose and noisy git commits in the package history. - Option for shared compatibility information across "packages", e.g. for the entire application. - No need for an artificial "package" concept on language level. Let community tools (e.g. Composer) define what a package is. - Possibility to test-run an application or specific files with different compatibility level. - Possibility to control compatibility level based on dynamic file lists, which can be updated based on error statistics, or which can be updated file by file to slowly make an existing codebase compliant with a new version. - The average developer only needs to learn the API of the framework or package manager, and does not need to deal with this on language level. Flaws: - No explicit compatibility information when looking at a specific file. ## Assumptions It is a assumed that "compatibility level" does NOT change the meaning of code. When running a file with a different compatibility level than it was designed for, we may get errors and warnings, but we do not want to get silent changes in behavior. Now I want to see this idea being barbecued.. On Wed, 14 Aug 2019 at 12:27, Michał Brzuchalski wrote: > > śr., 14 sie 2019 o 12:17 Michał Brzuchalski > napisał(a): > > > > > > > śr., 14 sie 2019 o 12:11 Rowan Collins > > napisał(a): > > > >> On 14/08/2019 11:07, Michał Brzuchalski wrote: > >> > Exactly so how would it know from string name either it should load > >> class > >> > from src/Foo.php or src/__nsmeta.php if there is no information? > >> > >> > >> It wouldn't. It would include src/Foo.php, and that would have the > >> definition of something with the name "Foo" - either a class, an > >> interface, a trait, or a package. If it wasn't what the engine was > >> expecting, it would be an error, just as it is right now if you write > >> "implements ClassName", or "new TraitName();" > >> > > > > Following that would introduce
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
śr., 14 sie 2019 o 12:17 Michał Brzuchalski napisał(a): > > > śr., 14 sie 2019 o 12:11 Rowan Collins > napisał(a): > >> On 14/08/2019 11:07, Michał Brzuchalski wrote: >> > Exactly so how would it know from string name either it should load >> class >> > from src/Foo.php or src/__nsmeta.php if there is no information? >> >> >> It wouldn't. It would include src/Foo.php, and that would have the >> definition of something with the name "Foo" - either a class, an >> interface, a trait, or a package. If it wasn't what the engine was >> expecting, it would be an error, just as it is right now if you write >> "implements ClassName", or "new TraitName();" >> > > Following that would introduce unneeded additional directory hierarchy > level in a usual library > which uses PSR-4 which is the most used one, right? > > /composer.json > /src/Foo.php > /src/Foo/ <- all package classes should go here? > Going even further by the example of Doctrine libraries: # doctrine/collections - Composer Package [1] uses PSR-4 autoload with "Doctrine\\Common\\Collections\\" prefix to adopt package concept it would have to change the prefix to "Doctrine\\Common\\" to find Collections.php and all the rest of source code in Collections directory # doctrine/common - Composer Package [2] uses "Doctrine\\Common\\" prefix should change into "Doctrine\\" to be able to load Common.php and the rest of source code in Common directory # ocramius/package-versions - Composer Package [3] uses "PackageVersions\\" prefix and then what? [1] https://github.com/doctrine/collections/blob/master/composer.json [2] https://github.com/doctrine/common/blob/master/composer.json [3] https://github.com/Ocramius/PackageVersions/blob/master/composer.json -- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 14/08/2019 11:17, Michał Brzuchalski wrote: Following that would introduce unneeded additional directory hierarchy level in a usual library which uses PSR-4 which is the most used one, right? /composer.json /src/Foo.php /src/Foo/ <- all package classes should go here? That would be one place to put it, yes. But it would be entirely up to how people wanted to define their autoloader, that's the beauty of it. There's no reason something couldn't generate an autoloader that essentially said this: function autoload($name) { if ( $name == self::PACKAGE_NAME ) { require self::SRC_DIR . '/__packagedef.php'; } elseif ( str_begins_with($name, self::BASE_NAMESPACE) ) { require self::SRC_DIR . str_replace('\\', '/', $name) . '.php'; } } Please don't pick holes in that implementation; my point is, if this was how packages were implemented, people would decide how they wanted to use it, and PSR-4 would probably be superseded by something which accounted for packages existing. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
śr., 14 sie 2019 o 12:11 Rowan Collins napisał(a): > On 14/08/2019 11:07, Michał Brzuchalski wrote: > > Exactly so how would it know from string name either it should load class > > from src/Foo.php or src/__nsmeta.php if there is no information? > > > It wouldn't. It would include src/Foo.php, and that would have the > definition of something with the name "Foo" - either a class, an > interface, a trait, or a package. If it wasn't what the engine was > expecting, it would be an error, just as it is right now if you write > "implements ClassName", or "new TraitName();" > Following that would introduce unneeded additional directory hierarchy level in a usual library which uses PSR-4 which is the most used one, right? /composer.json /src/Foo.php /src/Foo/ <- all package classes should go here? -- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 14/08/2019 11:07, Michał Brzuchalski wrote: Exactly so how would it know from string name either it should load class from src/Foo.php or src/__nsmeta.php if there is no information? It wouldn't. It would include src/Foo.php, and that would have the definition of something with the name "Foo" - either a class, an interface, a trait, or a package. If it wasn't what the engine was expecting, it would be an error, just as it is right now if you write "implements ClassName", or "new TraitName();" Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
śr., 14 sie 2019 o 11:49 Rowan Collins napisał(a): > > You suggest that it would trigger autoload to load "MyVendor\MyPackage" > > but current autoload machinery is able to load only classes, > > not even functions or consts! cause it gets the only class name now. > > It would need to be changed anyway. > > > As I said in another reply, this is only the same change that needed to > be made to support "trait" alongside "class" and "interface", or would > be needed to support "enum" or "struct". The userland part of the > autoloader already doesn't know which of those it's looking for, so the > only constraint is that the names can't collide, so you couldn't name a > package the same thing as a class. > > Exactly so how would it know from string name either it should load class from src/Foo.php or src/__nsmeta.php if there is no information? -- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 14/08/2019 10:27, Michał Brzuchalski wrote: But that's conflicting with you above idea for package definition like that: That's not what I'm suggesting; perhaps my example could have been clearer. I envisage two new keywords: - To put some code in a package, you would write "package Foo;" at the top of a file, or "package Foo { }" around a block, in the same way you can do now for namespaces and declare() statements. - To define a package before it is used, you would write "packagedef Foo { }" around some block of pseudo-PHP that defined the options for that package. That might involve using declare() directly, or might just be an array that defines the options. You suggest that it would trigger autoload to load "MyVendor\MyPackage" but current autoload machinery is able to load only classes, not even functions or consts! cause it gets the only class name now. It would need to be changed anyway. As I said in another reply, this is only the same change that needed to be made to support "trait" alongside "class" and "interface", or would be needed to support "enum" or "struct". The userland part of the autoloader already doesn't know which of those it's looking for, so the only constraint is that the names can't collide, so you couldn't name a package the same thing as a class. There are other problems with autoloading functions and constants, but the relevant point is that you can define function foo() {} and class foo {} in the same namespace; as long as you couldn't also have a separate package foo{}, it could share the same autoloader as classes, interfaces, and traits. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
śr., 14 sie 2019 o 11:01 Rowan Collins napisał(a): > I don't see this as a problem. Right now, PHP doesn't care how many > files you put your code in. As far as I know, you could concatenate the > entirety of Laravel into one PHP file, and applications would not be > able to tell the difference. Similarly, you could put the whole thing in > a database and use eval() to execute it without touching any files. > > That is true but not if there are any declare statements. If so it could IMO work only like that: I think what attracts me to this idea is precisely that it doesn't > require much extra machinery. We could even use the trick that PHPStorm > uses for metadata stubs [1], and make the package definition look like > valid executable PHP, but never actually execute it: > > package Foo { > const declare = [ > 'strict_types' => 1, > 'strict_operators' => 1 > ]; > } > How could that know when need look for package definition? Example: # src/Foo.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 14/08/2019 07:45, Michał Brzuchalski wrote: It doesn't have to be a new syntax if we agree to put package definiction in sort of separate configuration file. With the exception of INI files, all your examples are new syntax, as far as the internal mechanisms in PHP are concerned. They have the advantage of not inventing our own, but the disadvantage of needing our parser to handle all the ways people might write them (particularly true for YAML). That way it would prevent to mix normal PHP code with package definition, cause every possible PHP syntax we would agree, opens the door to add something more to that file, for eg.: # package.php I don't see this as a problem. Right now, PHP doesn't care how many files you put your code in. As far as I know, you could concatenate the entirety of Laravel into one PHP file, and applications would not be able to tell the difference. Similarly, you could put the whole thing in a database and use eval() to execute it without touching any files. In the same way, we can have a package definition not as a configuration file, but as a piece of PHP code that needs to have been executed. In practice, people wouldn't write what you have there for the same reason they don't write this: # foo.php I think what attracts me to this idea is precisely that it doesn't require much extra machinery. We could even use the trick that PHPStorm uses for metadata stubs [1], and make the package definition look like valid executable PHP, but never actually execute it: package Foo { const declare = [ 'strict_types' => 1, 'strict_operators' => 1 ]; } That way, we can probably reuse the whole parser infrastructure, and it looks entirely natural to a PHP programmer. [1]: https://blog.jetbrains.com/phpstorm/2019/02/new-phpstorm-meta-php-features/ -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 13/08/2019 23:28, Mark Randall wrote: On 13/08/2019 21:26, Rowan Collins wrote: Ah, that makes sense. Does that necessarily mean we need a dummy class, though? The autoloading logic in the engine knows that it called the autoload callback expecting a package definition, so can count as success that the package is now defined. In other words, the file the autoloader included would look like this (again, sticking to the notion that "package" is separate from "namespace"): Personally with file-level opt ins I'm not 100% sold on the benefits of packages over namespace level information. I guess I'm not certain on what problem they're trying to solve that's different from just another object at namespace level. The problem they're trying to solve is that at the moment, there is no namespace-level information. Namespaces form an arbitrarily deep hierarchy, and don't need to be declared before they're used; it's hard to retrofit configuration into that. In my mind a package would be very similar to a namespace, but would have a mandatory declaration somewhere, giving a place to define its settings and properties; and there would be no "sub-packages", so no need to define inheritance and over-rides. As for the dummy class, the only real benefit is that existing autoloading procedures can be used to locate it and be included with minimal overhead. PHP can call the autoloader internally but it would require userland loaders to be upgraded with it, not exactly a huge stretch, especially with most things being composer-based, but a dummy class would make it work out the box, including optimization steps like dumping the class list. I see what you mean; but the change needed to autoloaders would be pretty minimal: if they just turn the name into a file path and run file_exists(), no change at all; if they tokenize files in advance to build a class map, they would need to add "packagedef" to the list of tokens to search for, alongside "class", "interface", and "trait". The same change would be needed if we introduced a "struct" or "enum" keyword, and I don't think anyone would expect to write dummy classes alongside those. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
Hi Rowan, wt., 13 sie 2019 o 22:26 Rowan Collins napisał(a): > On 13/08/2019 18:45, Mark Randall wrote: > > I thought about this as my first consideration, however it effectively > > requires that the PHP code within the package class is fully parsed > > and executed in order for it to retrieve the data. > > > > Consider pre-loading where the code is compiled, but not run, it would > > not be possible to use namespace level defines to add compile-level > > optimizations or checks (at least without some AST hackery). > > > Ah, that makes sense. Does that necessarily mean we need a dummy class, > though? The autoloading logic in the engine knows that it called the > autoload callback expecting a package definition, so can count as > success that the package is now defined. > > In other words, the file the autoloader included would look like this > (again, sticking to the notion that "package" is separate from > "namespace"): > > > # > # File: /lib/company/project1.php > # > > > packagedef company/project1 { > strict_types=1; > strict_operators=1; > upgrade_errors_to_exceptions=E_ALL; > } > Was thinking a while about proper syntax and would like to mention what I said before. It doesn't have to be a new syntax if we agree to put package definiction in sort of separate configuration file. In the end all what we need is package name and a bunch of declare directives. Given that it could be easily done using separate conf file like: # package.ini [package] name = MyVendor\MyLibrary strict_types = 1 encoding = UTF-8 # package.json { "name": "MyVendor\\MyLibrary", "declare": { "strict_types": 1, "encoding": "UTF-8" } } # package.toml [[package]] name = "MyVendor\\MyLibrary" strict_types = 1 encoding = "UTF-8" # package.yaml name: MyVendor\MyLibrary strict_types: 1 encoding: UTF-8 That way it would prevent to mix normal PHP code with package definition, cause every possible PHP syntax we would agree, opens the door to add something more to that file, for eg.: # package.php https://wiki.php.net/rfc/namespace_scoped_declares#motivation_and_vision [2] https://www.php.net/manual/en/function.register-tick-function.php -- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 13/08/2019 21:26, Rowan Collins wrote: Ah, that makes sense. Does that necessarily mean we need a dummy class, though? The autoloading logic in the engine knows that it called the autoload callback expecting a package definition, so can count as success that the package is now defined. In other words, the file the autoloader included would look like this (again, sticking to the notion that "package" is separate from "namespace"): Personally with file-level opt ins I'm not 100% sold on the benefits of packages over namespace level information. I guess I'm not certain on what problem they're trying to solve that's different from just another object at namespace level. As for the dummy class, the only real benefit is that existing autoloading procedures can be used to locate it and be included with minimal overhead. PHP can call the autoloader internally but it would require userland loaders to be upgraded with it, not exactly a huge stretch, especially with most things being composer-based, but a dummy class would make it work out the box, including optimization steps like dumping the class list. Mark Randall -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 13/08/2019 18:40, Liam Hammett wrote: This already works (except for the "encoding" declare, which would make little sense halfway down a file). spl_autoload_register(function ($className) { declare(strict_types=1) { include $className . '.php'; } }); This, however, doesn't, because each file has to declare its own options, so we'd need some new syntax for "include with current parser options". It would also lead to the possibility for the same file to be included twice with different options, which would be confusing; or for it to be in OpCache twice with different options, which would be complex to implement. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 13/08/2019 18:45, Mark Randall wrote: I thought about this as my first consideration, however it effectively requires that the PHP code within the package class is fully parsed and executed in order for it to retrieve the data. Consider pre-loading where the code is compiled, but not run, it would not be possible to use namespace level defines to add compile-level optimizations or checks (at least without some AST hackery). Ah, that makes sense. Does that necessarily mean we need a dummy class, though? The autoloading logic in the engine knows that it called the autoload callback expecting a package definition, so can count as success that the package is now defined. In other words, the file the autoloader included would look like this (again, sticking to the notion that "package" is separate from "namespace"): # # File: /lib/company/project1.php # http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
> On 14 Aug 2019, at 00:05, Rowan Collins wrote: > >> On 13/08/2019 12:01, Mark Randall wrote: >>> On 13/08/2019 10:02, Rowan Collins wrote: >>> I really like this approach. It allows a package definition file to exist, >>> without either the language or the header of each file having to define its >>> location. >> >> # >> # File: /lib/company/project1/a/b/MyClass.php >> # >> >> > >> declare_import(company[:label]); >> >> namespace company/project1/a/b; >> >> ... >> >> >> # >> # File: /lib/company/__nsmeta.php >> # >> >> > >> namespace company; >> >> namespace_declare [:label] { >> strict_types=1; >> strict_operators=1; >> upgrade_errors_to_exceptions=E_ALL; >> } >> >> final class __nsmeta { >> /* does nothing except be findable by the autoloader */ >> /* and defaults to private constructor so it can't be used */ >> } > > > This seems to be more complicated than Nicolas's version, and involve much > more special magic, like the name __nsmeta, and the class that does nothing. > I'm also not clear on how you're picturing the relationship between > namespaces and packages. > > The way I understood the suggestion, you'd end up with something more like > this, which feels much simpler and cleaner: > > # > # File: /lib/company/project1/a/b/MyClass.php > # > > > declare(package=company/project1); > // or with a new keyword > package company/project1; > > namespace company/project1/a/b; > > ... > > > # > # File: /lib/company/project1.php > # > > > namespace company; > > class project1 extends \PHP\Package { > public function getParserDirectives() { > return [ > 'strict_types' => 1, > 'strict_operators' => 1, > 'upgrade_errors_to_exceptions' => E_ALL > ]; > } > } > > Regards, > > -- > Rowan Collins > [IMSoP] > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > I think this approach is easier to follow (less magic) but has a (small) potential for conflict with existing code that may then require renaming or more (eg if a class existed with that proposed name, and is either a singleton and/or already extends another class). Is it feasible to instead require the class implements an interface that defines a static method? Building on that, could the concept of “do something to initialise this package” be made more generic: when a file declares it’s a member of a given package, the static method on the class that matches the package name is called, and it’s up to the developer what it does in that method. That would of course also then require a new function to set the declares with package scope to be useful for this particular problem, but it also allows more control and power for the concept of packages in general. Cheers Stephen -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 13/08/2019 18:05, Rowan Collins wrote: This seems to be more complicated than Nicolas's version, and involve much more special magic, like the name __nsmeta, and the class that does nothing. I'm also not clear on how you're picturing the relationship between namespaces and packages. I was looking for a way that would be intuitive to the existing system. We already have an existing userland system for locating a class. By using a placeholder class we can locate it using our existing logic. class project1 extends \PHP\Package { public function getParserDirectives() { return [ 'strict_types' => 1, 'strict_operators' => 1, 'upgrade_errors_to_exceptions' => E_ALL ]; } } I thought about this as my first consideration, however it effectively requires that the PHP code within the package class is fully parsed and executed in order for it to retrieve the data. Consider pre-loading where the code is compiled, but not run, it would not be possible to use namespace level defines to add compile-level optimizations or checks (at least without some AST hackery). Meanwhile, the compiler itself could pull out a namespace_declare block and fully understand the information in it without actually needing to run anything. If I was writing a runtime package system, I would absolutely do it in the way you suggest, and in fact I already do for my own packages which deal with wrapping up css / js / html template files. Perfect for runtime, not so good for compile time, but if I'm wrong I dare say someone will let me know. Mark Randall -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 13/08/2019 12:01, Mark Randall wrote: On 13/08/2019 10:02, Rowan Collins wrote: I really like this approach. It allows a package definition file to exist, without either the language or the header of each file having to define its location. # # File: /lib/company/project1/a/b/MyClass.php # This seems to be more complicated than Nicolas's version, and involve much more special magic, like the name __nsmeta, and the class that does nothing. I'm also not clear on how you're picturing the relationship between namespaces and packages. The way I understood the suggestion, you'd end up with something more like this, which feels much simpler and cleaner: # # File: /lib/company/project1/a/b/MyClass.php # 1, 'strict_operators' => 1, 'upgrade_errors_to_exceptions' => E_ALL ]; } } Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 13/08/2019 10:02, Rowan Collins wrote: I really like this approach. It allows a package definition file to exist, without either the language or the header of each file having to define its location. # # File: /lib/company/project1/a/b/MyClass.php # Caveat would be for situations that do not use an autoloader, the __nsmeta.php would need to be loaded first, this is something that PHP7.4 autoloaders would need to take into consideration. Mark Randall -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 12/08/2019 09:17, Nicolas Grekas wrote: Individual files could declare their package using this style: I really like this approach. It allows a package definition file to exist, without either the language or the header of each file having to define its location. Importantly, although it would trigger the autoloader if not yet defined, the package could be defined in advance, for instance as part of a preload directive. It could even be possible to define multiple packages in one file, or define them dynamically, using all the existing features of the language like require and eval. On a bikeshedding note, I've never liked the way declare syntax looks, so would prefer a new keyword, but the symmetry of replacing declare(strict_types=1); with declare(package=Something\Defining\StrictOptions); is admittedly quite appealing. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
Hi Larry, pon., 12 sie 2019 o 15:45 Larry Garfield napisał(a): > > Has anyone done in-depth research into how other languages handle > packages, and what advantages packages would have over just our existing > nested namespaces? I feel like there's ample prior art here that we should > not ignore. > I did some writings on that https://brzuchal.com/posts/packages-in-programming-languages/ was a little hurry but tried my best to grasp key aspects of package / module concept in other languages. -- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 12/08/2019 14:45, Larry Garfield wrote: I don't think declaring the package in each file is necessarily bad. Every language I've worked in either has you declare a package explicitly or implies it off of the file system and you don't get any say in the matter. Of the two, I prefer the former. I concur with this, I would much rather specify a reference to external metadata once-per-file than have it controlled by invisible external state. If I send an individual file to a co-worker, IMO it should be immediately obvious at the top of that file that it belongs to package and may depend on that package definition to control its behaviour (especially if it gets loaded up with declares or editions). I'll simply be replacing my ubiquitous strict-types declare with whatever was used to reference this package. Mark Randall -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On Mon, Aug 12, 2019, at 3:26 AM, Nikita Popov wrote: > On Mon, Aug 12, 2019 at 10:17 AM Nicolas Grekas < > nicolas.grekas+...@gmail.com> wrote: > > 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. > > Nikita I don't think declaring the package in each file is necessarily bad. Every language I've worked in either has you declare a package explicitly or implies it off of the file system and you don't get any say in the matter. Of the two, I prefer the former. My concern with using a function call is that it introduces/increases the potential for a file to say it uses a namespace that isn't yet defined. What happens then? Fatal? Autoload trigger? The code ends up un-packaged silently? (Please not the last one.) I don't feel like "it's Composer's problem" is a good answer here. Making the package name be a class name at least makes autoloading a natural and well understood way to handle the lookup. There may be other benefits to using a class/methods to define a package, or possibly even downsides; I'm not sure there. More research needed. Same for avoiding package name collisions; "it's FIG's problem" may be an answer, but it seems like a poor one. In practice I'd expect package definitions to be the obvious example of the preloader, but there will always be cases where the preloader is not available or cannot be used so we need to consider the performance impact of registering packages in every request. Has anyone done in-depth research into how other languages handle packages, and what advantages packages would have over just our existing nested namespaces? I feel like there's ample prior art here that we should not ignore. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
Hi, Am 12.08.19 um 10:26 schrieb Nikita Popov: On Mon, Aug 12, 2019 at 10:17 AM Nicolas Grekas < nicolas.grekas+...@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: 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 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
> On 12 Aug 2019, at 15:26, Nikita Popov wrote: > > On Mon, Aug 12, 2019 at 10:17 AM Nicolas Grekas < > nicolas.grekas+...@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. > > Nikita Is there some specific benefit to passing an array with `name` and `declares` keys, over a signature like either package_declare(‘nikic/php-parser’, strict_types=1, foo=bar); or even package_declare('nikic/php-parser’, [‘strict_types’ => 1, ‘foo’ => bar]); I realise this is the epitome of bike shedding, it just seems like a non-obvious choice (to me at least) to accept a specifically structured array? Cheers Stephen -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
Hi Nicolas, pon., 12 sie 2019 o 10:17 Nicolas Grekas napisał(a): > 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. > > Why suggesting use of declare for that? Wouldn't a new "package" keyword be more appropriate for that? For eg.: 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 > -- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On Mon, Aug 12, 2019 at 10:17 AM Nicolas Grekas < nicolas.grekas+...@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. Nikita
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
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:
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 13/12/2017 07:12, Michał Brzuchalski wrote: Andreas, we're touching namespaces which is a hard subject, but if I could fly away with my thoughts I'd propose to introduce something called for eg. a package My thoughts were actually going along the same lines: basically, the current implementation of namespaces is, I think by design, very conservative in what a namespace represents. A namespace doesn't have any identity, and doesn't have any codified structure, it's just a shorthand for referring to similarly named classes (plus functions and constants). There are several things that I think would feel more natural with "packages" than namespaces as they exist today: - Declare directives, as discussed here - Visibility modifiers, e.g. a "private class", accessible only within its package - Per-package autoloaders, that only get called for classes in that package, rather than a global autoloader which parses out the prefixes it's interested in - An autoloader callback that fires once for each package, to setup these options Another difference is that namespaces tend to form deep hierarchies, but you're unlikely to set options at every level of the hierarchy. For instance, you probably don't want to set strict_types on for Acme\MyPackage\Input but off for Acme\MyPackage\Output. So a separate syntax to mark which level is the "package" would reduce the number of places a setting could be set, which would reduce the number of places you'd need to look - a bit like having Apache settings in a VirtualHost for the whole site, rather than .htaccess files in every directory. All that being said, I'm not 100% convinced this is solving a real problem. Yes, the option has to be set in every file, but that's because it effects the way that file is compiled, and the compiler sees one file at a time. The same applies to the "namespace" directive, which you might otherwise set against a particular directory. I don't see a pressing need to add the complexity. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
""Michal Brzuchalski"" wrote in message news:cabdc3wrz8qu_hgsbtjgbwwct8yplxgchonee9nijkwcderu...@mail.gmail.com... 13.12.2017 11:44 "Tony Marston"napisal(a): ""Michal Brzuchalski"" wrote in message news:CABdc3WpomNLz+vX_m0B0wQ3u cimiw8xw4ea_sgd-ptdgfv-...@mail.gmail.com... 2017-12-13 1:16 GMT+01:00 Andreas Hennings : Why? Because users use PSR-4 so then they're src folder looks more like: ? You are assuming that everybody is using PSR-4. That is a wrong assumption to make. I didn't say everybody at all! Please read carefully. I DID read carefully. You wrote "users use PSR-4" and not "those users who use PSR-4". You did not specify a subset of users, so this implies all users. -- Tony Marston -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
13.12.2017 11:44 "Tony Marston"napisał(a): ""Michal Brzuchalski"" wrote in message news:CABdc3WpomNLz+vX_m0B0wQ3u cimiw8xw4ea_sgd-ptdgfv-...@mail.gmail.com... > 2017-12-13 1:16 GMT+01:00 Andreas Hennings : > > > Why? Because users use PSR-4 so then they're src folder looks more like: > ? You are assuming that everybody is using PSR-4. That is a wrong assumption to make. I didn't say everybody at all! Please read carefully. -- Tony Marston -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
""Michal Brzuchalski"" wrote in message news:cabdc3wpomnlz+vx_m0b0wq3ucimiw8xw4ea_sgd-ptdgfv-...@mail.gmail.com... 2017-12-13 1:16 GMT+01:00 Andreas Hennings: Why? Because users use PSR-4 so then they're src folder looks more like: ? You are assuming that everybody is using PSR-4. That is a wrong assumption to make. -- Tony Marston -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
"Andreas Hennings" wrote in message news:CAH0Uv3FnYf_c7in4_6AmDO5pUZHsgU0m5scjU5oRz2kTAJ=+b...@mail.gmail.com... I agree with all of Stanislav's emails in this thread so far. On 12 December 2017 at 14:43, Nikita Popovwrote: On Tue, Dec 12, 2017 at 8:46 AM, Stanislav Malyshev wrote: PHP as a language should not assume that someone is using Composer correctly. Or even using Composer at all. -- Tony Marston -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
2017-12-13 6:04 GMT+01:00 Michał Brzuchalski: > > > 2017-12-13 5:38 GMT+01:00 Michał Brzuchalski : > >> >> >> 2017-12-13 5:24 GMT+01:00 Andreas Hennings : >> >>> On 13 December 2017 at 05:04, Michał Brzuchalski >>> wrote: >>> > >>> > If we're going to introduce someday a namespace file, then IMO it >>> should not >>> > be putted outside namespace folder. >>> > For eg class Acme\Animal\Cat in src/Acme/Animal/Cat.php should have >>> > namespace file in src/Acme/Aniimal/namespace.php >>> > or even more src/Acme/Animal/ns.php >>> > Why? Because users use PSR-4 so then they're src folder looks more >>> like: >>> > src/Cat.php <-- class Acme\Animal\Cat >>> > src/ns.php <-- that should be then a place for namespace declare or >>> even >>> > function and constants. >>> >>> You are right, my previous proposal src/Acme/Animal.namespace.php >>> would not work universally. >>> >>> But your proposal, src/Acme/Animal/ns.php clashes with the class file >>> for class \Acme\Animal\ns. >>> >>> We would need something other than NAME.php. >>> E.g. src/Acme/Animal/ns.inc.php >>> >> > Actually not true. `namespace` keyword is reserved and none class can have > such name. > This means this example couses a syntax error: > > namespace Acme\Animals; > class namespace {} > > That why we can assume we can utilise namespace.php file name. > And also why not trying to include it on autoload call? > For eg. > > new Acme\Animal\Cat(); // tries to load $file = "src/Acme/Animal/Cat.php" > > // but prevoiusly tries to load > require_once dirname($file) . DIRECTORY_SEPARATOR . 'namespace.php'; > > It's bad because it';s magic, but the `namespace.php` filename is still > available to use. > > Andreas, we're touching namespaces which is a hard subject, but if I could fly away with my thoughts I'd propose to introduce something called for eg. a package and then divide it's name in class/function/const name with a single colon, for eg. Acme:Animal\Cat which gives additional information about package which then declares something and may be a good start for future scoped declarations. I've prepared a short gist to illustrate that https://gist.github.com/brzuchal/352ffce2717648f0d43f2d5a0c4bfb7b This solution doesn't require usage of Composer, but needs to pass an aotuloader function a type to load. There was a proposal on internal some time ago to pass additional parameter to load function. > >>> But then Composer would still need to make sure that this file is >>> always included before any class files from this directory. >>> On language level we cannot assume that Composer is being used, and >>> that it is being used correctly. >>> >>> So again this would be fragile. >>> >>> > >>> > Such namespace file can be a good place for namespace function and >>> constants >>> > declaration. >>> > Also I think there is no need for another global function named >>> > `namespace_declare` if we had namespace file >>> > then we can utilise declare for that. >>> > Lets imagine such syntax: >>> > >>> > // src/Acme/Animal/ns.php >>> > >> > >>> > namespace Acme\Animal declare(strict_types=1,another_option=0); >>> > const CAT = 1; >>> > function createCat() : Cat {} >>> >>> This means you are changing the meaning of existing declare() to apply >>> to the entire namespace? >>> Or to the entire directory? >>> >>> >> To entire namespace just like: >> >> > >> namespace_declare('Acme\Animal', [ >> 'strict_types' => 1, >> 'dynamic_object_properties' => 0, >> ... >> ]); >> >> namespace Acme\Animal declare( >> strict_types=1, >> dynamic_object_properties=0 >> ); // <-- this works same as namespace_declare call above >> >> namespace Acme\Machines { >> // here we have strict_types=0 turned off >> } >> >> >>> Or maybe the difference here is that there is no semicolon directly >>> after the namespace declaration? >>> >>> I am not convinced by this syntax. >>> But even if we would find a good syntax, the behavioral problems >>> pointed out by Stanislav still apply. >>> >> >> >> >> -- >> regards / pozdrawiam, >> -- >> Michał Brzuchalski >> about.me/brzuchal >> brzuchalski.com >> > > > > -- > regards / pozdrawiam, > -- > Michał Brzuchalski > about.me/brzuchal > brzuchalski.com > -- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 11.12.17 14:43, Nikita Popov wrote: 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. Thanks for the proposal. While it seems comfortable for the user, and I understand the point you're trying to solve somehow, it can be a nightmare for the VM, the developer, and the user. I've few remarks and/or questions: * When parsing a file, the way the VM has to interprete/execute the file depends on a _runtime_ configuration defined in _another_ file. It makes things more implicit, and that's not good. * It can also be a nightmare for the developer. The behavior of their library can be changed by another library because there is no restriction about the location or usage of `namespace_declare`. If at least `namespace_declare` would only apply to the _current_ namespace, it might be better. * If `namespace_declare` is called twice for the same namespace, an error is raised, OK. It's easy to break someone's code by registering a file in an autoloader to load first, and call `namespace_declare` for that file. What the error will look like? It's important to prompt the correct culprit to the user. Any strategy to find which one is the culprit? * As you said in the RFC in the Proliferation of declare directives Section, it's not a good thing for the language to introduce more and more directives. PHP is living a time where it makes good things easier to do, and bad things harder to do. Everything I can imagine with `namespace_declare` is definitively not good for the language, the VM, and the ecosystem. Introducing a `strict` mode for the language is definitively a good thing to progressively make PHP stricter, yes, but I don't see a real need or a real motiviation behind `namespace_declare`, I for one see only dangers. So I'm sorry to say that —right now— I'm totally oppose to this RFC :-). Cheers. -Ivan. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
2017-12-13 5:38 GMT+01:00 Michał Brzuchalski: > > > 2017-12-13 5:24 GMT+01:00 Andreas Hennings : > >> On 13 December 2017 at 05:04, Michał Brzuchalski >> wrote: >> > >> > If we're going to introduce someday a namespace file, then IMO it >> should not >> > be putted outside namespace folder. >> > For eg class Acme\Animal\Cat in src/Acme/Animal/Cat.php should have >> > namespace file in src/Acme/Aniimal/namespace.php >> > or even more src/Acme/Animal/ns.php >> > Why? Because users use PSR-4 so then they're src folder looks more like: >> > src/Cat.php <-- class Acme\Animal\Cat >> > src/ns.php <-- that should be then a place for namespace declare or even >> > function and constants. >> >> You are right, my previous proposal src/Acme/Animal.namespace.php >> would not work universally. >> >> But your proposal, src/Acme/Animal/ns.php clashes with the class file >> for class \Acme\Animal\ns. >> >> We would need something other than NAME.php. >> E.g. src/Acme/Animal/ns.inc.php >> > Actually not true. `namespace` keyword is reserved and none class can have such name. This means this example couses a syntax error: > But then Composer would still need to make sure that this file is >> always included before any class files from this directory. >> On language level we cannot assume that Composer is being used, and >> that it is being used correctly. >> >> So again this would be fragile. >> >> > >> > Such namespace file can be a good place for namespace function and >> constants >> > declaration. >> > Also I think there is no need for another global function named >> > `namespace_declare` if we had namespace file >> > then we can utilise declare for that. >> > Lets imagine such syntax: >> > >> > // src/Acme/Animal/ns.php >> > > > >> > namespace Acme\Animal declare(strict_types=1,another_option=0); >> > const CAT = 1; >> > function createCat() : Cat {} >> >> This means you are changing the meaning of existing declare() to apply >> to the entire namespace? >> Or to the entire directory? >> >> > To entire namespace just like: > > > namespace_declare('Acme\Animal', [ > 'strict_types' => 1, > 'dynamic_object_properties' => 0, > ... > ]); > > namespace Acme\Animal declare( > strict_types=1, > dynamic_object_properties=0 > ); // <-- this works same as namespace_declare call above > > namespace Acme\Machines { > // here we have strict_types=0 turned off > } > > >> Or maybe the difference here is that there is no semicolon directly >> after the namespace declaration? >> >> I am not convinced by this syntax. >> But even if we would find a good syntax, the behavioral problems >> pointed out by Stanislav still apply. >> > > > > -- > regards / pozdrawiam, > -- > Michał Brzuchalski > about.me/brzuchal > brzuchalski.com > -- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
2017-12-13 5:24 GMT+01:00 Andreas Hennings: > On 13 December 2017 at 05:04, Michał Brzuchalski > wrote: > > > > If we're going to introduce someday a namespace file, then IMO it should > not > > be putted outside namespace folder. > > For eg class Acme\Animal\Cat in src/Acme/Animal/Cat.php should have > > namespace file in src/Acme/Aniimal/namespace.php > > or even more src/Acme/Animal/ns.php > > Why? Because users use PSR-4 so then they're src folder looks more like: > > src/Cat.php <-- class Acme\Animal\Cat > > src/ns.php <-- that should be then a place for namespace declare or even > > function and constants. > > You are right, my previous proposal src/Acme/Animal.namespace.php > would not work universally. > > But your proposal, src/Acme/Animal/ns.php clashes with the class file > for class \Acme\Animal\ns. > > We would need something other than NAME.php. > E.g. src/Acme/Animal/ns.inc.php > > But then Composer would still need to make sure that this file is > always included before any class files from this directory. > On language level we cannot assume that Composer is being used, and > that it is being used correctly. > > So again this would be fragile. > > > > > Such namespace file can be a good place for namespace function and > constants > > declaration. > > Also I think there is no need for another global function named > > `namespace_declare` if we had namespace file > > then we can utilise declare for that. > > Lets imagine such syntax: > > > > // src/Acme/Animal/ns.php > > > > > namespace Acme\Animal declare(strict_types=1,another_option=0); > > const CAT = 1; > > function createCat() : Cat {} > > This means you are changing the meaning of existing declare() to apply > to the entire namespace? > Or to the entire directory? > > To entire namespace just like: 1, 'dynamic_object_properties' => 0, ... ]); namespace Acme\Animal declare( strict_types=1, dynamic_object_properties=0 ); // <-- this works same as namespace_declare call above namespace Acme\Machines { // here we have strict_types=0 turned off } > Or maybe the difference here is that there is no semicolon directly > after the namespace declaration? > > I am not convinced by this syntax. > But even if we would find a good syntax, the behavioral problems > pointed out by Stanislav still apply. > -- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On 13 December 2017 at 05:04, Michał Brzuchalskiwrote: > > If we're going to introduce someday a namespace file, then IMO it should not > be putted outside namespace folder. > For eg class Acme\Animal\Cat in src/Acme/Animal/Cat.php should have > namespace file in src/Acme/Aniimal/namespace.php > or even more src/Acme/Animal/ns.php > Why? Because users use PSR-4 so then they're src folder looks more like: > src/Cat.php <-- class Acme\Animal\Cat > src/ns.php <-- that should be then a place for namespace declare or even > function and constants. You are right, my previous proposal src/Acme/Animal.namespace.php would not work universally. But your proposal, src/Acme/Animal/ns.php clashes with the class file for class \Acme\Animal\ns. We would need something other than NAME.php. E.g. src/Acme/Animal/ns.inc.php But then Composer would still need to make sure that this file is always included before any class files from this directory. On language level we cannot assume that Composer is being used, and that it is being used correctly. So again this would be fragile. > > Such namespace file can be a good place for namespace function and constants > declaration. > Also I think there is no need for another global function named > `namespace_declare` if we had namespace file > then we can utilise declare for that. > Lets imagine such syntax: > > // src/Acme/Animal/ns.php > > namespace Acme\Animal declare(strict_types=1,another_option=0); > const CAT = 1; > function createCat() : Cat {} This means you are changing the meaning of existing declare() to apply to the entire namespace? Or to the entire directory? Or maybe the difference here is that there is no semicolon directly after the namespace declaration? I am not convinced by this syntax. But even if we would find a good syntax, the behavioral problems pointed out by Stanislav still apply. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
2017-12-13 1:16 GMT+01:00 Andreas Hennings: > I agree with all of Stanislav's emails in this thread so far. > > On 12 December 2017 at 14:43, Nikita Popov wrote: > > On Tue, Dec 12, 2017 at 8:46 AM, Stanislav Malyshev > > > wrote: > > > >> Hi! > >> > >> > The idea is to allow specifying declare directives for a whole > library or > >> > project using: > >> > > >> > namespace_declare('Vendor\Lib', ['strict_types' => 1]); > >> > >> I am not sure I like this. Namespace is a prefix to a class name. > >> Anybody can declare a class with any name, and the side-effect that they > >> would inherit some context, which is completely invisible and would > >> magically exist somewhere globally, does not seem like a good idea to > >> me. Moreover, what if something - like older version of the same library > >> or test or something like that - would have different idea about what > >> that global state should be? How nice would it be if a piece of > >> unrelated code could completely change how my code is interpreted? How > >> nice would it be if whether it works or not would depend on in which > >> order classes were loaded in this particular request? > >> > > > > The way PHP works, it's not possible to have two versions of a library > > loaded at the same time. > > Really? > PHP does not even know what a "library" is. PHP sees files, > directories and namespaces. But it does not know how to conceptualize > any of this as a "library". > > With Composer you get the notion of a "package". > In general, Composer would prevent you from using different versions > of the same package. > But you could manually download two versions of a package, and wire up > the class loader in a way that it would load some classes from one > version, and some classes from another version. > E.g. if a class does not exist in version 2, load the class from > version 1 instead. > > PHP as a language should not assume that someone is using Composer > correctly. > > And even if we avoid two package versions coexisting: There could > easily be two distinct packages that use the same namespace. > We could discuss if this is a good idea, but it should not be the job > of PHP as a language to make this situation difficult. > > > > > There is no dependence on loading order. The implementation is careful to > > ensure that the used declare state is consistent. It's not possible to > call > > namespace_declare() twice on the same namespace. It's not possible to > first > > load some files from a namespace, do the namespace_declare() call and > then > > load some more files. If a namespace_declare() call succeeds without > > throwing an error, then that is the ground truth, without any dependence > on > > order or other calls. > > So by "is not possible", in fact you mean "will trigger an error". > > I imagine with Composer we would have to agree on a canonical file > name where a namespace_declare() would be found. > Maybe something like in src/Acme/Animal.namespace.php. > > The class loader would then have to make sure that this file is > included before the first class from that namespace is included. > Or alternatively, Composer init script would have to include all such > files at the beginning of the process. > > If Composer (or whichever tool one wants to use) would include class > file src/Acme/Animal/Cat.php without prior inclusion of the > Animal.namespace.php, the class file would be interpreted without the > desired setting. > If the process then continues without ever including > Animal.namespace.php, it will silently misbehave. > If, however, Animal.namespace.php is included some time later in the > process, then it would notice that something went wrong, and trigger > an error. > > If we're going to introduce someday a namespace file, then IMO it should not be putted outside namespace folder. For eg class Acme\Animal\Cat in src/Acme/Animal/Cat.php should have namespace file in src/Acme/Aniimal/namespace.php or even more src/Acme/Animal/ns.php Why? Because users use PSR-4 so then they're src folder looks more like: src/Cat.php <-- class Acme\Animal\Cat src/ns.php <-- that should be then a place for namespace declare or even function and constants. Such namespace file can be a good place for namespace function and constants declaration. Also I think there is no need for another global function named `namespace_declare` if we had namespace file then we can utilise declare for that. Lets imagine such syntax: // src/Acme/Animal/ns.php I haven't thought too carefully about whether having an option for the > > explicit-send-by-ref feature *specifically* would be beneficial, but I > > think it's very important to at least have the option on the table. Too > > many issues in PHP cannot be solved for reasons of > backwards-compatibility. > > We need to have *some* way to evolve the language without BC breaks, and > I > > think namespace-declares are an elegant way to do
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
I agree with all of Stanislav's emails in this thread so far. On 12 December 2017 at 14:43, Nikita Popovwrote: > On Tue, Dec 12, 2017 at 8:46 AM, Stanislav Malyshev > wrote: > >> Hi! >> >> > The idea is to allow specifying declare directives for a whole library or >> > project using: >> > >> > namespace_declare('Vendor\Lib', ['strict_types' => 1]); >> >> I am not sure I like this. Namespace is a prefix to a class name. >> Anybody can declare a class with any name, and the side-effect that they >> would inherit some context, which is completely invisible and would >> magically exist somewhere globally, does not seem like a good idea to >> me. Moreover, what if something - like older version of the same library >> or test or something like that - would have different idea about what >> that global state should be? How nice would it be if a piece of >> unrelated code could completely change how my code is interpreted? How >> nice would it be if whether it works or not would depend on in which >> order classes were loaded in this particular request? >> > > The way PHP works, it's not possible to have two versions of a library > loaded at the same time. Really? PHP does not even know what a "library" is. PHP sees files, directories and namespaces. But it does not know how to conceptualize any of this as a "library". With Composer you get the notion of a "package". In general, Composer would prevent you from using different versions of the same package. But you could manually download two versions of a package, and wire up the class loader in a way that it would load some classes from one version, and some classes from another version. E.g. if a class does not exist in version 2, load the class from version 1 instead. PHP as a language should not assume that someone is using Composer correctly. And even if we avoid two package versions coexisting: There could easily be two distinct packages that use the same namespace. We could discuss if this is a good idea, but it should not be the job of PHP as a language to make this situation difficult. > > There is no dependence on loading order. The implementation is careful to > ensure that the used declare state is consistent. It's not possible to call > namespace_declare() twice on the same namespace. It's not possible to first > load some files from a namespace, do the namespace_declare() call and then > load some more files. If a namespace_declare() call succeeds without > throwing an error, then that is the ground truth, without any dependence on > order or other calls. So by "is not possible", in fact you mean "will trigger an error". I imagine with Composer we would have to agree on a canonical file name where a namespace_declare() would be found. Maybe something like in src/Acme/Animal.namespace.php. The class loader would then have to make sure that this file is included before the first class from that namespace is included. Or alternatively, Composer init script would have to include all such files at the beginning of the process. If Composer (or whichever tool one wants to use) would include class file src/Acme/Animal/Cat.php without prior inclusion of the Animal.namespace.php, the class file would be interpreted without the desired setting. If the process then continues without ever including Animal.namespace.php, it will silently misbehave. If, however, Animal.namespace.php is included some time later in the process, then it would notice that something went wrong, and trigger an error. > I haven't thought too carefully about whether having an option for the > explicit-send-by-ref feature *specifically* would be beneficial, but I > think it's very important to at least have the option on the table. Too > many issues in PHP cannot be solved for reasons of backwards-compatibility. > We need to have *some* way to evolve the language without BC breaks, and I > think namespace-declares are an elegant way to do this. So if you want a setting for explicit-send-by-ref, why not do this per file, as we already do for strict_types? If at some day in the future we find that the declares become too verbose, we could bundle multiple declares into a new setting. E.g. something like "declare(php=8.1);" to combine all the declares that would be considered default in PHP 8.1. Or introduce some other shortcut like "http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
Hi! > There is no dependence on loading order. The implementation is careful > to ensure that the used declare state is consistent. It's not possible > to call namespace_declare() twice on the same namespace. It's not > possible to first load some files from a namespace, do the > namespace_declare() call and then load some more files. If a This means that namespace_declare can be only in one file, and if any mention of any namespace class has been made before that file has been loaded, then the declare would fail. That is loading order dependency - if A.php contains namespace_declare and B.php contains another class of the same namespace, then order (A, B) works but order (B, A) does not. > The big issue with ini settings is (mostly) not the "hidden" part, it's > the "global" part. Ini settings that change language behavior are tabu Exactly. And this proposal adds another global state, which is also invisible, so figuring out what the state is when debugging is... fun. It's better than php.ini as it's "namespaced php.ini" but still suffers from the same problems within the namespace (and namespaces can be pretty big). > this. A library can namespace_declare() it's configuration and be sure > that this is the configuration it's going to get, at the same time not > interfering with any other library or code that uses a different > configuration. This assumes each namespace is homogeneous code always belonging to the same library and nothing is every added to that namespace. This is not always the case. -- Stas Malyshev smalys...@gmail.com -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On Tue, Dec 12, 2017 at 8:46 AM, Stanislav Malyshevwrote: > Hi! > > > The idea is to allow specifying declare directives for a whole library or > > project using: > > > > namespace_declare('Vendor\Lib', ['strict_types' => 1]); > > I am not sure I like this. Namespace is a prefix to a class name. > Anybody can declare a class with any name, and the side-effect that they > would inherit some context, which is completely invisible and would > magically exist somewhere globally, does not seem like a good idea to > me. Moreover, what if something - like older version of the same library > or test or something like that - would have different idea about what > that global state should be? How nice would it be if a piece of > unrelated code could completely change how my code is interpreted? How > nice would it be if whether it works or not would depend on in which > order classes were loaded in this particular request? > The way PHP works, it's not possible to have two versions of a library loaded at the same time. There are projects like https://github.com/humbug/php-scoper to allow loading a library multiple times, which work by prefixing all namespaces. Of course, in this case namespace_declares() would also be applied to different namespaces and there will be no interference. There is no dependence on loading order. The implementation is careful to ensure that the used declare state is consistent. It's not possible to call namespace_declare() twice on the same namespace. It's not possible to first load some files from a namespace, do the namespace_declare() call and then load some more files. If a namespace_declare() call succeeds without throwing an error, then that is the ground truth, without any dependence on order or other calls. > Hidden global context has the same smell as php.ini settings, and for > the same reason - but this, as far as I can see, will also be hidden and > depending on file loading order, class loading order, etc. which in big > applications can lead to a lot of fun debugging why some code randomly > produces fatal errors... Debugging PHP is fun enough without quantum > entanglement-like effects :) > As said above, the implementation makes sure that all quantum state is collapsed ;) The only possible mistake that can occur is that the namespace_declare() call doesn't happen at all, but anything depending on loading order or conflicting calls is not possible. The big issue with ini settings is (mostly) not the "hidden" part, it's the "global" part. Ini settings that change language behavior are tabu because they apply to everything, so no library can assume any particular ini configuration. Namespace-scoped declares explicitly avoid this. A library can namespace_declare() it's configuration and be sure that this is the configuration it's going to get, at the same time not interfering with any other library or code that uses a different configuration. > 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. > > Where "soon" means "for all practical purposes, forever, unless we stop > calling that new thing PHP", IMO. > > > Namespace-scoped declares are perfectly suited to resolve this problem. > We > > I don't think so. First of all, I don't think, of course, that this > problem needs to be solved by adding more complexity to save a purely > cosmetic feature. But second of all, I don't think global hidden context > that could change at a distance how the code is interpreted is a good > idea regardless of whether it solves the issues with send-by-ref. > I haven't thought too carefully about whether having an option for the explicit-send-by-ref feature *specifically* would be beneficial, but I think it's very important to at least have the option on the table. Too many issues in PHP cannot be solved for reasons of backwards-compatibility. We need to have *some* way to evolve the language without BC breaks, and I think namespace-declares are an elegant way to do this. Regards, Nikita
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
Hi! > The idea is to allow specifying declare directives for a whole library or > project using: > > namespace_declare('Vendor\Lib', ['strict_types' => 1]); I am not sure I like this. Namespace is a prefix to a class name. Anybody can declare a class with any name, and the side-effect that they would inherit some context, which is completely invisible and would magically exist somewhere globally, does not seem like a good idea to me. Moreover, what if something - like older version of the same library or test or something like that - would have different idea about what that global state should be? How nice would it be if a piece of unrelated code could completely change how my code is interpreted? How nice would it be if whether it works or not would depend on in which order classes were loaded in this particular request? Hidden global context has the same smell as php.ini settings, and for the same reason - but this, as far as I can see, will also be hidden and depending on file loading order, class loading order, etc. which in big applications can lead to a lot of fun debugging why some code randomly produces fatal errors... Debugging PHP is fun enough without quantum entanglement-like effects :) > 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. Where "soon" means "for all practical purposes, forever, unless we stop calling that new thing PHP", IMO. > Namespace-scoped declares are perfectly suited to resolve this problem. We I don't think so. First of all, I don't think, of course, that this problem needs to be solved by adding more complexity to save a purely cosmetic feature. But second of all, I don't think global hidden context that could change at a distance how the code is interpreted is a good idea regardless of whether it solves the issues with send-by-ref. -- Stas Malyshev smalys...@gmail.com -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On Mon, Dec 11, 2017 at 4:46 PM, Sara Golemonwrote: > On Mon, Dec 11, 2017 at 8:43 AM, Nikita Popov > wrote: > > 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. > > > Being lazy here because I'm literally on my way out the door and don't > have a moment to parse through the implementation, but can you clarify > how this impact compile-time declares? > > > require('a.php"); > require('b.php"); // This file has a namespace declaration > require('c.php"); > > In this example, does a.php wind up getting compiled with a different > set of declares than b.php and c.php? > > -Sara > Nope. The namespace_declare() call in this case will throw an Error, because code using that namespace has already been loaded. The implementation is careful to ensure that it's never possible to end up in a situation where the used declare directives are inconsistent. Nikita
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
On Mon, Dec 11, 2017 at 8:43 AM, Nikita Popovwrote: > 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. > Being lazy here because I'm literally on my way out the door and don't have a moment to parse through the implementation, but can you clarify how this impact compile-time declares? http://www.php.net/unsub.php
[PHP-DEV] [RFC] Namespace-scoped declares, again
Hi internals! 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. Thanks, Nikita