Welcome! Log In Create A New Profile

Advanced

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

Posted by Nikita Popov 
Nikita Popov
[PHP-DEV] [RFC] Namespace-scoped declares, again
December 11, 2017 02:50PM
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
Sara Golemon
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 11, 2017 04:50PM
On Mon, Dec 11, 2017 at 8:43 AM, Nikita Popov <[email protected]> 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?

<?php

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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Mark Randall
[PHP-DEV] Re: [RFC] Namespace-scoped declares, again
December 11, 2017 05:00PM
On 11/12/2017 13:43, Nikita Popov wrote:
> 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().

Seems solid to me, I would definitely make use of this feature, as I
found adding the declare to each file felt untidy and even a little clumsy.

I certainly like the direction that PHP seems to be moving in terms of
making the script structure more like a compiled application, rather
than a set of independent scripts.

If this doesn't pass, long term I think the main alternative would be to
have a single statement that was like a quasi-include of declarations in
another file, almost like a ".h"

declare_import('/my/namespace/nsprefs.php');

--
Mark Randall

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Nikita Popov
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 11, 2017 05:00PM
On Mon, Dec 11, 2017 at 4:46 PM, Sara Golemon <[email protected]> wrote:

> On Mon, Dec 11, 2017 at 8:43 AM, Nikita Popov <[email protected]>
> 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?
>
> <?php
>
> 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
Stanislav Malyshev
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 12, 2017 08:50AM
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
smalyshev@gmail.com

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Nikita Popov
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 12, 2017 02:50PM
On Tue, Dec 12, 2017 at 8:46 AM, Stanislav Malyshev <[email protected]>
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
Christoph M. Becker
[PHP-DEV] Re: [RFC] Namespace-scoped declares, again
December 12, 2017 05:40PM
On 11.12.2017 at 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.

Generally I'm not keen on letting the language diverge via whatever
mechanism, but that has already happened and there seems to be some
further need, and the namespace scoped declares appear to be preferable
to per-file declares or even ini settings.

What I don't like about the present proposal is that it introduces a
proper function instead of a language construct. Is there a particular
reason for this design decision? Couldn't we add the namespace scoped
declares to the namespace declaration directly, e.g.

namespace Foo declare strict_types=1;

--
Christoph M. Becker

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Stanislav Malyshev
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 12:20AM
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
smalyshev@gmail.com

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Andreas Hennings
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 01:20AM
I agree with all of Stanislav's emails in this thread so far.

On 12 December 2017 at 14:43, Nikita Popov <[email protected]> wrote:
> On Tue, Dec 12, 2017 at 8:46 AM, Stanislav Malyshev <[email protected]>
> 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 "<?php.8.1" instead of "<?php"
opening tag.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Michał Brzuchalski
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 05:10AM
2017-12-13 1:16 GMT+01:00 Andreas Hennings <[email protected]>:

> I agree with all of Stanislav's emails in this thread so far.
>
> On 12 December 2017 at 14:43, Nikita Popov <[email protected]> wrote:
> > On Tue, Dec 12, 2017 at 8:46 AM, Stanislav Malyshev <[email protected]
> >
> > 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
<?php

namespace Acme\Animal declare(strict_types=1,another_option=0);
const CAT = 1;
function createCat() : Cat {}

A good reason for that is that we're not using namespace as a string in
function call which is more IDE friendly to refactor.
There is another good reason for that - some code generators/container
compilers etc. whatever else
uses one file for more than one class that means there would be still an
option to pack few namespaces in one
separate file like for. eg:

<?php

namespace Acme\Animal declare(strict_types=1) {
class Cat {}
}

namespace Another\Library { // <-- there is no declare for this namespace
class SomeClass {}
}

These are just my thoughts and they can be completely nonsense.
I think it might be also a good place to provide more info in a future.
I know PHP is not Java9 and I'm gratefull for that, but IMHO sometimes
there are good concepts,
like module info in module-info.java file with module exports and requires
and info about what it provides at all.

> 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 "<?php.8.1" instead of "<?php"
> opening tag.
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


--
regards / pozdrawiam,
--
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com
Andreas Hennings
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 05:30AM
On 13 December 2017 at 05:04, Michał Brzuchalski <[email protected]> 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
> <?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
Michał Brzuchalski
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 05:40AM
2017-12-13 5:24 GMT+01:00 Andreas Hennings <[email protected]>:

> On 13 December 2017 at 05:04, Michał Brzuchalski <[email protected]>
> 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
> > <?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:

<?php declare(strict_types=0);

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
Michał Brzuchalski
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 06:20AM
2017-12-13 5:38 GMT+01:00 Michał Brzuchalski <[email protected]>:

>
>
> 2017-12-13 5:24 GMT+01:00 Andreas Hennings <[email protected]>:
>
>> On 13 December 2017 at 05:04, Michał Brzuchalski <[email protected]>
>> 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:

<?php
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.
<?php

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.


>> 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
>> > <?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:
>
> <?php declare(strict_types=0);
>
> 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
Ivan Enderlin
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 07:40AM
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
Michał Brzuchalski
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 08:20AM
2017-12-13 6:04 GMT+01:00 Michał Brzuchalski <[email protected]>:

>
>
> 2017-12-13 5:38 GMT+01:00 Michał Brzuchalski <[email protected]>:
>
>>
>>
>> 2017-12-13 5:24 GMT+01:00 Andreas Hennings <[email protected]>:
>>
>>> On 13 December 2017 at 05:04, Michał Brzuchalski <[email protected]>
>>> 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:
>
> <?php
> 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.
> <?php
>
> 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
>>> > <?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:
>>
>> <?php declare(strict_types=0);
>>
>> 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
Tony Marston
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 11:40AM
"Andreas Hennings" wrote in message
news:[email protected]om...
>
>I agree with all of Stanislav's emails in this thread so far.
>
>On 12 December 2017 at 14:43, Nikita Popov <[email protected]> wrote:
>> On Tue, Dec 12, 2017 at 8:46 AM, Stanislav Malyshev <[email protected]>
>> wrote:
>>
<snip>
>
>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
Tony Marston
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 11:50AM
""Michal Brzuchalski"" wrote in message
news:CABdc3WpomNLz+vX_m0B0wQ3uCiMiw[email protected]
>
>2017-12-13 1:16 GMT+01:00 Andreas Hennings <[email protected]>:
>
<snip>
>
>Why? Because users use PSR-4 so then they're src folder looks more like:
?
<snip>

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
Michał Brzuchalski
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 02:30PM
13.12.2017 11:44 "Tony Marston" <[email protected]> napisał(a):

""Michal Brzuchalski"" wrote in message news:CABdc3WpomNLz+vX_m0B0wQ3u
CiMiw8xw4Ea_sGD-PTDGfV-PbA@mail.gmail.com...


> 2017-12-13 1:16 GMT+01:00 Andreas Hennings <[email protected]>:
>
> <snip>


> Why? Because users use PSR-4 so then they're src folder looks more like:
>
?
<snip>

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
Tony Marston
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 13, 2017 03:00PM
""Michal Brzuchalski"" wrote in message
news:[email protected]om...
>
>13.12.2017 11:44 "Tony Marston" <[email protected]> napisal(a):
>
>""Michal Brzuchalski"" wrote in message news:CABdc3WpomNLz+vX_m0B0wQ3u
>[email protected]
>
>
>> 2017-12-13 1:16 GMT+01:00 Andreas Hennings <[email protected]>:
>>
>> <snip>
>
>
>> Why? Because users use PSR-4 so then they're src folder looks more like:
>>
>?
><snip>
>
>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
Rowan Collins
Re: [PHP-DEV] [RFC] Namespace-scoped declares, again
December 19, 2017 09:30PM
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
Sorry, only registered users may post in this forum.

Click here to login