Hi all,
Since we have discussion for Next PHP, "PHP" namespace discussion would be
nice
to have.
Currently, PHP module functions/classes/interfaces are using global(root)
namespace.
If it is changed to use its own namespace, user space APIs may be changed
flexible and user controlled manner. Thus, PHP may have
- Consistent naming
- Consistent parameter order
- Graceful function/class/interface deprecation
(We know what we should do for these, right?)
without much compatibility issues.
"PHP" namespace may be used to provide PHP(and 3rd party)
functions/classes/interfaces/constants.
"PHP\Legacy" (or whatever) may be used for legacy
functions/classes/interfaces/constants.
From PHP 5.6, userland function aliasing can be done with namespace.
Following code overrides existing function.
<?php
use function \mb_strlen as strlen;
var_dump(strlen('日本語'));
?>
Result:
int(3)
It's good to use prefered API, but it requires "use" for every function
APIs to be overridden.
Note: Classes/Interfaces may override by "use" one by one also.
With "PHP" and "PHP\Legacy" namespace, user may write:
<?php
namespace PHP; // Use current PHP functions/classes/interfaces/constants
// Code uses current API
?>
<?php
namespace PHP;
namespace PHP\Legacy; // Override with legacy PHP
functions/classes/interfaces/constants.
// Code uses legacy API
?>
For compatibility, default namespace setting would be nice to have.
- None for compiled default
- "PHP" for php.ini-*
Previous example codes became:
<?php
// Code uses current API
?>
<?php
namespace PHP\Legacy; // Override with legacy PHP
functions/classes/interfaces/constants.
// Code uses legacy API
?>
Issue would be codes that assume PHP functions/classes/interfaces/constants
are
defined in global(root) namespace. (e.g. \strlen()) This could be
workaround by allowing
"use" aliasing to global(root) namespace. (e.g. "use PHP\Legacy as ;") In
this case,
current functions/classes/interfaces may stay in global(root) namespace.
(or "use PHP as ;")
Programmers may shoot their own foot by this. This is the trade off of
flexibility.
Any thoughts and/or comments?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi,
Hi all,
Since we have discussion for Next PHP, "PHP" namespace discussion would be
nice
to have.Currently, PHP module functions/classes/interfaces are using global(root)
namespace.
If it is changed to use its own namespace, user space APIs may be changed
flexible and user controlled manner. Thus, PHP may have
- Consistent naming
- Consistent parameter order
- Graceful function/class/interface deprecation
(We know what we should do for these, right?)without much compatibility issues.
"PHP" namespace may be used to provide PHP(and 3rd party)
functions/classes/interfaces/constants.
"PHP\Legacy" (or whatever) may be used for legacy
functions/classes/interfaces/constants.From PHP 5.6, userland function aliasing can be done with namespace.
Following code overrides existing function.<?php
use function \mb_strlen as strlen;
var_dump(strlen('日本語'));
?>Result:
int(3)It's good to use prefered API, but it requires "use" for every function
APIs to be overridden.
Note: Classes/Interfaces may override by "use" one by one also.With "PHP" and "PHP\Legacy" namespace, user may write:
<?php
namespace PHP; // Use current PHP functions/classes/interfaces/constants// Code uses current API
?><?php
namespace PHP;
namespace PHP\Legacy; // Override with legacy PHP
functions/classes/interfaces/constants.// Code uses legacy API
?>For compatibility, default namespace setting would be nice to have.
- None for compiled default
- "PHP" for php.ini-*
Previous example codes became:
<?php
// Code uses current API
?><?php
namespace PHP\Legacy; // Override with legacy PHP
functions/classes/interfaces/constants.
// Code uses legacy API
?>Issue would be codes that assume PHP functions/classes/interfaces/constants
are
defined in global(root) namespace. (e.g. \strlen()) This could be
workaround by allowing
"use" aliasing to global(root) namespace. (e.g. "use PHP\Legacy as ;") In
this case,
current functions/classes/interfaces may stay in global(root) namespace.
(or "use PHP as ;")Programmers may shoot their own foot by this. This is the trade off of
flexibility.Any thoughts and/or comments?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
This would be a major BC break, that couldn't possibly happen in PHP
5.x and IMO is way too radical even for PHP 6/7.
I generally hate to see statements like "this is not the PHP way", but
that's exactly the case with your proposal - it enforces a more
strict way of programming. One must absolutely not be required to use
namespaces for everything.
Cheers,
Andrey.
One must absolutely not be required to use
namespaces for everything.
+1
I fully share this statement as well.
Please, do not force any user to use namespaces.
PHP's never been namespace based, it added their support to 5.3.
IMO, PHP should never be namespace based for its own syntax.
Julien.P
Hi Andrey,
This would be a major BC break, that couldn't possibly happen in PHP
5.x and IMO is way too radical even for PHP 6/7.
It wouldn't be major BC, but minor.
Most compatible way is to allow namespace alias to \ (root) and simply
override
existing functions. There isn't BC with this. PHP allows it already when it
is done
one by one.
If we would like to have clean \ (root) namespace optionally, it's matter
of adding
a setting.
What make you think it a major BC?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi,
Hi Andrey,
This would be a major BC break, that couldn't possibly happen in PHP
5.x and IMO is way too radical even for PHP 6/7.It wouldn't be major BC, but minor.
Most compatible way is to allow namespace alias to \ (root) and simply
override
existing functions. There isn't BC with this. PHP allows it already when it
is done
one by one.If we would like to have clean \ (root) namespace optionally, it's matter of
adding
a setting.What make you think it a major BC?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
If you'd alias the root namespace to \php or whatever, what's the
point in all of it?
I don't see such, so I assumed that you meant to require developers to
explicitly import whatever they need in the root namespace. And that
would be a major BC break.
Cheers,
Andrey.
Hi all,
Since we have discussion for Next PHP, "PHP" namespace discussion would be
nice
to have.Currently, PHP module functions/classes/interfaces are using global(root)
namespace.
If it is changed to use its own namespace, user space APIs may be changed
flexible and user controlled manner. Thus, PHP may have
- Consistent naming
- Consistent parameter order
- Graceful function/class/interface deprecation
(We know what we should do for these, right?)without much compatibility issues.
"PHP" namespace may be used to provide PHP(and 3rd party)
functions/classes/interfaces/constants.
"PHP\Legacy" (or whatever) may be used for legacy
functions/classes/interfaces/constants.From PHP 5.6, userland function aliasing can be done with namespace.
Following code overrides existing function.<?php
use function \mb_strlen as strlen;
var_dump(strlen('日本語'));
?>Result:
int(3)It's good to use prefered API, but it requires "use" for every function
APIs to be overridden.
Note: Classes/Interfaces may override by "use" one by one also.With "PHP" and "PHP\Legacy" namespace, user may write:
<?php
namespace PHP; // Use current PHP functions/classes/interfaces/constants// Code uses current API
?><?php
namespace PHP;
namespace PHP\Legacy; // Override with legacy PHP
functions/classes/interfaces/constants.// Code uses legacy API
?>For compatibility, default namespace setting would be nice to have.
- None for compiled default
- "PHP" for php.ini-*
Previous example codes became:
<?php
// Code uses current API
?><?php
namespace PHP\Legacy; // Override with legacy PHP
functions/classes/interfaces/constants.
// Code uses legacy API
?>Issue would be codes that assume PHP functions/classes/interfaces/constants
are
defined in global(root) namespace. (e.g. \strlen()) This could be
workaround by allowing
"use" aliasing to global(root) namespace. (e.g. "use PHP\Legacy as ;") In
this case,
current functions/classes/interfaces may stay in global(root) namespace.
(or "use PHP as ;")Programmers may shoot their own foot by this. This is the trade off of
flexibility.Any thoughts and/or comments?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
hi,
I think it would make sense to announce that the php namespace is reserved
for internal use, but I don't think that we are ready for moving everything
under namespaces.
The way we currently implement namespaces can't support wildcard imports so
the migration for project would be pretty tedious, finding and replacing
every occurance of a global function/class or use-ing every function/class,
etc.
namespaces has a bit clunky way of supporting constants: define always
assumes global ns(and the const syntax only allows scalar values so it
isn't always an option to use const).
moving the functions to namespaces would be also a bit weird for me, as we
currently don't support function (and const) autoloading, so it would be a
mixed message about whether or not do we consider functions and constants
first-class citizens used together with the later introduced oop features.
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
Hi all,
Since we have discussion for Next PHP, "PHP" namespace discussion would
be
nice
to have.Currently, PHP module functions/classes/interfaces are using global(root)
namespace.
If it is changed to use its own namespace, user space APIs may be changed
flexible and user controlled manner. Thus, PHP may have
- Consistent naming
- Consistent parameter order
- Graceful function/class/interface deprecation
(We know what we should do for these, right?)without much compatibility issues.
"PHP" namespace may be used to provide PHP(and 3rd party)
functions/classes/interfaces/constants.
"PHP\Legacy" (or whatever) may be used for legacy
functions/classes/interfaces/constants.From PHP 5.6, userland function aliasing can be done with namespace.
Following code overrides existing function.<?php
use function \mb_strlen as strlen;
var_dump(strlen('日本語'));
?>Result:
int(3)It's good to use prefered API, but it requires "use" for every function
APIs to be overridden.
Note: Classes/Interfaces may override by "use" one by one also.With "PHP" and "PHP\Legacy" namespace, user may write:
<?php
namespace PHP; // Use current PHP functions/classes/interfaces/constants// Code uses current API
?><?php
namespace PHP;
namespace PHP\Legacy; // Override with legacy PHP
functions/classes/interfaces/constants.// Code uses legacy API
?>For compatibility, default namespace setting would be nice to have.
- None for compiled default
- "PHP" for php.ini-*
Previous example codes became:
<?php
// Code uses current API
?><?php
namespace PHP\Legacy; // Override with legacy PHP
functions/classes/interfaces/constants.
// Code uses legacy API
?>Issue would be codes that assume PHP
functions/classes/interfaces/constants
are
defined in global(root) namespace. (e.g. \strlen()) This could be
workaround by allowing
"use" aliasing to global(root) namespace. (e.g. "use PHP\Legacy as ;")
In
this case,
current functions/classes/interfaces may stay in global(root) namespace.
(or "use PHP as ;")Programmers may shoot their own foot by this. This is the trade off of
flexibility.Any thoughts and/or comments?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.nethi,
I think it would make sense to announce that the php namespace is reserved
for internal use, but I don't think that we are ready for moving everything
under namespaces.
For what it's worth, the manual already states that the "php" namespace is
reserved for us.[1]
The way we currently implement namespaces can't support wildcard imports so
the migration for project would be pretty tedious, finding and replacing
every occurance of a global function/class or use-ing every function/class,
etc.
namespaces has a bit clunky way of supporting constants: define always
assumes global ns(and the const syntax only allows scalar values so it
isn't always an option to use const).
moving the functions to namespaces would be also a bit weird for me, as we
currently don't support function (and const) autoloading, so it would be a
mixed message about whether or not do we consider functions and constants
first-class citizens used together with the later introduced oop features.--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
[1] http://php.net/manual/en/language.namespaces.rationale.php
On Mon, Jul 28, 2014 at 10:49 AM, Peter Cowburn petercowburn@gmail.com
wrote:
Hi all,
Since we have discussion for Next PHP, "PHP" namespace discussion would
be
nice
to have.Currently, PHP module functions/classes/interfaces are using
global(root)
namespace.
If it is changed to use its own namespace, user space APIs may be
changed
flexible and user controlled manner. Thus, PHP may have
- Consistent naming
- Consistent parameter order
- Graceful function/class/interface deprecation
(We know what we should do for these, right?)without much compatibility issues.
"PHP" namespace may be used to provide PHP(and 3rd party)
functions/classes/interfaces/constants.
"PHP\Legacy" (or whatever) may be used for legacy
functions/classes/interfaces/constants.From PHP 5.6, userland function aliasing can be done with namespace.
Following code overrides existing function.<?php
use function \mb_strlen as strlen;
var_dump(strlen('日本語'));
?>Result:
int(3)It's good to use prefered API, but it requires "use" for every function
APIs to be overridden.
Note: Classes/Interfaces may override by "use" one by one also.With "PHP" and "PHP\Legacy" namespace, user may write:
<?php
namespace PHP; // Use current PHP functions/classes/interfaces/constants// Code uses current API
?><?php
namespace PHP;
namespace PHP\Legacy; // Override with legacy PHP
functions/classes/interfaces/constants.// Code uses legacy API
?>For compatibility, default namespace setting would be nice to have.
- None for compiled default
- "PHP" for php.ini-*
Previous example codes became:
<?php
// Code uses current API
?><?php
namespace PHP\Legacy; // Override with legacy PHP
functions/classes/interfaces/constants.
// Code uses legacy API
?>Issue would be codes that assume PHP
functions/classes/interfaces/constants
are
defined in global(root) namespace. (e.g. \strlen()) This could be
workaround by allowing
"use" aliasing to global(root) namespace. (e.g. "use PHP\Legacy as
;") In
this case,
current functions/classes/interfaces may stay in global(root) namespace.
(or "use PHP as ;")Programmers may shoot their own foot by this. This is the trade off of
flexibility.Any thoughts and/or comments?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.nethi,
I think it would make sense to announce that the php namespace is reserved
for internal use, but I don't think that we are ready for moving
everything
under namespaces.For what it's worth, the manual already states that the "php" namespace is
reserved for us.[1]
hehe, was trying to check that before sending the mail, but couldn't find
it, thanks!
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
I think it would make sense to announce that the php namespace is reserved
for internal use, but I don't think that we are ready for moving everything
under namespaces.
http://php.net/manual/en/userlandnaming.php could indeed do with some
updates!
cheers,
Derick
Hi Ferenc,
namespaces has a bit clunky way of supporting constants: define always
assumes global ns(and the const syntax only allows scalar values so it
isn't always an option to use const).
define()
is problem because it's an exception.
Possible solution might be "make define()
ed constants aware namespace and
allow importing
them to \ (root)".
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
If it is changed to use its own namespace, user space APIs may be changed
flexible and user controlled manner. Thus, PHP may have
- Consistent naming
- Consistent parameter order
- Graceful function/class/interface deprecation
(We know what we should do for these, right?)without much compatibility issues.
I really don’t like this idea. This has been suggested already for the primitive type (string and array) functions. However, I must concur with Nikita when I say that I’d much rather write $foo->split() than string\split($foo). See: http://nikic.github.io/2014/03/14/Methods-on-primitive-types-in-PHP.html
Introducing a load of aliases in namespaces might lead to consistency, sure, but now there’s more characters you need to type, and aside from consistency there’s not that much benefit.
Andrea Faulds
http://ajf.me/
If it is changed to use its own namespace, user space APIs may be changed
flexible and user controlled manner. Thus, PHP may have
- Consistent naming
- Consistent parameter order
- Graceful function/class/interface deprecation
(We know what we should do for these, right?)
I do not support it for consistent naming or parameter order by
themselves; this would likely create more confusion.
However I see value in creating new APIs for certain operations such
as sorting, mapping, reducing and filtering. These new APIs could work
on both arrays and traversables and provide a more cohesive API. This
would 'fix' several bug reports dealing with array functions that you
can't pass traversables or array-like objects to where you would
reasonably expect to be able to. When creating these functions we
could be careful to create consistent naming conventions and
consistent parameter orders, but again I consider this a side-effect
rather than a reason.
Yasuo Ohgaki wrote (on 28/07/2014):
- Consistent naming
- Consistent parameter order
- Graceful function/class/interface deprecation
(We know what we should do for these, right?)
I'm not sure if this was meant sincerely, or slightly tongue-in-cheek,
but no, we definitely don't. It comes up on the list every few months
(I've only been subscribed a short time, but this is at least the 4th
time I've seen), and the general conclusion is there isn't an easy
answer, and that adding more namespaces doesn't particularly help.
Making small changes, such as extra function aliases, or identical
versions of existing functions with switched parameter order, just adds
to the overall confusion and list of special cases that users have to
carry around when reading and writing code.
That leaves the option of making larger changes, to design a clear new
API, deliberately minimising the similarity to existing functions so
it's clear when you're using what. The popular option for that is
migrating chunks of functionality to OOP (as with DateTime), and to
pseudo-OOP "scalar methods" (of which there are a couple of prototypes)
- not to turn PHP into a pure OOP language, just to give us a chance to
design a more consistent library of functions.
Regards,
Rowan Collins
[IMSoP]
Hi all,
On Wed, Jul 30, 2014 at 9:35 PM, Rowan Collins rowan.collins@gmail.com
wrote:
- Consistent naming
- Consistent parameter order
- Graceful function/class/interface deprecation
(We know what we should do for these, right?)I'm not sure if this was meant sincerely, or slightly tongue-in-cheek, but
no, we definitely don't. It comes up on the list every few months (I've
only been subscribed a short time, but this is at least the 4th time I've
seen), and the general conclusion is there isn't an easy answer, and that
adding more namespaces doesn't particularly help.
One of the discussion is mine, I suppose.
This is because cleaning up API cannot be done w/o breaking some except
simple aliasing.
Even if there are issues in API, there isn't a consensus for feasible
resolution yet.
Namespace is good resolution obviously. It accomplishes compatibility and
consistency at the same time
even when parameters or class/interface definitions are changed.
Making small changes, such as extra function aliases, or identical
versions of existing functions with switched parameter order, just adds to
the overall confusion and list of special cases that users have to carry
around when reading and writing code.
We make small changes in versions always. API changes are small changes
also.
The difference is BC. Since API change breaks APP, it wasn't changed for a
long time.
Use of alias was proposed several times, but it wasn't optimum and couldn't
reach to consensus.
With namespace, user may choose. We don't force users to new or old
way. There is no BC issue.
It's users' choice. If we care about confusion, we may change API only with
major release to minimize it.
That leaves the option of making larger changes, to design a clear new API,
deliberately minimising the similarity to existing functions so it's
clear when you're using what. The popular option for that is migrating
chunks of functionality to OOP (as with DateTime), and to pseudo-OOP
"scalar methods" (of which there are a couple of prototypes) - not to turn
PHP into a pure OOP language, just to give us a chance to design a more
consistent library of functions.
Unless we rewrite everything completely, it wouldn't be accomplished. This
has been said for years
(more than a decade AFAIK) and didn't happen. Therefore, new API is not
feasible by history.
Even when we rewrite everything, are we going to remove old API? It's BC,
so I guess not. Most
legacy/obscure API will remain as it is now and usable by default.
New API doesn't help some time. For example, SessionHandlerInterface has
some variations and
has issue for adding to it. Instead having many SessionHandlerXXXInterface,
simply selecting
proper namespace is simpler/cleaner. Having new Session2 class only for
simpler interface name
does not make sense.
Since we don't have new major release often, it would be good for users
cleaning up API with every
new major versions. Otherwise, legacy/obscure APIs will remain 10 years or
even 20 years later for sure.
(In fact, we have legacy APIs almost 20 years that are used commonly)
Use of namespace guarantees new PHP has consistent/modern API. This will
neutralize/negate all cons, IMO.
cons are
- New php.ini (default namesapce setting)
- Legacy API can be used and remains (this is pros also)
- Confusing to current users by having versions of API. (confusing API is
confusing for both new and current users, too)
If there are more cons, please add them.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
On Wed, Jul 30, 2014 at 9:35 PM, Rowan Collins
<rowan.collins@gmail.com mailto:rowan.collins@gmail.com> wrote:Making small changes, such as extra function aliases, or identical versions of existing functions with switched parameter order, just adds to the overall confusion and list of special cases that users have to carry around when reading and writing code.
We make small changes in versions always. API changes are small
changes also.
The difference is BC. Since API change breaks APP, it wasn't changed
for a long time.
Use of alias was proposed several times, but it wasn't optimum and
couldn't reach to consensus.
When we talk about compatibility of an API, we are normally talking
about how an existing piece of code connects to another program,
library, or service. But when you're talking about the core functions of
a language, the consumer of that API is the programmer themselves, when
writing new code and reading old.
One of the problems which we would like to fix is that pogrammers have
to stop and think "Does array_map take the array first, or the
callback?" Because there isn't a good rule of thumb, each function has
to be remembered or looked up individually.
I have previously been tempted by the thought of adding a new set of
functions with a clearer design, but on reflection, I realise that you
just end up making the problem worse: now the programmer has to ask
themselves extra questions, like "Does PHP\Array\map take the arguments
in the same order as array_map? Which am I supposed to be using in this
project?"
Add in namespace aliasing, or a magic ini setting that hides the old
functions and puts the new ones in their place, and reading code becomes
equally confusing: "When it says array_map here, is that the classic PHP
function, or a new version aliased in? What differences are there
between the two?"
With namespace, user may choose. We don't force users to new or
old way.
Individual users can't choose, because they will be contributing to
projects - be they open source or commercial - with coding standards
based on the platforms supported, the size of the existing code base,
and the prejudices of project leaders. And the current trend in open
source projects is towards more co-operation and standardisation (e.g.
PHP-FIG), so adding a new thing to disagree on would be unfortunate to
say the least.
If we care about confusion, we may change API only with major release
to minimize it.
I can't imagine an API change of that sort being even considered outside
of a major release.
Unless we rewrite everything completely, it wouldn't be accomplished.
This has been said for years
(more than a decade AFAIK) and didn't happen. Therefore, new API is
not feasible by history.
So what is it you suggest instead? A series of namespaces with slightly
different versions of all the functions, introduced over time, and every
file having to declare at the top "use PHP7;", "use PHP8;" etc?
Use of namespace guarantees new PHP has consistent/modern API. This
will neutralize/negate all cons, IMO.
I'm really not sure what problems adding one or more namspaces solves.
If you just arrange the existing functions into namespaces with better
naming conventions, then it's just the same as any other set of aliases;
it's clear which are the "old" names and which the "new", but that's
about the only benefit. If you make the functions superficially similar,
but with minor changes like argument order or error-handling, then the
cost of adoption is even higher.
Coding standards are unlikely to accept a mixing of old and new styles
in one project, and bulk conversion of existing code is only possible if
you drop support for older PHP versions. So in order to adopt the new
functions at all, programmers would have to learn both APIs, and
remember the differences between them when switching projects. More
likely, they would simply carry on using the old functions even in new
projects, because the benefit of a slightly better parameter order here
and there wouldn't be worth the cost of learning it.
Further, if a magic ini setting could change which set of functions is
in scope, then distributing code libraries becomes a nightmare. Some
libraries include code to work around the ability to overwrite strlen()
with mb_strlen()
, meaning there's no safe function for getting the
number of bytes in a string, and this would be much more far-reaching.
The reason I think major changes are less likely to fail than minor ones
is that you can avoid the confusion of which version is which, and offer
a much stronger benefit to adopting the new style. For instance, "scalar
methods" are both very distinct from existing code, and naturally give
actions a "subject", e.g. $a = [1,3,2]; $a->map($callback); They have
the inherent attraction (for some people) of giving code an OO flavour.
But even then, there is a possibility of a schism in the language, with
some projects opting to stick to compatible, familiar, functions and
others moving to the modern-looking, redesigned, API. And that's
definitely not something I want to see.
Regards,
--
Rowan Collins
[IMSoP]
Hi Rowan,
On Mon, Aug 18, 2014 at 12:28 AM, Rowan Collins rowan.collins@gmail.com
wrote:
On Wed, Jul 30, 2014 at 9:35 PM, Rowan Collins <rowan.collins@gmail.com
mailto:rowan.collins@gmail.com> wrote:
Making small changes, such as extra function aliases, or identical versions of existing functions with switched parameter order, just adds to the overall confusion and list of special cases that users have to carry around when reading and writing code.
We make small changes in versions always. API changes are small changes
also.
The difference is BC. Since API change breaks APP, it wasn't changed for
a long time.
Use of alias was proposed several times, but it wasn't optimum and
couldn't reach to consensus.When we talk about compatibility of an API, we are normally talking about
how an existing piece of code connects to another program, library, or
service. But when you're talking about the core functions of a language,
the consumer of that API is the programmer themselves, when writing new
code and reading old.One of the problems which we would like to fix is that pogrammers have to
stop and think "Does array_map take the array first, or the callback?"
Because there isn't a good rule of thumb, each function has to be
remembered or looked up individually.I have previously been tempted by the thought of adding a new set of
functions with a clearer design, but on reflection, I realise that you just
end up making the problem worse: now the programmer has to ask themselves
extra questions, like "Does PHP\Array\map take the arguments in the same
order as array_map? Which am I supposed to be using in this project?"
Add in namespace aliasing, or a magic ini setting that hides the old
functions and puts the new ones in their place, and reading code becomes
equally confusing: "When it says array_map here, is that the classic PHP
function, or a new version aliased in? What differences are there between
the two?"
I'm not intended to divide global name space into parts.
Current(most updated API) namespace and legacy(older API) namespace would
be enough. Namespace may have version. (5, 7, and so on)
Therefore, user would not confuse like you describe.
For example, when a library major version incremented, API may differ.
Users may use new or old API selectively. I would like to have a choice to
use cleaner API or older API like library API.
If we divide namespace into pieces and change API frequently (i.e with
minor or bugfix version up), then it's confusing for sure. I'll against
such usage.
With namespace, user may choose. We don't force users to new or old
way.
Individual users can't choose, because they will be contributing to
projects - be they open source or commercial - with coding standards based
on the platforms supported, the size of the existing code base, and the
prejudices of project leaders. And the current trend in open source
projects is towards more co-operation and standardisation (e.g. PHP-FIG),
so adding a new thing to disagree on would be unfortunate to say the least.
Libraries/Projects may choose appropriate namespace (e.g. 5, 7, and so on)
like choosing specific library version mostly.
Issue would be if new PHP allows to import namespace into "" (root). Older
PHP would complain if default namespace is specified in scripts.
php > use PHP\5 as ;
Parse error: syntax error, unexpected '' (T_NS_SEPARATOR), expecting
identifier (T_STRING) in php shell code on line 1
and PHP does not have C like macro. I have to come up with solution for
this.
If we care about confusion, we may change API only with major release to
minimize it.
I can't imagine an API change of that sort being even considered outside
of a major release.Unless we rewrite everything completely, it wouldn't be accomplished.
This has been said for years
(more than a decade AFAIK) and didn't happen. Therefore, new API is not
feasible by history.So what is it you suggest instead? A series of namespaces with slightly
different versions of all the functions, introduced over time, and every
file having to declare at the top "use PHP7;", "use PHP8;" etc?
Yes. Something like this.
Since 'PHP' is reserved namespace name, "PHP\5", "PHP\7", "PHP\8" perhaps.
Use of namespace guarantees new PHP has consistent/modern API. This will
neutralize/negate all cons, IMO.
I'm really not sure what problems adding one or more namspaces solves.
If you just arrange the existing functions into namespaces with better
naming conventions, then it's just the same as any other set of aliases;
it's clear which are the "old" names and which the "new", but that's about
the only benefit. If you make the functions superficially similar, but with
minor changes like argument order or error-handling, then the cost of
adoption is even higher.
I like alias also and have proposed use of aliases before.
It may be good idea to use aliases as much as possible for simple name
changes.
Whole point of namespace use is to remove small inconsistency and/or
improper names (e.g. SessionHandlerInterface) with major release so that
small inconsistency would not be added up and have cleaner API for new
major versions.
Coding standards are unlikely to accept a mixing of old and new styles in
one project, and bulk conversion of existing code is only possible if you
drop support for older PHP versions. So in order to adopt the new functions
at all, programmers would have to learn both APIs, and remember the
differences between them when switching projects. More likely, they would
simply carry on using the old functions even in new projects, because the
benefit of a slightly better parameter order here and there wouldn't be
worth the cost of learning it.
Besides function/method name aliasing, changes in namespace would be small
enough to adopt/learn. New major release has long list of changes always.
Adding a few would not make much difference. IMHO.
Further, if a magic ini setting could change which set of functions is in
scope, then distributing code libraries becomes a nightmare. Some libraries
include code to work around the ability to overwritestrlen()
with
mb_strlen()
, meaning there's no safe function for getting the number of
bytes in a string, and this would be much more far-reaching.
PHP allows overriding strlen()
by mb_strlen()
, etc, with namespace already.
(Unless there is a function byte_len(), this would not be practical as you
mentioned. If "PHP" namespace is used, programmers may write
"PHP\5\strlen($str);", though.)
The reason I think major changes are less likely to fail than minor ones
is that you can avoid the confusion of which version is which, and offer a
much stronger benefit to adopting the new style. For instance, "scalar
methods" are both very distinct from existing code, and naturally give
actions a "subject", e.g. $a = [1,3,2]; $a->map($callback); They have the
inherent attraction (for some people) of giving code an OO flavour.
I like the idea and I'm +1 for this.
There is such RFC also.
https://wiki.php.net/rfc/autoboxing
BTW, I also preferred to keep procedural API. Everything does not have to
be an object and I would like to have choice (e.g MySQLi, session save
handler)
But even then, there is a possibility of a schism in the language, with
some projects opting to stick to compatible, familiar, functions and others
moving to the modern-looking, redesigned, API. And that's definitely not
something I want to see.
Using namespace for cleaning current API is just an idea.
I'll write a FRC when I came up with concrete idea and hope you like it.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Rowan,
On Mon, Aug 18, 2014 at 12:28 AM, Rowan Collins
<rowan.collins@gmail.com mailto:rowan.collins@gmail.com> wrote:I have previously been tempted by the thought of adding a new set of functions with a clearer design, but on reflection, I realise that you just end up making the problem worse: now the programmer has to ask themselves extra questions, like "Does PHP\Array\map take the arguments in the same order as array_map? Which am I supposed to be using in this project?" Add in namespace aliasing, or a magic ini setting that hides the old functions and puts the new ones in their place, and reading code becomes equally confusing: "When it says array_map here, is that the classic PHP function, or a new version aliased in? What differences are there between the two?"
I'm not intended to divide global name space into parts.
Current(most updated API) namespace and legacy(older API) namespace
would be enough. Namespace may have version. (5, 7, and so on)
Therefore, user would not confuse like you describe.
It doesn't matter if you have 1, 5, or zero namespaces, the problem is
having to learn more than one version of the same function.
If PHP\5\array_map and PHP\7\array_map took different arguments, the
language would be harder to learn, not easier.
For example, when a library major version incremented, API may differ.
Users may use new or old API selectively. I would like to have a
choice to use cleaner API or older API like library API.If we divide namespace into pieces and change API frequently (i.e with
minor or bugfix version up), then it's confusing for sure. I'll
against such usage.
I'm not sure what dividing the namespace into pieces has to do with
frequent updates. My feeling is that if you're going to go with
namespaces, you might as well actually use them to group functions, so
rather than PHP\array_map (or PHP\7\array_map) it could be PHP\Array\map
(or PHP\7\Array\map).
Individual users can't choose, because they will be contributing to projects - be they open source or commercial - with coding standards based on the platforms supported, the size of the existing code base, and the prejudices of project leaders. And the current trend in open source projects is towards more co-operation and standardisation (e.g. PHP-FIG), so adding a new thing to disagree on would be unfortunate to say the least.
Libraries/Projects may choose appropriate namespace (e.g. 5, 7, and so
on) like choosing specific library version mostly.
Yes, and users making use of and contributing to multiple projects will
have to learn both versions. Thus the more subtle variations there are
between the versions, the more they'll have to learn.
You also didn't respond to my point that introducing the extra choice
means one more barrier to smooth co-operation between projects.
Unless we rewrite everything completely, it wouldn't be accomplished. This has been said for years (more than a decade AFAIK) and didn't happen. Therefore, new API is not feasible by history. So what is it you suggest instead? A series of namespaces with slightly different versions of all the functions, introduced over time, and every file having to declare at the top "use PHP7;", "use PHP8;" etc?
Yes. Something like this.
Since 'PHP' is reserved namespace name, "PHP\5", "PHP\7", "PHP\8" perhaps.
This sounds like a recipe for massive confusion to me, for the reasons
I've already tried to explain.
Use of namespace guarantees new PHP has consistent/modern API. This will neutralize/negate all cons, IMO. I'm really not sure what problems adding one or more namspaces solves. If you just arrange the existing functions into namespaces with better naming conventions, then it's just the same as any other set of aliases; it's clear which are the "old" names and which the "new", but that's about the only benefit. If you make the functions superficially similar, but with minor changes like argument order or error-handling, then the cost of adoption is even higher.
I like alias also and have proposed use of aliases before.
It may be good idea to use aliases as much as possible for simple name
changes.Whole point of namespace use is to remove small inconsistency and/or
improper names (e.g. SessionHandlerInterface) with major release so
that small inconsistency would not be added up and have cleaner API
for new major versions.
You can make the changes without introducing namespaces, so saying that
the point of namespaces is to make changes makes no sense. I think what
you're getting at is that namespaces allow PHP to contain multiple
versions of the same function or class, which aren't simply aliases,
but have different behaviour in some way.
That provides a smoother upgrade path (or, at least, lets people put off
that upgrade), but it doesn't negate the problem of programmers having
to know both versions, or the huge amount of existing code examples
which won't work correctly under some environments because "use PHP\7;"
is in effect.
Incidentally, I'm not sure what the problem with SessionHandlerInterface
is, which you keep mentioning as an example.
Besides function/method name aliasing, changes in namespace would be
small enough to adopt/learn. New major release has long list of
changes always. Adding a few would not make much difference. IMHO.
It's quite hard to generalise about the changes in major releases, since
it's 10 years since the last one, and the project is in a very different
place than it was then. And as Derick pointed out in another thread,
it's very risky to go from "we can make such changes if necessary" to
"we can make as many changes as we feel like".
PHP allows overriding
strlen()
bymb_strlen()
, etc, with namespace
already. (Unless there is a function byte_len(), this would not be
practical as you mentioned. If "PHP" namespace is used, programmers
may write "PHP\5\strlen($str);", though.)
Yes, but the use of this makes code harder to read, and harder to
maintain. To design a feature aimed entirely at making a function name
mean different things in different files, and to do so in the name of
consistency and a clean API, seems counter-productive.
The reason I think major changes are less likely to fail than minor ones is that you can avoid the confusion of which version is which, and offer a much stronger benefit to adopting the new style. For instance, "scalar methods" are both very distinct from existing code, and naturally give actions a "subject", e.g. $a = [1,3,2]; $a->map($callback); They have the inherent attraction (for some people) of giving code an OO flavour.
I like the idea and I'm +1 for this.
There is such RFC also.
https://wiki.php.net/rfc/autoboxingBTW, I also preferred to keep procedural API. Everything does not have
to be an object and I would like to have choice (e.g MySQLi, session
save handler)
The point is not (necessarily) that "everything should be an object",
it's that a big visible change makes it obvious that the new API is
being used.
Using namespace for cleaning current API is just an idea.
I'll write a FRC when I came up with concrete idea and hope you like it.
Like I say, I used to think it would be a good idea, but now see it
introducing just as many problems as it solves.
--
Rowan Collins
[IMSoP]