Re: [PHP-DEV] [RFC] Namespace-scoped declares, again

2019-09-04 Thread Andreas Hennings
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

2019-08-14 Thread Michał Brzuchalski
ś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

2019-08-14 Thread Rowan Collins

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

2019-08-14 Thread Michał Brzuchalski
ś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

2019-08-14 Thread Rowan Collins

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

2019-08-14 Thread Michał Brzuchalski
ś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

2019-08-14 Thread Rowan Collins

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

2019-08-14 Thread Michał Brzuchalski
ś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

2019-08-14 Thread Rowan Collins

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

2019-08-14 Thread Rowan Collins

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

2019-08-14 Thread Michał Brzuchalski
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

2019-08-13 Thread Mark Randall

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

2019-08-13 Thread Rowan Collins

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

2019-08-13 Thread Rowan Collins

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

2019-08-13 Thread Stephen Reay



> 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

2019-08-13 Thread Mark Randall

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

2019-08-13 Thread Rowan Collins

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

2019-08-13 Thread Mark Randall

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

2019-08-13 Thread Rowan Collins

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

2019-08-12 Thread Michał Brzuchalski
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

2019-08-12 Thread Mark Randall

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

2019-08-12 Thread Larry Garfield
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

2019-08-12 Thread Thomas Nunninger

Hi,

Am 12.08.19 um 10:26 schrieb Nikita Popov:

On Mon, Aug 12, 2019 at 10:17 AM Nicolas Grekas <
nicolas.grekas+...@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

2019-08-12 Thread Stephen Reay


> 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

2019-08-12 Thread Michał Brzuchalski
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

2019-08-12 Thread 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:
> 
> 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

2019-08-12 Thread Nicolas Grekas
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

2017-12-19 Thread Rowan Collins

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

2017-12-13 Thread Tony Marston
""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

2017-12-13 Thread Michał Brzuchalski
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

2017-12-13 Thread Tony Marston
""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

2017-12-13 Thread Tony Marston
"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 Popov  wrote:

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-12 Thread Michał Brzuchalski
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

2017-12-12 Thread Ivan Enderlin

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-12 Thread 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:

> 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-12 Thread 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
>
> 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

2017-12-12 Thread 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?

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-12 Thread Michał Brzuchalski
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

2017-12-12 Thread 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.

> 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

2017-12-12 Thread Stanislav Malyshev
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

2017-12-12 Thread Nikita Popov
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. 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

2017-12-11 Thread Stanislav Malyshev
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

2017-12-11 Thread Nikita Popov
On Mon, Dec 11, 2017 at 4:46 PM, Sara Golemon  wrote:

> 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

2017-12-11 Thread Sara Golemon
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?

http://www.php.net/unsub.php



[PHP-DEV] [RFC] Namespace-scoped declares, again

2017-12-11 Thread Nikita Popov
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