Hi all,
Let me make this brief: there will be lots of complaining about the
namespace separator.
Stop. Now.
It serves no possible useful purpose. If you want to discuss why this
was chosen or suggest alternatives, feel free to write me off-list. I
would be more than happy to answer any questions about the technical
aspects of various choices. The decision is made, now I suggest
everyone get busy actually trying it out. You will very quickly
understand why it is a very viable choice.
Thanks,
Greg
Greg Beaver wrote:
The decision is made, now I suggest everyone get busy actually trying
it out.
How are we supposed to try it out? There is no updated implementation
yet, and I would rather discuss a specification instead.
It was mentioned on IRC that internal functions have to be prefixed with
\ when used in a namespaced file. Without a fallback. This is insane.
We should either disallow functions and constants in namespaces which,
as far as I understand the issue, got us into the trouble, or remove the
feature completely.
--
Sebastian Bergmann http://sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69
Greg Beaver wrote:
The decision is made, now I suggest everyone get busy actually trying
it out.How are we supposed to try it out? There is no updated implementation
yet, and I would rather discuss a specification instead.It was mentioned on IRC that internal functions have to be prefixed
with
\ when used in a namespaced file. Without a fallback. This is insane.We should either disallow functions and constants in namespaces which,
as far as I understand the issue, got us into the trouble, or remove
the
feature completely.
Sebastian, you have not participated in the discussion so far. Now you
post a rumor you picked up on IRC into an already heated situation.
You do know full well that it does not require you to point out that
this would indeed be problematic (since people who are participating
in this discussion are actually aware of this). So do us all the favor
and stop and think a second before you post the next time.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Lukas Kahwe Smith wrote:
On 26.10.2008, at 19:07, Sebastian Bergmann wrote:
Greg Beaver wrote:
The decision is made, now I suggest everyone get busy actually trying
it out.How are we supposed to try it out? There is no updated implementation
yet, and I would rather discuss a specification instead.It was mentioned on IRC that internal functions have to be prefixed with
\ when used in a namespaced file. Without a fallback. This is insane.We should either disallow functions and constants in namespaces which,
as far as I understand the issue, got us into the trouble, or remove the
feature completely.Sebastian, you have not participated in the discussion so far. Now you
post a rumor you picked up on IRC into an already heated situation. You
do know full well that it does not require you to point out that this
would indeed be problematic (since people who are participating in this
discussion are actually aware of this). So do us all the favor and stop
and think a second before you post the next time.
So now the decisions are done in IRC..? Didn't we once agree that that does not
work since not everyone is there all the time?
And I must agree with Sebastian: How do you test something that isn't even
implemented yet? :D
NOTE: I do not give a damn about namespaces as long as they're optional. :)
For me prefixing has been enough for quite a long time and I don't see the need
for this syntax sugar. ;)
--Jani
And I must agree with Sebastian: How do you test something that isn't even
implemented yet? :D
You apply the 'rough draft' patch against PHP_5_3 :D
http://pear.php.net/~greg/backslash.sep.patch.txt
As referenced in the original rfc for the backslash approach cited at
http://wiki.php.net/rfc/namespaceseparator.
- Steph
Hi Lukas,
Sebastian, you have not participated in the discussion so far. Now you post
a rumor you picked up on IRC into an already heated situation. You do know
full well that it does not require you to point out that this would indeed
be problematic (since people who are participating in this discussion are
actually aware of this). So do us all the favor and stop and think a second
before you post the next time.
Excuse me but while the idea to have an online meeting was great,
sending a mail to ask to attend an online meeting 24 hours before and
on a Friday was not a wised choice. I would have participated too if
it was during this week or the next weekend.
I do agree with Sebastian about not allowing functions and constants
(from a principle point of view, as I barely see any example out there
of NS and procedural code). I'd to say that I do not care about which
symbol is used.
@Greg and Steph: Private discussions are bad. Or are you trying to say
that this list can't be used as a discussion platform (even heated)?
If we like to have a developer only list, let do it, but keep things
in the public area, that's the only way to keep our decision process
transparent for everyone.
Cheers,
Pierre
Hi Lukas,
On Sun, Oct 26, 2008 at 11:28 AM, Lukas Kahwe Smith <mls@pooteeweet.org
wrote:
Sebastian, you have not participated in the discussion so far. Now
you post
a rumor you picked up on IRC into an already heated situation. You
do know
full well that it does not require you to point out that this would
indeed
be problematic (since people who are participating in this
discussion are
actually aware of this). So do us all the favor and stop and think
a second
before you post the next time.Excuse me but while the idea to have an online meeting was great,
sending a mail to ask to attend an online meeting 24 hours before and
on a Friday was not a wised choice. I would have participated too if
it was during this week or the next weekend.
Admittedly the meeting was mainly scheduled to allow Greg, Dmitry/Stas
and at least half a dozen (it was even more in the end) of core
developers that have spend time to follow the discussions and thought
processes to come together. We had the assumption that this was a
sufficiently large and competent group to make a decision on something
that many (including you) have said is important but where neither of
the choices spell doom for PHP, while still not being easy.
Now the people that were not able to attend this IRC meeting can
either accept that there was a sufficient number of people to make a
final decision on something that everybody (obviously also people who
did not attend the meeting) had plenty of time to make their concerns
heard or you can question this approach.
I do agree with Sebastian about not allowing functions and constants
(from a principle point of view, as I barely see any example out there
of NS and procedural code). I'd to say that I do not care about which
symbol is used.
Right, there are plenty people in both camps.
@Greg and Steph: Private discussions are bad. Or are you trying to say
that this list can't be used as a discussion platform (even heated)?
If we like to have a developer only list, let do it, but keep things
in the public area, that's the only way to keep our decision process
transparent for everyone.
As was evident from the discussions in the past weeks, a lot of people
commented, most of which did not spend the necessary time to actually
understand the issues at hand. Given that it did indeed make it
impossible to bring this topic to a conclusion on the list.
As for transparency, I see no issues. The decision process was
entirely transparent, albeit the final decision meeting was not open
to all. Again everybody that cares had weeks/months (actually years)
to bring up his POV. In the end there were 10 people (including both
RMs) that made a final decision and that are prepared to take the blame.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
As was evident from the discussions in the past weeks, a lot of people
commented, most of which did not spend the necessary time to actually
understand the issues at hand. Given that it did indeed make it impossible
to bring this topic to a conclusion on the list.As for transparency, I see no issues. The decision process was entirely
transparent, albeit the final decision meeting was not open to all. Again
everybody that cares had weeks/months (actually years) to bring up his POV.
In the end there were 10 people (including both RMs) that made a final
decision and that are prepared to take the blame.
To make my point more clear: I respect the decision even if I'm not
completely happy about it (that's what we call a compromise). But my
comment to Greg and Steph was about the danger of abusing of private
discussions not about having held this meeting on IRC.
--
Pierre
To make my point more clear: I respect the decision even if I'm not
completely happy about it (that's what we call a compromise). But my
comment to Greg and Steph was about the danger of abusing of private
discussions not about having held this meeting on IRC.
ok point taken.
we should indeed not get in a habit of this kind of decision making.
while none of us can prevent offlist discussions, we should also all
of course try to keep things onlist as much as possible. but its still
fine to talk things over to get things a bit more coherent before
posting to internals (in the spirit of signal to noise ratio).
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
To make my point more clear: I respect the decision even if I'm not
completely happy about it
As do I. So lets kill this thread, unless you want the cool slashdot
guys to post more FUD referencing this thread.
-Hannes
Lukas Kahwe Smith schrieb:
Now the people that were not able to attend this IRC meeting can
either accept that there was a sufficient number of people to make
a final decision on something that everybody (obviously also people
who did not attend the meeting) had plenty of time to make their
concerns heard or you can question this approach.
It eludes me how something can be discussed and be voted upon when the
only basis for discussion is the current implementation (that has no
specification).
--
Sebastian Bergmann http://sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69
On Mon, Oct 27, 2008 at 15:09, Sebastian Bergmann
sb@sebastian-bergmann.de wrote:
Lukas Kahwe Smith schrieb:
Now the people that were not able to attend this IRC meeting can
either accept that there was a sufficient number of people to make
a final decision on something that everybody (obviously also people
who did not attend the meeting) had plenty of time to make their
concerns heard or you can question this approach.It eludes me how something can be discussed and be voted upon when the
only basis for discussion is the current implementation (that has no
specification).
What exactly are you expecting other then the various wiki entries and
README.namespaces in CVS?
Stop being such a dick.
It is great that some project only thinks about specifications, and
cool UML diagrams and use cases and all the stuff you learned taking
your master, but never implement a single piece of code - or are so
seriously over engineered that are impossible to use.. but PHP has
been working fine using the trigger happy coding approach for the last
several years.
-Hannes
Hannes Magnusson schrieb:
What exactly are you expecting other then the various wiki entries
and README.namespaces in CVS?
Right, various sources of information that are not neccessarily in
sync and/or up to date.
--
Sebastian Bergmann http://sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69
Hi Pierre,
Excuse me but while the idea to have an online meeting was great,
sending a mail to ask to attend an online meeting 24 hours before and
on a Friday was not a wised choice. I would have participated too if
it was during this week or the next weekend.
You were actually online throughout it, and were notified that it was
happening at the start. In fact you were the first person to blog the
outcome of the meeting.
I do agree with Sebastian about not allowing functions and constants
(from a principle point of view, as I barely see any example out there
of NS and procedural code).
Apart from PEAR?
I'd to say that I do not care about which
symbol is used.@Greg and Steph: Private discussions are bad. Or are you trying to say
that this list can't be used as a discussion platform (even heated)?
If we like to have a developer only list, let do it, but keep things
in the public area, that's the only way to keep our decision process
transparent for everyone.
@Pierre: we didn't have a 'private discussion'. That this irc meeting was
going to take place was noted on internals@ over a week ago following my
'consultation excercise', which incidentally practically all the core devs
complained about due to the noise it generated. Only one internals dev
requested to be notified of the details when the information was made
public. Only one internals dev has complained that he wasn't invited, from
which it would seem that the rest really didn't want to go through it all
again, for one reason or another. It should also be noted that more were
invited than actually attended, yourself included.
The need for a dev-only discussion will I think become apparent if you look
at the detailed investigative reports Greg gave.
- Steph
Hi Pierre,
Excuse me but while the idea to have an online meeting was great,
sending a mail to ask to attend an online meeting 24 hours before and
on a Friday was not a wised choice. I would have participated too if
it was during this week or the next weekend.You were actually online throughout it, and were notified that it was
happening at the start. In fact you were the first person to blog the
outcome of the meeting.
"I'm" always online, bot/proxy.
I do agree with Sebastian about not allowing functions and constants
(from a principle point of view, as I barely see any example out there
of NS and procedural code).Apart from PEAR?
That's a new feature for a not released PHP version. The large part of
the pear code base is OO anyway.
@Pierre: we didn't have a 'private discussion'.
See my attempt to make this comment more clear.
The need for a dev-only discussion will I think become apparent if you look
at the detailed investigative reports Greg gave.
I tend to think that there is phases, some are more heat, other are
deadly quiet. Nothing that can really justify to create a larger wall
between our users and us, even if we sometimes like to silent some of
them :)
Cheers,
Pierre
Pierre Joye wrote:
@Greg and Steph: Private discussions are bad. Or are you trying to say
that this list can't be used as a discussion platform (even heated)?
If we like to have a developer only list, let do it, but keep things
in the public area, that's the only way to keep our decision process
transparent for everyone.
Hi Pierre,
Go ahead and attack my character if you feel it serves some purpose and
benefits PHP. I on the other hand will continue to post actual
solutions, patches and discuss them.
I stand by my obvious public intent with the multiple emails, RFCs and
patches I have sent. It's truly laughable to suggest that I have done
anything private when the truth is closer to a flood of internals with
public airing of ideas and patches :).
With regard to the namespace discussion, the decision has been made by
the RMs, and unless your intent is to undermine or reformulate the RM
process, I suggest we get in line behind Lukas and Johannes and instead
start talking about implementing the new separator or about other
unrelated issues in namespaces.
Thanks,
Greg
hi Greg,
Go ahead and attack my character if you feel it serves some purpose and
benefits PHP. I on the other hand will continue to post actual
solutions, patches and discuss them.
I'm not sure what's the hell is going on with you and Step, but if we
can't answer to any of your mails without being accused of personal
attacks, then it is going to be painful.
I do not think there is a need for further explanations of my point.
We are a OSS project, we should try to keep mails discussions on the
respective mailing lists. If that does not work anymore (noise ratio
too high or whatever else), then let find a solution instead of going
private for every second discussion.
Cheers,
Hi,
I'm not sure what's the hell is going on with you and Step,
OK, Pierre. You got us. Greg and I have been secret lovers for the last 5
years and we've been planning to take over php.net the whole of that time.
but if we
can't answer to any of your mails without being accused of personal
attacks, then it is going to be painful.
You made a personal attack in a very public space. There have been a lot
of technical discussions off-list, including most of the recent
Windows-related changes, but you pick on Greg and myself particularly - why,
pray?
- Steph
Greg Beaver schrieb:
I stand by my obvious public intent with the multiple emails, RFCs and
patches I have sent.
Just to make it clear: I appreciate your effort and work on namespaces,
but AFAICS there is no single/complete RFC, only bits and pieces
(problems with the current implementation, overview of alternative
separators).
--
Sebastian Bergmann http://sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69
Sebastian Bergmann wrote:
Greg Beaver wrote:
The decision is made, now I suggest everyone get busy actually trying
it out.How are we supposed to try it out? There is no updated implementation
yet, and I would rather discuss a specification instead.
As Steph pointed out, I toiled for about 18 hours to create a working
patch before the IRC meeting just to be sure there weren't any hidden
gotchas.
http://pear.php.net/~greg/backslash.sep.patch.txt
This patch is unreviewed by Zend Engine experts, and so should be
considered a proof of concept only and not a final implementation.
It was mentioned on IRC that internal functions have to be prefixed with
\ when used in a namespaced file. Without a fallback. This is insane.
This is not true, and the unit tests demonstrate that resolution in fact is:
- check for namespaced\functionname
- check for internal functionname
and the same is true for both constants and classes. In fact, the class
resolution is what it has always been
- check for namespaced\classname
- check for internal classname
- try to autoload namespaced\classname
which is planned to be changed to
- check for namespaced\classname
- try to autoload namespaced\classname
- check for internal classname
or even
- check for namespaced\classname
- try to autoload namespaced\classname
So not all details are completely nailed down, but these are independent
of whether \ or :: or &*@$#% is used as the separator, and would not
be fixed by removing functions and constants because the two issues have
nothing to do with one another.
Thanks,
Greg
Greg Beaver schrieb:
It was mentioned on IRC that internal functions have to be
prefixed with \ when used in a namespaced file. Without a fallback.This is not true, and the unit tests demonstrate that
Thank you for clearing this up.
- check for namespaced\functionname
- check for internal functionname
[...]- check for namespaced\classname
- try to autoload namespaced\classname
- check for internal classname
This is exactly what I would assume to happen; I am relieved.
So not all details are completely nailed down, but these are
independent of whether \ or :: or &*@$#% is used as the separator,
Honestly, I do not really care about the separator and I think that
is the best choice of the ones that were available.
--
Sebastian Bergmann http://sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69
Hi!
- check for namespaced\classname
- try to autoload namespaced\classname
- check for internal classname
That's the wrong way to do it - it means every time you mention the
internal class name without prefixing it with \ you get exhaustive
autoloading search and nothing tells you about it but sudden performance
drop in your application.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Stanislav Malyshev wrote:
Hi!
- check for namespaced\classname
- try to autoload namespaced\classname
- check for internal classname
That's the wrong way to do it - it means every time you mention the
internal class name without prefixing it with \ you get exhaustive
autoloading search and nothing tells you about it but sudden performance
drop in your application.
I agree with Stas. It's better to force people to actually reference
their classes/functions/constants correctly and get better performance
than getting unclear slowdowns.
On a side note, congratulations for identifying and addressing the
issues with namespaces before the release. Changing the separator was a
hard but wise decision. There's no perfect choice but it was best of all
IMO.
-- Rodrigo Saboya
2008/10/27 Rodrigo Saboya rodrigo.saboya@bolsademulher.com:
I agree with Stas. It's better to force people to actually reference their
classes/functions/constants correctly and get better performance than
getting unclear slowdowns.
If I'm not mistaken, you only experience any noticeable slowdown if
all of these conditions are met:
- you use an internal class many, many times (as the overhead from a
handful of invocations would be negligible) - you do implement __autoload(), that __autoload() accesses the
filesystem and the result is not cached (isn't there a stat cache?) or
that __autoload() performs some kind of computation-intensive
operation - you didn't reference the class using the global namespace (IOW, "new
PDO" instead of "new \PDO")
I'd expect people who execute that kind of code and care about
performance to know that referencing internal classes in the correct
namespace is more efficient. People who don't know the difference are
likely to run worse code than that anyway (eg LIKE '%foo%' queries,
in_array()
in a loop, and other common mistakes).
Perhaps the performance argument would have more weight if somebody
benchmarked the impact on an average application?
-JD
Hi!
- you use an internal class many, many times (as the overhead from a
handful of invocations would be negligible)
Actually, one time is enough, as it can bring an application from
essentially zero disk accesses (with bytecode caching) to multiple disk
accesses (to traverse full include path to exhaust all autoloading
capabilities).
- you do implement __autoload(), that __autoload() accesses the
filesystem and the result is not cached (isn't there a stat cache?) or
There's no negative autoloading cache.
- you didn't reference the class using the global namespace (IOW, "new
PDO" instead of "new \PDO")
That's how 100% of existing code is written, btw, and how 100% of
existing programmers are educated.
I'd expect people who execute that kind of code and care about
performance to know that referencing internal classes in the correct
namespace is more efficient. People who don't know the difference are
How they are supposed to know that? It doesn't give any error, it
doesn't give any indication anything is wrong. It's just slow. Expecting
all people to scrupulously study every note in the manual is
over-optimistic at best.
Perhaps the performance argument would have more weight if somebody
benchmarked the impact on an average application?
What's "average application"? There are no namespaced applications now.
But you can estimate it if you take big application, run it under
bytecode cache and on each use of internal class you insert, say, 5 disk
accesses.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
2008/10/27 Stanislav Malyshev stas@zend.com:
Actually, one time is enough, as it can bring an application from
essentially zero disk accesses (with bytecode caching) to multiple disk
accesses (to traverse full include path to exhaust all autoloading
capabilities).
So we're talking about an __autoload() that uses relative paths right?
That's how 100% of existing code is written, btw, and how 100% of existing
programmers are educated.
I'm not sure I understand your argument. First of all, as you pointed
out there is virtually no code out there using namespace so we can
only speculate about how programmers will be educated on namespaces.
Then, if we assume that most people will use the global namespace
without prefixing it, what would be the best resolution order for
them? (you didn't mention it in your previous message)
How they are supposed to know that?
People who care about performance are supposed to profile their
code... I guess? If they don't, they probably don't really care about
it. People who care about performance are supposed to be knowledgeable
about good practices.
It doesn't give any error, it doesn't
give any indication anything is wrong. It's just slow. Expecting all people
to scrupulously study every note in the manual is over-optimistic at best.
Include + relative path does not give any indication either and it
does exactly what you've described above (traverse the full include
path). Neither does in_array()
or the thousand other slow things we
can do with PHP. As I said I only expect people who care about
performance to study that kind of things. Wouldn't it be more
beneficial to the users to educate them on the performance
implications of using relative paths in __autoload() rather than base
the scope resolution on worst-case scenari?
What's "average application"? There are no namespaced applications now.
I'm thinking about taking any of Wordpress, phpBB, Drupal, etc... and
making them run in a namespace. Well, it would only work for those
that use __autoload(). With relative paths. Come to think of it, why
would an application autoload files that aren't in its directory?
That's what perplexes me the most about your position, I can't think
of real-life examples where the performance impact would be as bad as
you describe it.
-JD
Hi!
Then, if we assume that most people will use the global namespace
without prefixing it, what would be the best resolution order for
them? (you didn't mention it in your previous message)
Using the prefixed names.
People who care about performance are supposed to profile their
code... I guess? If they don't, they probably don't really care about
it. People who care about performance are supposed to be knowledgeable
about good practices.
I consider knowingly putting performance bomb into the language with the
reasoning of "if you know what you are doing, you can disarm it"
extremely bad idea, especially in PHP which is supposed to be
low-learning-curve language.
Include + relative path does not give any indication either and it
does exactly what you've described above (traverse the full include
Include can be cached. Failed autoload can't.
that use __autoload(). With relative paths. Come to think of it, why
would an application autoload files that aren't in its directory?
Because there exist applications that have more than one directory, use
all sorts of libraries and frameworks, which can have autoloading rules
not fit for the scenario when you try to load class which actually is
not meant to be loaded. How many of the loaders optimize for the
scenario that class can not be found? Not all of them even will survive
that.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
2008/10/27 Stanislav Malyshev stas@zend.com:
Then, if we assume that most people will use the global namespace
without prefixing it, what would be the best resolution order for
them? (you didn't mention it in your previous message)Using the prefixed names.
I'm sorry but I still don't get what's your "right" way to do it. For
reference, the "wrong" way is:
- check for namespaced\classname
- try to autoload namespaced\classname
- check for internal classname
How would you reorder those?
I consider knowingly putting performance bomb into the language with the
reasoning of "if you know what you are doing, you can disarm it" extremely
bad idea, especially in PHP which is supposed to be low-learning-curve
language.
You keep throwing that "performance bomb" thing even though there is
no benchmark about it. You are speculating that people will have huge
librairies with autoloads that search for files inside the
include_path. Is it wise to base the resolution order on those
speculations?
Include + relative path does not give any indication either and it
does exactly what you've described above (traverse the full includeInclude can be cached. Failed autoload can't.
...but didn't you say "one time is enough"? According to your own
logic, include is a "performance bomb" as well.
My point is that your base scenario is simply not realistic. Only the
biggest websites need to perform without touching the disk. Only some
very complicated framework will autoload classes outside of their
directory and attempt to traverse the include path for some reason.
Those are fringe cases, and all they need to do to perform efficiently
is prepend the class names with \ or fix their autoloader. On the
other hand, changing the resolution order to prefer internal classes
over autoloading induces a loss of functionality that can only be
fixed by explicitly including the needed files in advance, defeating
the purpose of an autoloader.
Anyway, I feel like I've made my point, the discussion isn't
progressing and my arguments have already been rehashed in past
discussions so I'll probably rest my case. Thanks for reading ;)
-JD
Hi!
- check for namespaced\classname
- try to autoload namespaced\classname
- check for internal classname
How would you reorder those?
- check for namespaced\classname
- try to autoload namespaced\classname
- fail
...but didn't you say "one time is enough"? According to your own
logic, include is a "performance bomb" as well.
You seem to not understand how bytecode caches work. With bytecode
caches, you can have zeto disk accesses per request.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
2008/10/27 Stanislav Malyshev stas@zend.com:
- check for namespaced\classname
- try to autoload namespaced\classname
- fail
Ok, that makes some sense wrt your position, which I originally
interpreted as namespace/internal/autoload.
You want to force users to use the full name at all times. IOW, you
want to sacrifice convenience for performance. On the upside, no
ambiguity whatsoever. "new Foo" is always a namespaced class. The
downside is that it makes it harder for users to copy/paste code from
current tutorials and examples, they will have to fix the class names.
Also, a few people will probably regret not being able to
auto-magically override some internal classes (e.g. override PDO to
log queries and what not) and it will probably increase the amount of
complaints about peppering one's code with backslashes.
...but didn't you say "one time is enough"? According to your own
logic, include is a "performance bomb" as well.You seem to not understand how bytecode caches work. With bytecode caches,
you can have zeto disk accesses per request.
I didn't know that bytecode caches could optimize includes with
relative paths...
You want to force users to use the full name at all times. IOW, you
want to sacrifice convenience for performance.
(chiming in because it seems that we're overlooking something obvious
here)
If it comes down to this, I'd prefer to see an E_NOTICE
for the "bad
performance" use, though I don't think it's necessary to shield users
from this. There's plenty of poorly performing PHP code out there that
an extra disk access isn't going to hurt.
S
You want to force users to use the full name at all times. IOW, you
want to sacrifice convenience for performance.(chiming in because it seems that we're overlooking something
obvious here)If it comes down to this, I'd prefer to see an
E_NOTICE
for the "bad
performance" use, though I don't think it's necessary to shield
users from this. There's plenty of poorly performing PHP code out
there that an extra disk access isn't going to hurt.
this seems like a very good idea to me. this way things default to
"just work" (which imho is the PHP spirit), while its brain dead easy
to detect misuse.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hi!
this seems like a very good idea to me. this way things default to "just
work" (which imho is the PHP spirit), while its brain dead easy to
detect misuse.
They not "just work" - they "work" in a wrong way (not usable in any
practical application). And E_NOTICE
is a non-solution here - if we
know that it's wrong enough to put a warning there, why we don't make it
right? Why should we put another thing to stumble upon - why people
should learn another gimmick "you can write it that way, but you never
should do it because it works badly". If they shouldn't write it that
way - what would be the reason to allow them to do it instead of giving
clear error message that makes it easy to fix? I can understand when
such things are left over by BC reasons - but to explicitly design the
language in a way that needs footnotes and warnings to code around bad
design?
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
this seems like a very good idea to me. this way things default to
"just work" (which imho is the PHP spirit), while its brain dead
easy to detect misuse.They not "just work" - they "work" in a wrong way (not usable in any
practical application). AndE_NOTICE
is a non-solution here - if we
know that it's wrong enough to put a warning there, why we don't
make it right? Why should we put another thing to stumble upon - why
people should learn another gimmick "you can write it that way, but
you never should do it because it works badly". If they shouldn't
write it that way - what would be the reason to allow them to do it
instead of giving clear error message that makes it easy to fix? I
can understand when such things are left over by BC reasons - but to
explicitly design the language in a way that needs footnotes and
warnings to code around bad design?
just the same reason as you can use a constant without initialization.
out of the box PHP does not try to be a teacher. it lets you write you
code that does what you need. but it lets you grow at the same time.
this is how PHP got its huge userbase. we let people grow with their
needs.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hi!
just the same reason as you can use a constant without initialization.
out of the box PHP does not try to be a teacher. it lets you write you
Constant without initialization doesn't lead to any problems. This one
does.
this is how PHP got its huge userbase. we let people grow with their needs.
And how exactly it serves the needs of people by secretly making their
applications orders of magnitude slower, and then saying "oh, that's
because you failed to read paragraph 16.4.5.1 in the manual, you should
really read that paragraph before pretending to be PHP programmer!".
Good environment or does what you want it to do, or fails, explaining to
you why it doesn't work - it doesn't do it half way half broken and then
blames you for not reading some obscure note in the manual. That's not
how I see helping.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
this is how PHP got its huge userbase. we let people grow with
their needs.And how exactly it serves the needs of people by secretly making
their applications orders of magnitude slower, and then saying "oh,
that's because you failed to read paragraph 16.4.5.1 in the manual,
you should really read that paragraph before pretending to be PHP
programmer!". Good environment or does what you want it to do, or
fails, explaining to you why it doesn't work - it doesn't do it half
way half broken and then blames you for not reading some obscure
note in the manual. That's not how I see helping.
ok this might be a shock for you .. but the vast majority of our user
base does not have a performance problem (thats not to say we need to
waste their CPU cycles .. we all love the planet).
then as we are suggesting they will not have to read a manual. in our
proposal they can use all the existing books, examples on PHP, migrate
their code easily to namespaces and things will just work. if they
advance beyond the point of absolute n00b, they will learn to look for
E_NOTICE
and by that time they will know how to fix their performance
issues (if they have any) without having to open a manual.
in your scenario, all examples in the world will mysteriously break
when they are used inside a namespace (which they might have gotten
from another example or some inherited code).
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hi Stas, and All,
I understand that there is a strong desire for this thread to be dead.
However, after reading this and all related threads and wiki, I find that
one item is still unclear, at least to me.
And how exactly it serves the needs of people by secretly making their
applications orders of magnitude slower, and then saying "oh, that's because
you failed to read paragraph 16.4.5.1 in the manual, you should really
read that paragraph before pretending to be PHP programmer!". Good
environment or does what you want it to do, or fails, explaining to you why
it doesn't work - it doesn't do it half way half broken and then blames you
for not reading some obscure note in the manual. That's not how I see
helping.
What, if any, performance penalty should we expect with the proposed
namespace changes when executing existing code that does not use
namespaces? Do we need to change existing namespace-free code in order to
avoid any potential performance penalties? Has anyone benchmarked the
changes yet to see if the performance penalty, if any, is actually
significant for some set of common usage cases?
If it's too soon to answer that last question then perhaps the whole
performance debate is a bit premature.
--
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Regards,
Marshall
Hi!
What, if any, performance penalty should we expect with the proposed
namespace changes when executing existing code that does not use
namespaces? Do we need to change existing namespace-free code in order
If you don't use namespaces, none I guess (well, compiling would be a
little slower since you still have all kinds of checks, but not
significantly). At least I'd expect that.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi
I have tried to collect the various opinions on resolution order into
a single RFC:
http://wiki.php.net/rfc/namespaceresolution
Proactive damage control:
I have also included some discussion on how the removable of function/
constants would affect the question of namespace resolution order
choices. Lets not use this to get back on to the topic of the
namespace separator and instead focus on the namespace resolution for
now. First lets get an RFC that documents all approaches for namespace
resolution in perfect shape. Divide and conquer.
Furthermore, we have all noticed that the participation on the list
has increased a lot in the recent weeks. As a result I ask everybody
to restrain themselves a bit more. Try to not reply on an impulse,
maybe wait a few hours before posting. This way we might reduce
redundant replies, also the quality of posts will hopefully be higher
so less misconceptions will need to be cleared later (and
misconceptions have a way to spiral into flamewars).
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hi
I have tried to collect the various opinions on resolution order
into a single RFC:
http://wiki.php.net/rfc/namespaceresolutionProactive damage control:
I have also included some discussion on how the removable of
function/constants would affect the question of namespace resolution
order choices. Lets not use this to get back on to the topic of the
namespace separator and instead focus on the namespace resolution
for now. First lets get an RFC that documents all approaches for
namespace resolution in perfect shape. Divide and conquer.Furthermore, we have all noticed that the participation on the list
has increased a lot in the recent weeks. As a result I ask everybody
to restrain themselves a bit more. Try to not reply on an impulse,
maybe wait a few hours before posting. This way we might reduce
redundant replies, also the quality of posts will hopefully be
higher so less misconceptions will need to be cleared later (and
misconceptions have a way to spiral into flamewars).
Some people have told me that they found the RFC hard to read.
Unfortunately this is not the first time that I have gotten feedback
like this from an RFC/FAQ I have written. If anyone has some
suggestions for improvements please let me know.
I have also just added another approach to the RFC. Instead of loading
classes as follows:
- ns
- autoload
- global
one could also do
- ns
- global
- autoload
this would prevent the issue with performance that Stas pointed out.
it would also retain the concept that autoload is a last resort
attempt (i guess some people even define classes in the fly if they
cannot be found elsewhere to be able to handle errors or even download
code when needed).
this would obviously mean that when someone wants to intentionally
overload a class, its important to either use the fully qualified name
or ensure that the class definition is loaded before use (similar
situation as we have with functions/constants if we do have the
fallback).
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Lukas Kahwe Smith wrote:
one could also do
- ns
- global
- autoload
I'm in favour of this (if it avoids performance problems) as I don't see
a problem with giving global priority over autoload.
- Chris
Christian Schneider wrote:
Lukas Kahwe Smith wrote:
one could also do
- ns
- global
- autoload
I'm in favour of this (if it avoids performance problems) as I don't see
a problem with giving global priority over autoload.
Hi,
This is the current name resolution. The problem is that:
<?php
namespace foo;
$a = new Exception();
?>
will instantiate foo::Exception only if the class already exists, but
will instantiate Exception otherwise. This defeats autoload's purpose
for existing. We've been over this before. It's dangerous.
There is one essential difference between classes and
functions/constants: autoload.
The only time the question of load order and fallback becomes and issue
is when code is not explicitly loaded. In other words, a developer who
is relying upon an external function will do this at some point before
calling the function:
<?php
include 'path/to/code/containing/function/source.php';
?>
In other words, PHP expects you to actually load the source of functions
or constants you're going to be using in advance of using it.
This, I believe, is a reasonable expectation.
Classes, however, do not share this same expectation, because
autoload's explicit purpose is to allow using classes before their
source has been loaded.
In other words, it is perfectly all right to have a different name
resolution for classes than we have for functions and constants because
of this different expectation. It is dangerous to fallback for classes
prior to autoload, but it is not at all dangerous for
functions/constants because the expectation is different.
For this reason, the only resolution that we should be considering is:
classes:
- try ns::class
- autoload ns::class
- fail
functions/constants:
- try ns::function/ns::const
- try internal function/const
- fail.
Note that I say "try internal" because the only purpose behind allowing
this is to make it easier to use PHP's built-in functionality. Any
userspace stuff should be specifically \prefixed or imported via use.
And (yes) we need import for functions.
Greg
P.S. my mail server has been down for almost a week, apologies to anyone
who is wondering why I haven't replied to your message, I probably
didn't get it.
In other words, it is perfectly all right to have a different name
resolution for classes than we have for functions and constants
because
of this different expectation. It is dangerous to fallback for
classes
prior to autoload, but it is not at all dangerous for
functions/constants because the expectation is different.
To me the key question is do we want to let people overload global
classes easily or are we mostly talking about convinience? Class names
are typed quite seldom (and even in a few years down the road the bulk
of PHP's features will be provided via functions), so I would not
think that we really need to focus on convenience here.
For this reason, the only resolution that we should be considering is:
classes:
- try ns::class
- autoload ns::class
- fail
functions/constants:
- try ns::function/ns::const
- try internal function/const
- fail.
Note that I say "try internal" because the only purpose behind
allowing
this is to make it easier to use PHP's built-in functionality. Any
userspace stuff should be specifically \prefixed or imported via use.
I dont think it makes sense to differentiate between internal and non
internal functions. I think this is quite hard to grasp, I also do not
see the real benefit.
And (yes) we need import for functions.
Would be nice to have .. for me the pains for functions/constants have
reached the threshold now that I am reviewing the question of
resolution.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Lukas Kahwe Smith wrote:
In other words, it is perfectly all right to have a different name
resolution for classes than we have for functions and constants because
of this different expectation. It is dangerous to fallback for classes
prior to autoload, but it is not at all dangerous for
functions/constants because the expectation is different.To me the key question is do we want to let people overload global
classes easily or are we mostly talking about convinience? Class names
are typed quite seldom (and even in a few years down the road the bulk
of PHP's features will be provided via functions), so I would not think
that we really need to focus on convenience here.
OK, taking a step back. Let's distill the two problems we're trying to
solve
- namespaces provide encapsulation - a safe way to name things without
worrying about whether it will conflict with external code - accessing internal functionality - the most used stuff in PHP should
still be easy to use in namespaces.
#1 means that when using our code inside namespaces, when there is
ambiguity we want it to look for namespaced stuff first and foremost.
#2 means we want to be able to access stuff like strlen()
and
array_map()
without any monkey business.
The largest conflict between #1 and #2 happens with classes because of
autoload. __autoload() is expensive from a performance standpoint, and
should not be called unnecessarily.
I posit that the most used stuff in PHP are internal functions (not
global userspace functions, not internal classes, not userspace classes)
and so this needs to be a priority. In addition, there is already
confusion over things like:
<?php
// which of these is a function?
$a = 1;
unset($a);
$a = key(array('hi' => 1));
include('oops.php');
?>
so requiring a prefix for functions will lead to parse errors in user
code like:
<?php
\include('oops.php');
?>
so the best resolution for functions is:
- ns\function
- internal function
Classes are different (TM).
if we do:
- ns\class
- autoload ns\class
- internal class
then this code has hidden performance hits:
<?php
namespace foo;
include 'external_autoload.php'; // __autoload must be declared
unnamespaced
$a = new ArrayObject(array('hi')); // calls autoload unnecessarily
?>
if we really mean the "ArrayObject" class and not the "foo\ArrayObject"
class. Thus, the convenience of internal fallback has disadvantages
(major performance problems) that do not exist with functions or constants.
Notifying the user via E_NOTICE/E_STRICT/E_WHATEVER simply adds
annoyance, and introduces potential for behavior change. For instance,
if a user decides to start using some external library that defines an
autoload when they didn't have it before, suddenly all of their code
throws E_NOTICEs every time an internal class name is referenced. Or,
without the E_NOTICE, performance suddenly slows way down and the user
blames the external library.
If we do:
- ns\class
- internal class
- autoload ns\class
then our code example fails in a more subtle way. The ambiguity of
"ArrayObject" resolves always in favor of internal class ArrayObject,
which means that users have to always explicitly import namespaced
classes to avoid this problem. Why is it a problem?
Let's say we're doing our own userspace implementation of PDO with a few
extensions, for a system where PDO is disabled:
<?php
namespace Myproject;
class PDO {} // userspace implementation of PDO
?>
now in another file:
<?php
namespace Myproject;
$a = new PDO(...);
?>
[note: this implementation depends on __autoload existing]
Now, if PDO extension is disabled, the above code will successfully
autoload Myproject\PDO. Imagine that on an upgrade, PDO is enabled.
Now, the object instantiated is of class PDO, not Myproject\PDO.
Suddenly, there are subtle logic errors that creep in (not a fatal
error), but the code continues to operate normally.
This resolution is very dangerous, and is a clear violation of the
primary purpose of namespaces.
If we do this:
- ns\class
- autoload ns\class
we get a "stronger" E_NOTICE
(fatal E_ERROR) when an internal class is
used without explicit import. This is robust, easy to debug, and forces
good code without much pain. Our example user above has no problems
with the external library, and changes need not be made after initial
coding.
By doing the resolution I've suggested (and Stas, incidentally, was the
first to suggest this):
classes:
- ns\class
- autoload ns\class
- FAILBOAT
functions/constants:
- ns\func or ns\const
- internal func\const
- FAILBOAT
We get the best of #1 and the best of #2, and it makes coding easier in
the long run.
Greg
Hi Greg,
By doing the resolution I've suggested (and Stas, incidentally, was the
first to suggest this):classes:
- ns\class
- autoload ns\class
- FAILBOAT
functions/constants:
- ns\func or ns\const
- internal func\const
- FAILBOAT
We get the best of #1 and the best of #2, and it makes coding easier in
the long run.
Stefan just convinced me of this in a much shorter post :)
+1
- Steph
Greg
<snip>#2 means we want to be able to access stuff like
strlen()
and
array_map()
without any monkey business.
functions/constants:
- ns\func or ns\const
- internal func\const
- FAILBOAT
Right, for the most part people will want access to internal
functions, but what is the benefit of not including user space
functions/constants? I find this quite confusing. The resolution rules
should be easy to explain and it should be easy to understand what is
going to happen when reading code. Nobody knows all PHP internal
functions (especially as new internal functions can be defined by
enabling extensions), so expecting people to know what will or will
not fallback is kind funky.
So lets have a look about the disadvantages of including all functions/
constants:
- you have to ensure the proper load order
- .. ?
As you pointed out, there is no autoload for functions, so people are
accustomed to ensuring that all functions are loaded before usage. Am
I missing something?
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
As you pointed out, there is no autoload for functions, so people are
accustomed to ensuring that all functions are loaded before usage. Am I
missing something?
Yes - you're missing the possibility of overriding, AKA naming collisions
between internal and userspace funcs/consts.
- Steph
Hi Greg, all,
For this reason, the only resolution that we should be considering is:
classes:
- try ns::class
- autoload ns::class
- fail
functions/constants:
- try ns::function/ns::const
- try internal function/const
- fail.
I see this as giving priority to library authors rather than the average PHP
user. So here's another option - and if I mention the word INI, will y'all
promise to read to the end before you shout at me?
We could have an INI_SYSTEM
switch.
ns.lookup=Off
means you have to prefix because otherwise resolution will fail with a
fatal error, but
ns.lookup=On
means that anything not prefixed and not local goes through the full lookup,
i.e. it does what is currently done outside a namespace context.
You'd switch ns.lookup off during development and on in production, and the
default would be on. Prefixed elements would be found at the first try
regardless of the setting, but would fail after a single check for a global
value if the element is not found when the setting's off. Non-prefixed code
would fail when the setting's off, but would otherwise get by except in
cases of ambiguity (easily remedied with a ''). It would, however, run
slower and be more prone to conflict, particularly in complex sites or
applications.
We make it very, very clear in the docs that prefixing is best practice, but
at the same time we allow John Doe to import a couple of namespaced
libraries without putting him through prefix hell.
What am I missing?
- Steph
Hello Steph,
Tuesday, November 4, 2008, 5:44:50 PM, you wrote:
Hi Greg, all,
For this reason, the only resolution that we should be considering is:
classes:
- try ns::class
- autoload ns::class
- fail
functions/constants:
- try ns::function/ns::const
- try internal function/const
- fail.
I see this as giving priority to library authors rather than the average PHP
user. So here's another option - and if I mention the word INI, will y'all
promise to read to the end before you shout at me?
We could have an
INI_SYSTEM
switch.
Nope. INI is the worst we can do.
[...]
What am I missing?
That INI is the worst we could do. Because it prevents from writing
portable code.
- Steph
Best regards,
Marcus
What am I missing?
That INI is the worst we could do. Because it prevents from writing
portable code.
This particular INI doesn't prevent anyone writing portable code. It simply
gives the option of a 'tighter' development mode.
- Steph
What am I missing?
That INI is the worst we could do. Because it prevents from writing
portable code.This particular INI doesn't prevent anyone writing portable code. It simply
gives the option of a 'tighter' development mode.
IT will break the code from everybody who doesn'T expect such a flag
exists and the average application user won't know and jsut see errors
which "randomly" occur.
No ini settings for basic behavior.
johannes
IT will break the code from everybody who doesn'T expect such a flag
exists and the average application user won't know and jsut see errors
which "randomly" occur.
Erm, how is that going to happen?
This is basically a tighter setting that can optionally be used and should
always be used in development. It would be documented loud and clear in
the PHP manual, where people go to find out about new/different-from-Java
language elements. There's a possible slowdown and possible conflicts if
you never use it, but the people most likely to never use it are those least
likely to be loading lots of third-party OO code in the first place.
No ini settings for basic behavior.
Ah well we might as well throw out E_STRICT
too!
- Steph
Steph Fox wrote:
IT will break the code from everybody who doesn'T expect such a flag
exists and the average application user won't know and jsut see errors
which "randomly" occur.Erm, how is that going to happen?
This is basically a tighter setting that can optionally be used and
should always be used in development. It would be documented loud and
clear in the PHP manual, where people go to find out about
new/different-from-Java language elements. There's a possible slowdown
and possible conflicts if you never use it, but the people most likely
to never use it are those least likely to be loading lots of third-party
OO code in the first place.No ini settings for basic behavior.
Ah well we might as well throw out
E_STRICT
too!
- Steph
I don't think it's going to prevent writing portable code, at least for
serious framework developers, because they'll prefix their classes
anyway. But I think it's dangerous and will cause unexpected behavior
for the average user.
This was discussed before, I'm with Stas: Global classes cannot be
overriden unless explicitly prefixed.
-- Rodrigo Saboya
On Tuesday 04 November 2008 17:44:50 Steph Fox wrote:
We could have an
INI_SYSTEM
switch.ns.lookup=Off
means you have to prefix because otherwise resolution will fail with a
fatal error, butns.lookup=On
means that anything not prefixed and not local goes through the full
lookup, i.e. it does what is currently done outside a namespace context.
Dev writes a script, uses autoload, overrides global class.
Distributed to user, that has ns.lookup=On as you propose, user borks his
install, lacks the file containing the class, gets the global class ->
obscure error messages because of nonexisting methods in places unrelated to
the place where the actual error happened. Not really a good idea, IMO.
Failing there is the best option. It's not like you have to prefix every
single occurence, you just have to say at the top of the file "When I say
Exception, I mean \Exception".
Regards,
Stefan
Hi Stefan,
Dev writes a script, uses autoload, overrides global class.
Distributed to user, that has ns.lookup=On as you propose, user borks his
install, lacks the file containing the class, gets the global class ->
obscure error messages because of nonexisting methods in places unrelated
to
the place where the actual error happened. Not really a good idea, IMO.
This is what happens now, right. So what's different?
Failing there is the best option. It's not like you have to prefix every
single occurence, you just have to say at the top of the file "When I say
Exception, I mean \Exception".
The point is that your dev would have done exactly that, so whether your
user has the setting on or off is immaterial.
- Steph
On Tuesday 04 November 2008 18:27:43 Steph Fox wrote:
Hi Stefan,
Dev writes a script, uses autoload, overrides global class.
Distributed to user, that has ns.lookup=On as you propose, user borks his
install, lacks the file containing the class, gets the global class ->
obscure error messages because of nonexisting methods in places unrelated
to
the place where the actual error happened. Not really a good idea, IMO.This is what happens now, right. So what's different?
With the proposed change -- failing at "step 3", it doesn't. It fails at the
time that you try to create the instance, saying the class was not found,
which is actually the case.
Failing there is the best option. It's not like you have to prefix every
single occurence, you just have to say at the top of the file "When I say
Exception, I mean \Exception".The point is that your dev would have done exactly that, so whether your
user has the setting on or off is immaterial.
- Steph
No, the dev didn't mean \Exception, he meant his exception, the one that he
has in the current namespace, and any way your setting would not have
resulted in any error, because for the dev, autoload worked.
Regards, Stefan
Hi Stefan,
Dev writes a script, uses autoload, overrides global class.
Distributed to user, that has ns.lookup=On as you propose, user borks
his
install, lacks the file containing the class, gets the global class ->
obscure error messages because of nonexisting methods in places
unrelated
to
the place where the actual error happened. Not really a good idea, IMO.This is what happens now, right. So what's different?
With the proposed change -- failing at "step 3", it doesn't. It fails at
the
time that you try to create the instance, saying the class was not found,
which is actually the case.
For clarity...
Current behaviour:
- check for namespaced\classname
- check for internal classname
- try to autoload namespaced\classname
- fail
Proposed (Stas, Greg):
- check for namespaced\classname
- try to autoload namespaced\classname
- fail
What I'm suggesting is a configurable switch between that proposed order
and:
- check for namespaced\classname
- try to autoload namespaced\classname
- check for internal classname
- fail
Failing there is the best option. It's not like you have to prefix
every
single occurence, you just have to say at the top of the file "When I
say
Exception, I mean \Exception".The point is that your dev would have done exactly that, so whether your
user has the setting on or off is immaterial.
- Steph
No, the dev didn't mean \Exception, he meant his exception, the one that
he
has in the current namespace, and any way your setting would not have
resulted in any error, because for the dev, autoload worked.
I see your point. OK, thanks.
- Steph
Hello Gregory,
Tuesday, November 4, 2008, 5:15:35 PM, you wrote:
Christian Schneider wrote:
Lukas Kahwe Smith wrote:
one could also do
- ns
- global
- autoload
I'm in favour of this (if it avoids performance problems) as I don't see
a problem with giving global priority over autoload.
Hi,
This is the current name resolution. The problem is that:
<?php
namespace foo;
$a = new Exception();
?>>
will instantiate foo::Exception only if the class already exists, but
will instantiate Exception otherwise. This defeats autoload's purpose
for existing. We've been over this before. It's dangerous.
There is one essential difference between classes and
functions/constants: autoload.
The only time the question of load order and fallback becomes and issue
is when code is not explicitly loaded. In other words, a developer who
is relying upon an external function will do this at some point before
calling the function:
<?php
include 'path/to/code/containing/function/source.php';
?>>
In other words, PHP expects you to actually load the source of functions
or constants you're going to be using in advance of using it.
This, I believe, is a reasonable expectation.
Classes, however, do not share this same expectation, because
autoload's explicit purpose is to allow using classes before their
source has been loaded.
In other words, it is perfectly all right to have a different name
resolution for classes than we have for functions and constants because
of this different expectation. It is dangerous to fallback for classes
prior to autoload, but it is not at all dangerous for
functions/constants because the expectation is different.
For this reason, the only resolution that we should be considering is:
classes:
- try ns::class
- autoload ns::class
- fail
Since we can stack autoload we could provide a c-level autoload function
that does the default lookup.
function global_autoload($name) {
if (($p = strrpos($name, '\')) !== false) {
$name = substr($name, $p);
if (NAMESPACE == substr($name, 0, $p -1) && class_exists("\$name")) {
use "\$name"; // if we find a way to do this at C-levle
}
}
}
functions/constants:
- try ns::function/ns::const
- try internal function/const
- fail.
Note that I say "try internal" because the only purpose behind allowing
this is to make it easier to use PHP's built-in functionality. Any
userspace stuff should be specifically \prefixed or imported via use.
And (yes) we need import for functions.
Greg
P.S. my mail server has been down for almost a week, apologies to anyone
who is wondering why I haven't replied to your message, I probably
didn't get it.
Best regards,
Marcus
classes:
- try ns::class
- autoload ns::class
- fail
Since we can stack autoload we could provide a c-level autoload
function
that does the default lookup.function global_autoload($name) {
if (($p = strrpos($name, '\')) !== false) {
$name = substr($name, $p);
if (NAMESPACE == substr($name, 0, $p -1) && class_exists("\
$name")) {
use "\$name"; // if we find a way to do this at C-levle
}
}
}
just to make sure i understand this correctly .. you are suggesting
here that we make it somehow possible in __autoload() to fallback to
the global namespace. so that if someone wants the fallback to global
namespace behavior for classes, he could get this by calling this
standard autoload function (or rather by using the spl autoload stack
- noting that spl may not be disabled anymore as of PHP 5.3).
more specifically you want to enable use statements inside autoload. i
presume that use statement would only be in effect for this single
name resolution? as in the use statement would not have an affect on
subsequent triggering of autoload, even when originating from the same
file?
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hello Lukas,
Wednesday, November 5, 2008, 12:32:19 AM, you wrote:
classes:
- try ns::class
- autoload ns::class
- fail
Since we can stack autoload we could provide a c-level autoload
function
that does the default lookup.function global_autoload($name) {
if (($p = strrpos($name, '\')) !== false) {
$name = substr($name, $p);
if (NAMESPACE == substr($name, 0, $p -1) && class_exists("\
$name")) {
use "\$name"; // if we find a way to do this at C-levle
}
}
}
just to make sure i understand this correctly .. you are suggesting
here that we make it somehow possible in __autoload() to fallback to
the global namespace. so that if someone wants the fallback to global
namespace behavior for classes, he could get this by calling this
standard autoload function (or rather by using the spl autoload stack
- noting that spl may not be disabled anymore as of PHP 5.3).
yes
more specifically you want to enable use statements inside autoload. i
and yes
presume that use statement would only be in effect for this single
name resolution?
and yes
as in the use statement would not have an affect on
subsequent triggering of autoload, even when originating from the same
file?
and yes
or in other words give the user the ability to specify when he wants the
fallback to global and not doing a fallback to global per default. That way
we get an efficient lookup witout a double retry:
- local
- autoload
- fail
while the user can stack above in first: - local
2.1) autoload as above == global
2.n) autoload - fail
and also stack at the end: - local
2.n) autoload
2.X) autoload as above == global - fail
Best regards,
Marcus
Hi!
or in other words give the user the ability to specify when he wants the
fallback to global and not doing a fallback to global per default. That way
This would be quite complex thing since this way you can't be sure which
class gets loaded when you say, e.g., Exception - and thus, if you write
something like "throw new Exception("XML did not load")" and except
My\XML\Parser\Exception and have catch for it but get just Exception
your application would happily unroll to the top and fail.
I think actually knowing what class is going to be loaded is a good idea
and overriding loader behavior so it's asked for one class and loads
completely different one is not a good idea. One would expect if he asks
for class X he gets class X, not class Y.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
or in other words give the user the ability to specify when he
wants the
fallback to global and not doing a fallback to global per default.
That wayThis would be quite complex thing since this way you can't be sure
which class gets loaded when you say, e.g., Exception - and thus, if
you write something like "throw new Exception("XML did not load")"
and except My\XML\Parser\Exception and have catch for it but get
just Exception your application would happily unroll to the top and
fail.I think actually knowing what class is going to be loaded is a good
idea and overriding loader behavior so it's asked for one class and
loads completely different one is not a good idea. One would expect
if he asks for class X he gets class X, not class Y.
Well, its not like the person is getting Y when he is expecting X.
Both classes have the same name after all, so there is some relation
between these two classes. More importantly its the users choice to
enable this in __autoload(). As all frameworks got that its the end
users job to implement autoload, I would not worry soo much in this
case.
Just a question: How hard would it be to implement in case we do want
this?
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Lukas Kahwe Smith wrote:
Hi!
or in other words give the user the ability to specify when he wants
the
fallback to global and not doing a fallback to global per default.
That wayThis would be quite complex thing since this way you can't be sure
which class gets loaded when you say, e.g., Exception - and thus, if
you write something like "throw new Exception("XML did not load")"
and except My\XML\Parser\Exception and have catch for it but get just
Exception your application would happily unroll to the top and fail.I think actually knowing what class is going to be loaded is a good
idea and overriding loader behavior so it's asked for one class and
loads completely different one is not a good idea. One would expect
if he asks for class X he gets class X, not class Y.Well, its not like the person is getting Y when he is expecting X.
Both classes have the same name after all, so there is some relation
between these two classes. More importantly its the users choice to
enable this in __autoload(). As all frameworks got that its the end
users job to implement autoload, I would not worry soo much in this case.Just a question: How hard would it be to implement in case we do want
this?
To do in any kind of performant way would require storing the source
filename along with the class name in the opcode (not hard), and would
also probably best be implemented not just as an autoload callback, but
as code that checks a flag in EG() inside zend_fetch_class. Thus, when
spl_autoload_register is passed in the dummy resolver name, it would
simply set a flag. This would also mean we would have to disallow a
chain like so:
<?php
spl_autoload_register('blah');
spl_autoload_register('internal'); // or whatever we decide to call it
spl_autoload_register('another');
?>
The last call should throw an error. internal should either be the
first or the last registered autoload.
Once this is set up, the actual code would simply check for whether the
internal class exists.
Even though it is technically possible, there is one huge flaw in the
idea: autoload can be changed external to the current file. How do you
safely design code that would work with both autoload implementations?
The truth is that code designed for internal resolution prior to
autoload would fail with any other resolution order, and code designed
for autoload prior to internal resolution would fail with any other
resolution.
There is only 1 safe and simple way to do this, and that is to have the
same resolution order in all cases, and the only safe resolution is 1)
ns::class 2) autoload ns::class 3) fail
Greg
Hi!
Well, its not like the person is getting Y when he is expecting X. Both
classes have the same name after all, so there is some relation between
They don't have the same name - two classes can't have the same name.
And "relation" is definitely not enough - you really do not want to get
generic \Exception instead of \My\Very\Specific\Exception - it would
probably break all your error handling.
That's like having a date with a pretty woman and getting her
85-year-old grand-uncle instead - the relation is there, but it's
definitely not what you were going for :)
these two classes. More importantly its the users choice to enable this
in __autoload(). As all frameworks got that its the end users job to
implement autoload, I would not worry soo much in this case.
I do not see a need for autoload to substitute different classes instead
of ones that are requested. autoload has very specific function - to
load classes. To override it with tricks that substitute one class for
another is the runkit domain, and IMHO should stay there. It would
seriously complicate matters everywhere (if you load the class, you can
no longer be sure successful loading have indeed loaded you the class
you asked for!) and appears completely unnecessary hack.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
Well, its not like the person is getting Y when he is expecting X.
Both classes have the same name after all, so there is some
relation betweenThey don't have the same name - two classes can't have the same
name. And "relation" is definitely not enough - you really do not
ok, they have the same non fully qualified named.
want to get generic \Exception instead of \My\Very\Specific
\Exception - it would probably break all your error handling.
this is about overloading and flexibility.
these two classes. More importantly its the users choice to enable
this in __autoload(). As all frameworks got that its the end users
job to implement autoload, I would not worry soo much in this case.I do not see a need for autoload to substitute different classes
instead of ones that are requested. autoload has very specific
function - to load classes. To override it with tricks that
substitute one class for another is the runkit domain, and IMHO
should stay there. It would seriously complicate matters everywhere
(if you load the class, you can no longer be sure successful loading
have indeed loaded you the class you asked for!) and appears
completely unnecessary hack.
the point was that this gives the end user the choice of when, if at
all, to fallback to the global namespace. in this way the default
could indeed be 1) ns 2) autoload 3) fail. just that autoload can now
handle more cases in a manner the end users might deem sensible.
i guess the other alternative (though actually i am not sure if its
possible), that people will likely try out is to extend the base class
inside the namespace on the fly. which i would consider much worse.
this might or might not be a sensible compromise, but you would do us
all a favor if you would stop killing off open thinking with useless
metaphors about 85 year old ladies.
thanks ...
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hi!
ok, they have the same non fully qualified named.
That's why we should have unambiguous resolution mechanism. You propose
to add one ambiguity on top of another.
want to get generic \Exception instead of \My\Very\Specific\Exception
- it would probably break all your error handling.
this is about overloading and flexibility.
We never had class name overloading and I don't see why we should start
it. It's runkit domain, as I said. If you call certain class, you should
be able to know which class is that. I don't understand why when seeing
problem so big that it requires change of whole syntax in something like
foo::bar() - you fail to understand ambiguity potential in your proposal.
the point was that this gives the end user the choice of when, if at
all, to fallback to the global namespace. in this way the default could
indeed be 1) ns 2) autoload 3) fail. just that autoload can now handle
more cases in a manner the end users might deem sensible.
It's not autoload's task to change class names that it is loading. By
the time you use autoloader the class name should already be known -
otherwise you can't even decide if to use autoloader or not! And it
definitely will screw up everything if you use multiple autoloaders with
different ideas about how to rewrite class names. Please let's keep
autoloaders simple and not insert there hacks that do not belong there,
we have enough complexity there already.
i guess the other alternative (though actually i am not sure if its
possible), that people will likely try out is to extend the base class
inside the namespace on the fly. which i would consider much worse.
What are you trying to achieve here?
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Note that I say "try internal" because the only purpose behind allowing
this is to make it easier to use PHP's built-in functionality. Any
userspace stuff should be specifically \prefixed or imported via use.
And (yes) we need import for functions.Greg
P.S. my mail server has been down for almost a week, apologies to anyone
who is wondering why I haven't replied to your message, I probably
didn't get it.
Hi,
This is starting to bother me, to be honest. Every time we go back to this
"fallback to internal X" I give examples and real world scenarios that will
become broken in namespaces which work today outside a namespace.
I get nods, agreement, people start talking that we should either fallback
to all global functions, or not fallback at all so that the behavior is
predictable for PHP users.
... And in few days we all forget problem and start talking about falling
back to internal again.
People do implement fallbacks for internal functionality as userspace
functions/classes on their own, TODAY. In namespace, if you don't treat
internal/user equally in resolution, things will work outside a namespace,
and break inside it. This will be confusing to people, who especially use
fallbacks to transparently implement missing PECL extensions or
functionality, or augment the internal functions of PHP with other, for ex.
user implemented ifsetor(), array_() or str() functions.
Regards,
Stan Vassilev
Marshall Greenblatt wrote:
Hi Stas, and All,
I understand that there is a strong desire for this thread to be dead.
However, after reading this and all related threads and wiki, I find that
one item is still unclear, at least to me.And how exactly it serves the needs of people by secretly making their
applications orders of magnitude slower, and then saying "oh, that's because
you failed to read paragraph 16.4.5.1 in the manual, you should really
read that paragraph before pretending to be PHP programmer!". Good
environment or does what you want it to do, or fails, explaining to you why
it doesn't work - it doesn't do it half way half broken and then blames you
for not reading some obscure note in the manual. That's not how I see
helping.What, if any, performance penalty should we expect with the proposed
namespace changes when executing existing code that does not use
namespaces? Do we need to change existing namespace-free code in order to
avoid any potential performance penalties? Has anyone benchmarked the
changes yet to see if the performance penalty, if any, is actually
significant for some set of common usage cases?If it's too soon to answer that last question then perhaps the whole
performance debate is a bit premature.
Existing code should see no change in performance from the previous PHP
5.3 alpha, and a significant improvement from PHP 5.2. In fact, code
that uses a lot of static method calls or class constants might see a
slight (imperceptible) performance increase, as a few hash lookups would
be removed.
I have not benchmarked this.
Greg
Josh Davis wrote:
2008/10/27 Stanislav Malyshev stas@zend.com:
- check for namespaced\classname
- try to autoload namespaced\classname
- fail
Ok, that makes some sense wrt your position, which I originally
interpreted as namespace/internal/autoload.You want to force users to use the full name at all times. IOW, you
want to sacrifice convenience for performance. On the upside, no
ambiguity whatsoever. "new Foo" is always a namespaced class. The
downside is that it makes it harder for users to copy/paste code from
current tutorials and examples, they will have to fix the class names.
Also, a few people will probably regret not being able to
auto-magically override some internal classes (e.g. override PDO to
log queries and what not) and it will probably increase the amount of
complaints about peppering one's code with backslashes.
<?php
namespace Foo;
use \PDO;
$a = new PDO; // $a is an object of class PDO
?>
<?php
namespace Foo;
use Clever\newversion\of\PDO;
$a = new PDO; // $a is now an object of class Clever\newversion\of\PDO
?>
Greg
It doesn't take a lot to kill an application if using internal class causes
__autoload to run for a non-existing user class.
Neither caches not optimizations can avoid that, as you can't have something
cached which doesn't exist.
In my autoloader for example, an existing user class is resolved instantly
from a hashmap lookup, i.e. my cache. I don't have ArrayObject in my cache,
so if my autoloader is asked to find ArrayObject.class.php, it'll start
crawling huge PHP libraries of code, every single request, only to fail in
the end and fallback to internal class.
Is this negligible performance hit? Actually (re)scanning my full library
takes few seconds of heavy disk grinding. Make your own conclusions.
Regards,
Stan Vassilev
Greg Beaver wrote:
Hi all,
Let me make this brief: there will be lots of complaining about the
namespace separator.Stop. Now.
It serves no possible useful purpose. If you want to discuss why this
was chosen or suggest alternatives, feel free to write me off-list. I
would be more than happy to answer any questions about the technical
aspects of various choices. The decision is made, now I suggest
everyone get busy actually trying it out. You will very quickly
understand why it is a very viable choice.Thanks,
Greg
just wanted to quickly say thanks for all you're long suffering hard
work on this - and a great decision imho.
thanks again :-)
So can I just confirm that what was previously
<?php
$x = new Framework::Utils::Foo();
$y = new Project::PEAR::Bar( 'somestring' );
?>
is now
<?php
$x = new Framework\Utils\Foo();
$y = new Project\PEAR\Bar( 'somestring' );
?>
Is this correct ?
Greg Beaver wrote:
Hi all,
Let me make this brief: there will be lots of complaining about the
namespace separator.Stop. Now.
It serves no possible useful purpose. If you want to discuss why this
was chosen or suggest alternatives, feel free to write me off-list. I
would be more than happy to answer any questions about the technical
aspects of various choices. The decision is made, now I suggest
everyone get busy actually trying it out. You will very quickly
understand why it is a very viable choice.Thanks,
Gregjust wanted to quickly say thanks for all you're long suffering hard work on
this - and a great decision imho.thanks again :-)
2008/10/26 Andrew Mason slackmase2@gmail.com:
So can I just confirm that what was previously
<?php
$x = new Framework::Utils::Foo(); $y = new Project::PEAR::Bar( 'somestring' );
?>
is now
<?php
$x = new Framework\Utils\Foo(); $y = new Project\PEAR\Bar( 'somestring' );
?>
Is this correct ?
Yes when greg's patch has been applied then it will work like that.
Greg Beaver wrote:
Hi all,
Let me make this brief: there will be lots of complaining about the
namespace separator.Stop. Now.
It serves no possible useful purpose. If you want to discuss why this
was chosen or suggest alternatives, feel free to write me off-list. I
would be more than happy to answer any questions about the technical
aspects of various choices. The decision is made, now I suggest
everyone get busy actually trying it out. You will very quickly
understand why it is a very viable choice.Thanks,
Gregjust wanted to quickly say thanks for all you're long suffering hard work on
this - and a great decision imho.thanks again :-)
--
--
--
Kalle Sommer Nielsen
So can I just confirm that what was previously
<?php
$x = new Framework::Utils::Foo(); $y = new Project::PEAR::Bar( 'somestring' );
?>
is now
<?php
$x = new Framework\Utils\Foo(); $y = new Project\PEAR\Bar( 'somestring' );
?>
Is this correct ?
Wouldn't it be:
<?php
$x = new Framework\Utils::Foo();
$y = new Project\PEAR::Bar( 'somestring' );
?>
Cheers,
Rob.
http://www.interjinn.com
Application and Templating Framework for PHP
Robert Cummings wrote:
So can I just confirm that what was previously
<?php
$x = new Framework::Utils::Foo(); $y = new Project::PEAR::Bar( 'somestring' );
?>
is now
<?php
$x = new Framework\Utils\Foo(); $y = new Project\PEAR\Bar( 'somestring' );
?>
Is this correct ?
Wouldn't it be:
<?php
$x = new Framework\Utils::Foo(); $y = new Project\PEAR::Bar( 'somestring' );
?>
The correct syntax is:
<?php
// initialize class
$a = new Framework\Utils\Foo();
// namespaced function
Framework\Utils\parse($string);
// static method
Project\PEAR\XML::makeEntity('\');
// namespaced constant
if ($a == Framework\Utils\FOO) echo "hi";
// class constant
if ($a == Project\PEAR\XML::ZOMG) echo "bye";
?>
Note that static class elements are accessed using T_DOUBLE_COLON
(::),
and that the namespace separator \ is used to join namespace and element
name.
Greg
Robert Cummings wrote:
So can I just confirm that what was previously
<?php
$x = new Framework::Utils::Foo(); $y = new Project::PEAR::Bar( 'somestring' );
?>
is now
<?php
$x = new Framework\Utils\Foo(); $y = new Project\PEAR\Bar( 'somestring' );
?>
Is this correct ?
Wouldn't it be:
<?php
$x = new Framework\Utils::Foo(); $y = new Project\PEAR::Bar( 'somestring' );
?>
The correct syntax is:
<?php
// initialize class
$a = new Framework\Utils\Foo();
// namespaced function
Framework\Utils\parse($string);
// static method
Project\PEAR\XML::makeEntity('\');
// namespaced constant
if ($a == Framework\Utils\FOO) echo "hi";
// class constant
if ($a == Project\PEAR\XML::ZOMG) echo "bye";
?>Note that static class elements are accessed using
T_DOUBLE_COLON
(::),
and that the namespace separator \ is used to join namespace and element
name.
Sorry, my mistake, I didn't notice the 'new' contsruct. Sorry for the
pollution.
Cheers,
Rob.
http://www.interjinn.com
Application and Templating Framework for PHP
Hi lover,
(sorry, couldn't resist)
The correct syntax is:
<?php
// initialize class
$a = new Framework\Utils\Foo();
// namespaced function
Framework\Utils\parse($string);
// static method
Project\PEAR\XML::makeEntity('\');
// namespaced constant
if ($a == Framework\Utils\FOO) echo "hi";
// class constant
if ($a == Project\PEAR\XML::ZOMG) echo "bye";
?>Note that static class elements are accessed using
T_DOUBLE_COLON
(::),
and that the namespace separator \ is used to join namespace and element
name.
OK... thanks for the clarification. That does actually make perfect sense to
me, I just read :: as a method call in Robert's example rather than as a new
class.
Guess I should sleep before typing 'as I understand it' again :)
- Steph
Hi Rob,
Wouldn't it be:
<?php
$x = new Framework\Utils::Foo();
$y = new Project\PEAR::Bar( 'somestring' );
?>
Yes, as I understand it.
- Steph
Greg Beaver wrote:
Hi all,
Let me make this brief: there will be lots of complaining about the
namespace separator.Stop. Now.
And if you had the common decency not to change the thread-id and subject
some on this list might respect the spirit of your plea.
William A. Rowe, Jr. wrote:
Greg Beaver wrote:
Hi all,
Let me make this brief: there will be lots of complaining about the
namespace separator.Stop. Now.
And if you had the common decency not to change the thread-id and subject
some on this list might respect the spirit of your plea.
I should add that I'm guilty of marking-read entire-thread.
having scrolled back, it's pretty clearly time for another Rasmus intervention
into what -was- a technical discussion, a couple 100 posts ago.
William A. Rowe, Jr. wrote:
Greg Beaver wrote:
Hi all,
Let me make this brief: there will be lots of complaining about the
namespace separator.Stop. Now.
And if you had the common decency not to change the thread-id and subject
some on this list might respect the spirit of your plea.
??? I wrote a from-scratch message, what do you mean?
Greg
Hello Greg,
thanks for finalizing this.
marcus
Sunday, October 26, 2008, 4:37:37 PM, you wrote:
Hi all,
Let me make this brief: there will be lots of complaining about the
namespace separator.
Stop. Now.
It serves no possible useful purpose. If you want to discuss why this
was chosen or suggest alternatives, feel free to write me off-list. I
would be more than happy to answer any questions about the technical
aspects of various choices. The decision is made, now I suggest
everyone get busy actually trying it out. You will very quickly
understand why it is a very viable choice.
Thanks,
Greg
Best regards,
Marcus