FAQ
All,

I have created a new draft RFC implementing function and constant

All feedback is welcome.

Thanks

Anthony

## Search Discussions

•  at Aug 30, 2013 at 4:57 am ⇧
Hi!
I have created a new draft RFC implementing function and constant

All feedback is welcome.
I think it is an unnecessary complication. Classes fit autoloader
paradigm nicely, since the usual pattern is one class per one file
(actually recommended in PSR), so it is easy to establish one-to-one
automatic mapping between classes and files (also recommended in the
PSR). But for functions nobody does this. This means that to implement
function autoloader one will need to have a complicated and fragile
logic (since there's no way to ensure this logic would be in sync with
actual content of files containing multiple functions).

Moreover, since this replaces a simple hash lookup with additional two
function calls (and also other operations included in those) everywhere
in the engine, it will also have performance impact of one of the most
frequently used operations in the engine - function calls - while
providing absolutely no benefit for 100% of existing code and 99.99% of
future code.

little sense to me - why would the same code load both classes and
functions? How would it do that besides ugly switch that just stuffs two
completely different logic pieces into one function for no reason? The
example given in the RFC is certainly not what anybody would actually
want their autoloaders to do, so I fail to see any case for doing it and
for putting loading more than one entity into one function (that given
doesn't seem so for me).

It is
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
•  at Aug 30, 2013 at 4:58 am ⇧
Hi!
It is
Oops, clicked too soon. I wanted to conclude that I think it is too many
complications in the engine for too little gain.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
•  at Aug 30, 2013 at 5:36 am ⇧

On Fri, Aug 30, 2013 at 12:58 PM, Stas Malyshev wrote:
Hi!
It is
Oops, clicked too soon. I wanted to conclude that I think it is too many
complications in the engine for too little gain.
I agree with Stas here.

thanks
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

--
Laruence Xinchen Hui
http://www.laruence.com/
•  at Aug 30, 2013 at 6:51 am ⇧

I think it is an unnecessary complication. Classes fit autoloader
paradigm nicely, since the usual pattern is one class per one file
(actually recommended in PSR), so it is easy to establish one-to-one
automatic mapping between classes and files (also recommended in the
PSR). But for functions nobody does this. This means that to implement
function autoloader one will need to have a complicated and fragile
logic (since there's no way to ensure this logic would be in sync with
actual content of files containing multiple functions).

I disagree on the basis that namespaced functions/constants *do* fit the

Moreover, since this replaces a simple hash lookup with additional two
function calls (and also other operations included in those) everywhere
in the engine, it will also have performance impact of one of the most
frequently used operations in the engine - function calls - while
providing absolutely no benefit for 100% of existing code and 99.99% of
future code.

Those function calls would only kick in if the function/constant wasn't
already defined, which will be the exception case, so perf isn't a strong
argument.

little sense to me - why would the same code load both classes and
functions? How would it do that besides ugly switch that just stuffs two
completely different logic pieces into one function for no reason? The
example given in the RFC is certainly not what anybody would actually
want their autoloaders to do, so I fail to see any case for doing it and
for putting loading more than one entity into one function (that given
doesn't seem so for me).

That I agree with 100%.
-Sara
•  at Aug 30, 2013 at 7:02 am ⇧
Hi!
I disagree on the basis that namespaced functions/constants *do* fit the
If they're already namespaced, what prevents one to put it in a class
Those function calls would only kick in if the function/constant wasn't
already defined, which will be the exception case, so perf isn't a
strong argument.
Not according to the code I see in the patch. There I see 2 func calls
(among other things) before the hash is even looked up.

--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
•  at Aug 30, 2013 at 7:08 am ⇧

If they're already namespaced, what prevents one to put it in a class

Nothing, really... Just countering your specific premise.
Those function calls would only kick in if the function/constant wasn't
already defined, which will be the exception case, so perf isn't a
strong argument.
Not according to the code I see in the patch. There I see 2 func calls
(among other things) before the hash is even looked up.

Well, the patch needs work obviously. I'm living in a magical world where

-Sara
•  at Aug 30, 2013 at 7:22 am ⇧
2013/8/30 Stas Malyshev <smalyshev@sugarcrm.com>
Hi!
I disagree on the basis that namespaced functions/constants *do* fit the
If they're already namespaced, what prevents one to put it in a class
Well, static methods aren't the same as functions.

Those function calls would only kick in if the function/constant wasn't
already defined, which will be the exception case, so perf isn't a
strong argument.
Not according to the code I see in the patch. There I see 2 func calls
(among other things) before the hash is even looked up.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

--
github.com/KingCrunch
•  at Aug 30, 2013 at 5:10 pm ⇧
Hi!
Well, static methods aren't the same as functions.
The big difference being?

--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
•  at Aug 30, 2013 at 5:38 pm ⇧

On Fri, Aug 30, 2013 at 7:10 PM, Stas Malyshev wrote:

Hi!
Well, static methods aren't the same as functions.
The big difference being?
This seems to be the core of your argumentation in this thread: "Why don't
you just use Foo::bar() instead of foo\bar()?"

In which case, I wonder why we have functions at all. We could just use
static methods instead after all. Maybe we should deprecate function
support?

On a more serious note: If you want an actual example of how functions can
be easier to use than static methods, consider the "use function" RFC. Now
that it's in, it is possible to directly import a function foo\bar() and
use it with just bar(). Static methods allow no such thing. You always need
to write the class name.

The reason why people currently resort to using static methods instead of
functions is the fact that there is no autoloading for functions. With

Nikita
•  at Aug 30, 2013 at 5:54 pm ⇧
Hi!
This seems to be the core of your argumentation in this thread: "Why
don't you just use Foo::bar() instead of foo\bar()?"

In which case, I wonder why we have functions at all. We could just use
static methods instead after all. Maybe we should deprecate function
support?
Maybe we should stop strawman arguments? I never claimed functions
should be replaced with static methods or that we should deprecate
anything, please don't put words in my mouth.
What I claimed is that if you write code in a *specific pattern*, that
is the only pattern that makes this proposal useful and that is, as far
as I can see, in no way common among people that use functions, then *in
this specific case* you could as well use slightly different pattern
which would allow you to use existing facilities, and the only
difference between the two is the word "class" and using :: instead of \.
On a more serious note: If you want an actual example of how functions
can be easier to use than static methods, consider the "use function"
RFC. Now that it's in, it is possible to directly import a function
foo\bar() and use it with just bar(). Static methods allow no such
thing. You always need to write the class name.
Which is a good thing. Making different thing mean the same is not a
good idea, it reduces readability. And typing 2 characters less was
never a priority.
The reason why people currently resort to using static methods instead
of functions is the fact that there is no autoloading for functions.
I don't accept this "resort to" - static functions is not something that
one should "resort to", it is a completely valid syntactic construct.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
•  at Aug 31, 2013 at 8:43 am ⇧
So you say you will create a file for every function you want to support autoloading?
As I already asked, tell us about realworld use case, for example where this could improve say big projects like Symfony or ZF.
There is no logic to add this functionality just because we can.

kindly,
nvartolomei

On Friday, August 30, 2013 at 8:38 PM, Nikita Popov wrote:

On Fri, Aug 30, 2013 at 7:10 PM, Stas Malyshev (mailto:smalyshev@sugarcrm.com)>wrote:
Hi!
Well, static methods aren't the same as functions.
The big difference being?
This seems to be the core of your argumentation in this thread: "Why don't
you just use Foo::bar() instead of foo\bar()?"

In which case, I wonder why we have functions at all. We could just use
static methods instead after all. Maybe we should deprecate function
support?

On a more serious note: If you want an actual example of how functions can
be easier to use than static methods, consider the "use function" RFC. Now
that it's in, it is possible to directly import a function foo\bar() and
use it with just bar(). Static methods allow no such thing. You always need
to write the class name.

The reason why people currently resort to using static methods instead of
functions is the fact that there is no autoloading for functions. With

Nikita
•  at Aug 31, 2013 at 6:03 pm ⇧
2013/8/31 Vartolomei Nicolae <nvartolomei@gmail.com>
So you say you will create a file for every function you want to support
I already _have_ create files for functions of a namespace... Closed
source.

this could improve say big projects like Symfony or ZF.
Not everything can be found in the 5 most popular frameworks.

There is no logic to add this functionality just because we can.
The lack of logic is: Why is it actually missing?

- Functions: Needs manual handling
- Constants: Needs manual handling

That is at first inconsistent. The need of "require_once"s is inefficient
and error prone.

Regards,
Sebastian

kindly,
nvartolomei

On Friday, August 30, 2013 at 8:38 PM, Nikita Popov wrote:

On Fri, Aug 30, 2013 at 7:10 PM, Stas Malyshev (mailto:
smalyshev@sugarcrm.com)>wrote:
Hi!
Well, static methods aren't the same as functions.
The big difference being?
This seems to be the core of your argumentation in this thread: "Why don't
you just use Foo::bar() instead of foo\bar()?"

In which case, I wonder why we have functions at all. We could just use
static methods instead after all. Maybe we should deprecate function
support?

On a more serious note: If you want an actual example of how functions can
be easier to use than static methods, consider the "use function" RFC. Now
that it's in, it is possible to directly import a function foo\bar() and
use it with just bar(). Static methods allow no such thing. You always need
to write the class name.

The reason why people currently resort to using static methods instead of
functions is the fact that there is no autoloading for functions. With

Nikita

--
github.com/KingCrunch
•  at Aug 31, 2013 at 9:57 pm ⇧

On Saturday, August 31, 2013 at 9:03 PM, Sebastian Krebs wrote:

I already _have_ create files for functions of a namespace... Closed source.
Can we take a look at them as an example? Maybe we can give you some advice
how to refactor this code :)
Not everything can be found in the 5 most popular frameworks.
Sure, but best practices usually are found there.
The lack of logic is: Why is it actually missing?
Why humans don’t have one leg more, on head?

I really want to look at an example for this. Looks like you are the only one who needs this.

Oh, is OOP that bad for you? Also constant autoloading looks so bad, I want to see an example of this too for sure.

Please don’t consider these questions like you need to prove something to me,
I’m asking them hoping that anwers will help all internals to understand problem you are trying to solve.

kindly,
nvartolomei
•  at Aug 31, 2013 at 10:33 pm ⇧

The lack of logic is: Why is it actually missing?
Why humans don’t have one leg more, on head?

I really want to look at an example for this. Looks like you are the only
one who needs this.

want to see an example of this too for sure.

Please don’t consider these questions like you need to prove something to
me,
I’m asking them hoping that anwers will help all internals to understand
problem you are trying to solve.
the function (and constant) autoloading was brought up on the list numerous
times, so I don't think that you can say things like he is the only one in
the need of this.
php is a multiparadigm programing language, and usually you can do
everything in procedural code that you would be able to do with oop code in
php.
except the autoloading, which for some people is an oop-only feature, so
makes no sense to provide for procedural code, while for some other people
as there is no 1:1 mapping between files and autoloader calls.

personally Ithink it would be nice if we could provide a way for

--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
•  at Aug 31, 2013 at 10:36 pm ⇧
personally Ithink it would be nice if we could provide a way for const/function autoloading.
So you will create files for constants? One file with a single line defining a constant?

Did I understood something wrong?

kindly,
nvartolomei
•  at Aug 31, 2013 at 11:05 pm ⇧

On Sun, Sep 1, 2013 at 12:36 AM, Vartolomei Nicolae wrote:
personally Ithink it would be nice if we could provide a way for const/function autoloading.
So you will create files for constants? One file with a single line defining a constant?

Did I understood something wrong?

kindly,
nvartolomei
Hi,

Yes, you understood it wrong. You can have one function / const in a
file if you want, but you can also have a bunch of them in a file
like you have today with classes. And from what I read in the RFC,
someone else who read it could confirm if I'm right or wrong, there's
no mandatory function / file to use this so you can use it like the
current autoloader for classes is working.

This will be optional to use, like the current autoloader, which is
why we don't have PSR-0 in Core (maybe we should have a thread about
this sooner or later) and I've had plenty of use cases for a feature
will cover this as well :)

Like it has been pointed out already, it also allows the language to
be complete in what's offering and help some users along the way.

Do you, or anyone else, have a real reason to be against this rather that:
- I don't like it
- I don't/won't use it
- why do we need it?
- it doesn't belong to the language
- etc.

So, my opinion as a PHP user is that it's a nice addition to the
language and even if I won't use it, as long as it won't affect the
global performance, I can live with it.

Regards,
Florin
----
Florin Patan
https://github.com/dlsniper
•  at Aug 31, 2013 at 11:11 pm ⇧
All,

There has been a lot of discussion unto the merit of this feature. That's
fine.

What I'd really like to know before proposing this is what can be improved
in this RFC.

For example: someone (Stas) brought up that it was weird that all three
types (Class, Function, Constant) are served by a single register function
(and multiple can be served by a single autoloader). Personally, I see this
as a significant simplification advantage, but I can see if others don't.
If you don't, can we please try to ideate around coming up with a better
syntax?

Another example: I've received a lot of feedback that using the "php" root
namespace is weird and unexpected. Does anyone agree? Should that be
changed prior to proposing this feature?

Let's try to improve this RFC to be the best it can prior to proposing and
voting. Even if you don't think it's necessary, there are surely things you
think can be improved (and hence everyone wins).

Thanks

Anthony

On Sat, Aug 31, 2013 at 7:04 PM, Florin Patan wrote:

On Sun, Sep 1, 2013 at 12:36 AM, Vartolomei Nicolae
wrote:
personally Ithink it would be nice if we could provide a way for
So you will create files for constants? One file with a single line
defining a constant?
Did I understood something wrong?

kindly,
nvartolomei
Hi,

Yes, you understood it wrong. You can have one function / const in a
file if you want, but you can also have a bunch of them in a file
like you have today with classes. And from what I read in the RFC,
someone else who read it could confirm if I'm right or wrong, there's
no mandatory function / file to use this so you can use it like the
current autoloader for classes is working.

This will be optional to use, like the current autoloader, which is
why we don't have PSR-0 in Core (maybe we should have a thread about
this sooner or later) and I've had plenty of use cases for a feature
will cover this as well :)

Like it has been pointed out already, it also allows the language to
be complete in what's offering and help some users along the way.

Do you, or anyone else, have a real reason to be against this rather that:
- I don't like it
- I don't/won't use it
- why do we need it?
- it doesn't belong to the language
- etc.

So, my opinion as a PHP user is that it's a nice addition to the
language and even if I won't use it, as long as it won't affect the
global performance, I can live with it.

Regards,
Florin
----
Florin Patan
https://github.com/dlsniper
•  at Sep 1, 2013 at 9:13 am ⇧

On Sun, Sep 1, 2013 at 1:11 AM, Anthony Ferrara wrote:
All,

There has been a lot of discussion unto the merit of this feature. That's
fine.

What I'd really like to know before proposing this is what can be improved
in this RFC.

For example: someone (Stas) brought up that it was weird that all three
types (Class, Function, Constant) are served by a single register function
(and multiple can be served by a single autoloader). Personally, I see this
as a significant simplification advantage, but I can see if others don't.
If you don't, can we please try to ideate around coming up with a better
syntax?
I think adding two different functions and maintaining the general one
could be the way to go in this case.

The function names might look like this:

Thinking on how PSRs work, one might register one autoloader for
they don't need to take care of supporting them in the autoloader.
loader could be registered to it's own
'spl_register_function_autoloader()'. If there'll be a special PSR
that covers both then that loader will need to call

I'm sure the names could be improved.

Another example: I've received a lot of feedback that using the "php" root
namespace is weird and unexpected. Does anyone agree? Should that be
changed prior to proposing this feature?
Could we have something like the global namespace for classes where
'\' is the default namespace?

Or maybe alias php\ to \ namespace auto-magically?

Let's try to improve this RFC to be the best it can prior to proposing and
voting. Even if you don't think it's necessary, there are surely things you
think can be improved (and hence everyone wins).

Thanks

Anthony
Those are the idea that I have in regards to this RFC. Hope they help.

Kind regards,

Florin Patan
https://github.com/dlsniper
•  at Sep 2, 2013 at 8:11 pm ⇧
Hi!
The function names might look like this:
Also, we usually name functions in increasing order of specificity (i.e.
Or maybe alias php\ to \ namespace auto-magically?
Nope. \ namespace is root namespace, it can not be magically aliased to
anything and should not be.

--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
•  at Sep 1, 2013 at 3:27 pm ⇧
My previous message didn't push the point I wanted raise: don't we have a
major problem related to at-run-time namespace resolution for functions and
constants?

Take this code: namespace foo { strlen("bar"); }

Will you trigger an autoload for foo\strlen?
I believe not because that would hurt performance too much.
But then, how will you load function foo\strlen if it exists?

Now take this code: namespace foo { bar(); }

Will you trigger autoload for "foo\bar" first, then for "bar"?
Only for "foo\bar"? But then, what if "bar" exists and just waits being

namespace resolution.
•  at Sep 1, 2013 at 8:30 pm ⇧
Nicolas,
On Sun, Sep 1, 2013 at 11:27 AM, Nicolas Grekas wrote:

My previous message didn't push the point I wanted raise: don't we have a
major problem related to at-run-time namespace resolution for functions and
constants?

Take this code: namespace foo { strlen("bar"); }

Will you trigger an autoload for foo\strlen?
I believe not because that would hurt performance too much.
But then, how will you load function foo\strlen if it exists?

Now take this code: namespace foo { bar(); }

Will you trigger autoload for "foo\bar" first, then for "bar"?
Only for "foo\bar"? But then, what if "bar" exists and just waits being

namespace resolution.
So, here's how it works, by example:

namespace foo {
use function biz\buz;
use foo\bar;

}

So basically, if the call uses "fallback" resolution, the autoload is only
attempted at the global resolution.

Does that make sense?

Anthony
•  at Sep 2, 2013 at 7:34 am ⇧
Hi!
namespace foo {
use function biz\buz;
use foo\bar;

Wait, so it wouldn't work like class autoloader, using fully qualified
namespaces, so you'd have to specify explicit imports or full namespace
names for any namespaced functions you use in your code?

That doesn't sound very practical. It's much easier to do one require
than to import manually each function in the namespace and requiring to
explicitly name all of them removes half of the usefulness of namespaces
- if you wanted all the full names, you could use
very_long_names_like_this() as before.

topic came up.

Also it is weird that namespace name is added to bar\baz() but not to
bar(). This is contrary to how namespaces work in other places - where
namespace name is added to everything not fully quailified.
Does that make sense?
Frankly, for me it doesn't. Now I recall namespaces resolution and
failed the last time. IMHO this is a pretty big problem for practical
usage of this - as pretty much the only case for function autoloading is
resting on namespaces, so if autoloader can't deal with namespaced
resolution rules, it's not good.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
•  at Sep 2, 2013 at 12:58 pm ⇧
Stas,
namespace foo {
use function biz\buz;
use foo\bar;

Wait, so it wouldn't work like class autoloader, using fully qualified
namespaces, so you'd have to specify explicit imports or full namespace
names for any namespaced functions you use in your code?
It indeed does work like the class loader in all but one case. When the
compiler knows what you're intending (via explicit use, relative or
absolute qualification), it can load the namespaced function.

The time it is different is when you don't use function and just write
foo(). With classes, this works fine, because there is no "fallback"
behavior. With functions, it can't, because it was decided long ago to
silently fall back to using a global function if this happens.

So the only case this effects is that you can't autoload a function from
the same namespace that you're currently in without explicitly using that
function.

That's not such a huge issue.

The bigger issue (for me) is that in 5.3+, you have code that means
different things depending on the state of the engine. In the example
above, that function call can mean "foo\something" or "something".

Having a function call that isn't obviously resolvable is...

But "fixing" that would be such a massive BC break...

That doesn't sound very practical. It's much easier to do one require
than to import manually each function in the namespace and requiring to
explicitly name all of them removes half of the usefulness of namespaces
- if you wanted all the full names, you could use
very_long_names_like_this() as before.
You would only need to explicitly use function those in your current
namespace. Any outside (relative or absolute calls) would still work fine.

And after all, this is the exact reason we implemented use function.
Because namespaces WERE useless for functions until last week. Now we have
the power to be explicit with our calls.

topic came up.

Also it is weird that namespace name is added to bar\baz() but not to
bar(). This is contrary to how namespaces work in other places - where
namespace name is added to everything not fully quailified.
That's how functions (and namespaces) have always worked. Give it a try:
http://3v4l.org/S6FN8 Keep in mind, functions have been treated as second
class citizens in PHP since 5.3. They haven't played well with namespaces,
or autoloading. Today we've fixed half of that issue. This RFC attempts to
fix the other half.

Does that make sense?
Frankly, for me it doesn't. Now I recall namespaces resolution and
failed the last time. IMHO this is a pretty big problem for practical
usage of this - as pretty much the only case for function autoloading is
resting on namespaces, so if autoloader can't deal with namespaced
resolution rules, it's not good.

The big difference is that last time there was no mechanism to be explicit
with what you wanted your code to do without fully qualifying every call.
Today we have use function.

Anthony
•  at Sep 2, 2013 at 8:03 pm ⇧
Hi!
So the only case this effects is that you can't autoload a function from
the same namespace that you're currently in without explicitly using
that function.

That's not such a huge issue.
I think it is such a huge issue, because this means this functionality
declaration, and this is pretty much the use case we've been preached
about all along. So if it doesn't work in this case without prior
declarations just for it, than how it's better than require?
But "fixing" that would be such a massive BC break...
There's nothing to "fix", it was a conscious decision about how
namespaces must work. Alternative is doing \strlen each time you need
string length, which would be just silly.
You would only need to explicitly use function those in your current
namespace. Any outside (relative or absolute calls) would still work fine.
It's not "only" - functions in current namespace are exactly those I'm
likely to use.
And after all, this is the exact reason we implemented use function.
Because namespaces WERE useless for functions until last week. Now we
have the power to be explicit with our calls.
I don't think RFC proposed well before this issue was raised was
sincerely hope it has more uses than that, otherwise it's a pretty big
mistake.
That's how functions (and namespaces) have always worked. Give it a
try: http://3v4l.org/S6FN8 Keep in mind, functions have been treated as
No it's not how it worked - function resolution rules were always "try
namespace, then global", unless alias is explicitly specified by use
(aliased name is treated as fully qualified, because this is what the
function of aliasing is). Just try to remove "use" statement and see.
The big difference is that last time there was no mechanism to be
explicit with what you wanted your code to do without fully qualifying
every call. Today we have use function.
Which is the same specification, just at the beginning of the file. I'd
rather do one require then ten use functions. My opinion is producing
autoloader that is inconsistent with how language itself treats import
would only produce more WTFs and more people thinking nothing in PHP
makes sense and nobody cares about internal consistency of the language.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
•  at Sep 2, 2013 at 9:57 pm ⇧
Stas,

On Mon, Sep 2, 2013 at 4:02 PM, Stas Malyshev wrote:

Hi!
So the only case this effects is that you can't autoload a function from
the same namespace that you're currently in without explicitly using
that function.

That's not such a huge issue.
I think it is such a huge issue, because this means this functionality
declaration, and this is pretty much the use case we've been preached
about all along. So if it doesn't work in this case without prior
declarations just for it, than how it's better than require?

It doesn't *need* prior declaration. It needs either prior declaration or
qualification (absolute or relative). But more on that in a sec.

But "fixing" that would be such a massive BC break...
There's nothing to "fix", it was a conscious decision about how
namespaces must work. Alternative is doing \strlen each time you need
string length, which would be just silly.

So what your saying, if I understand you correctly, is that PHP was
intentionally designed to be non-deterministic? And it was designed that
way to save a single character?

To get why I think that's such a big deal, let's look at some sample code:

namespace Foo {
function test1($input) { return strlen($input);
}
function test2($input) { return strlen($input);
}
var_dump(test1("test")); // int(4)

// Simulate require
eval('namespace Foo { function strlen($input) { return 42; }}'); var_dump(test2("test")); // int(42) var_dump(test1("test")); // int(4) on 5.4+, int(42) on 5.3 } The eval is just there to simulate a require_once. Thanks to function caching, NOTHING makes sense!!! http://3v4l.org/MMvFv If you don't agree that behavior is wonky, then I'm not sure where else to go. You would only need to explicitly use function those in your current namespace. Any outside (relative or absolute calls) would still work fine. It's not "only" - functions in current namespace are exactly those I'm likely to use. Look at the code where you use classes. How many times to do use a class from your current namespace vs another one. The code I've looked at tends to favor other namespaces significantly... And after all, this is the exact reason we implemented use function. Because namespaces WERE useless for functions until last week. Now we have the power to be explicit with our calls. I don't think RFC proposed well before this issue was raised was actually meant only to fix broken function autoloading proposal. I sincerely hope it has more uses than that, otherwise it's a pretty big mistake. That's how functions (and namespaces) have always worked. Give it a try: http://3v4l.org/S6FN8 Keep in mind, functions have been treated as No it's not how it worked - function resolution rules were always "try namespace, then global", unless alias is explicitly specified by use (aliased name is treated as fully qualified, because this is what the function of aliasing is). Just try to remove "use" statement and see. It's only "try namespace, then global" in the case where there's no \ in the function name. Compile code that does the check: http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_compile.c#1938 The big difference is that last time there was no mechanism to be explicit with what you wanted your code to do without fully qualifying every call. Today we have use function. Which is the same specification, just at the beginning of the file. I'd rather do one require then ten use functions. My opinion is producing autoloader that is inconsistent with how language itself treats import would only produce more WTFs and more people thinking nothing in PHP makes sense and nobody cares about internal consistency of the language. Anthony PS: I think it's ironic talking about internal consistency of a language in the same reply where you justify "try namespace, then global" as a good design feature. Just pointing that out... •  at Sep 2, 2013 at 10:18 pm ⇧ Hi! So what your saying, if I understand you correctly, is that PHP was intentionally designed to be non-deterministic? And it was designed that way to save a single character? It is deterministic, there are rules for it, described in http://us1.php.net/manual/en/language.namespaces.fallback.php. And it's not to save single character, it is to save single character on hundreds of thousands of function calls which otherwise all would have to be rewritten. It's to prevent namespacing a code piece being equal to rewriting every function call in it and making it extremely ugly on the way. The cost of if is that yes, if you want to override strlen (which still escapes me why would you ever want to do something like that) you need to load it first so the engine knows about it and resolves it correctly. I think it is a very small cost compared to rewriting and uglifying all your code. It was all extensively and meticulously discussed on the list when namespaces were designed. It is a real waste of time to repeat those discussions now. It's only "try namespace, then global" in the case where there's no \ in the function name. Compile code that does the check: http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_compile.c#1938 I know. That you for pointing me to the code I wrote. I am sorry that I didn't just copy-paste the whole "namespace resolution rules" section, I though it is clear from the context that I am talking about non-fully-qualified names. PS: I think it's ironic talking about internal consistency of a language in the same reply where you justify "try namespace, then global" as a good design feature. Just pointing that out... It is a good design feature, and there are very good reasons for it. Unless, of course, you think prepending every internal function and PHP constant in all the existing code in PHP with \ would be better. In which case we have very different ideas about what good design is and would never come to any agreement on that. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 •  at Sep 3, 2013 at 5:32 am ⇧ hi! On Tue, Sep 3, 2013 at 12:17 AM, Stas Malyshev wrote: Hi! At this point I would suggest to put the summary of the pros and cons described (in a more or less exhaustive way) in the RFC and go for the vote. Maybe double checks if there are any BC related issues that need to be addressed as well, as this is something we have to avoid. But for what I can see, this discussion is running in circle and costs both of us too much time and energy. Cool down a bit, breath deeply and let the RFC voting phase begins as soon as possible. Cheers. -- Pierre @pierrejoye | http://www.libgd.org •  at Sep 3, 2013 at 4:04 pm ⇧ In which case we have very different ideas about what good design is and would never come to any agreement on that. This is already evident in ALL of your recent "discussions" on this ML. Go and look: you are the most active participant in each topic and you are bickering in each one. Could you please stop dominating every discussion? •  at Sep 3, 2013 at 4:54 pm ⇧ On Tue, Sep 3, 2013 at 6:04 PM, Levi Morrison wrote: In which case we have very different ideas about what good design is and would never come to any agreement on that. This is already evident in ALL of your recent "discussions" on this ML. Go and look: you are the most active participant in each topic and you are bickering in each one. Could you please stop dominating every discussion? I'd to say it is more an attempt to understand the needs of one feature or another. This is why this ML exists, to discuss (which may move to arguing sometimes, so it goes). But I won't ever ask someone to stop participating to discussions, unless it goes off topic or the tone is not appropriate (had one recently where my tone was not the best, I stopped :). That being said, there is always a point in a RFC discussion where there is nothing left to discuss or argue about, we are so far with this one. Cheers, -- Pierre @pierrejoye | http://www.libgd.org •  at Sep 3, 2013 at 5:04 pm ⇧ On Tue, Sep 3, 2013 at 10:54 AM, Pierre Joye wrote: On Tue, Sep 3, 2013 at 6:04 PM, Levi Morrison wrote: In which case we have very different ideas about what good design is and would never come to any agreement on that. This is already evident in ALL of your recent "discussions" on this ML. Go and look: you are the most active participant in each topic and you are bickering in each one. Could you please stop dominating every discussion? I'd to say it is more an attempt to understand the needs of one feature or another. This is why this ML exists, to discuss (which may move to arguing sometimes, so it goes). But I won't ever ask someone to stop participating to discussions, unless it goes off topic or the tone is not appropriate (had one recently where my tone was not the best, I stopped :). I didn't ask him to stop participating: I asked him to stop dominating every discussion. There is a significant difference. That being said, there is always a point in a RFC discussion where there is nothing left to discuss or argue about, we are so far with this one. We've been at this point for a while; no new arguments have been raised despite several people asking to bring it back in focus. •  at Sep 5, 2013 at 8:24 am ⇧ 2013/9/3 Levi Morrison <morrison.levi@gmail.com> On Tue, Sep 3, 2013 at 10:54 AM, Pierre Joye wrote: On Tue, Sep 3, 2013 at 6:04 PM, Levi Morrison <morrison.levi@gmail.com> wrote: In which case we have very different ideas about what good design is and would never come to any agreement on that. This is already evident in ALL of your recent "discussions" on this ML. Go and look: you are the most active participant in each topic and you are bickering in each one. Could you please stop dominating every discussion? I'd to say it is more an attempt to understand the needs of one feature or another. This is why this ML exists, to discuss (which may move to arguing sometimes, so it goes). But I won't ever ask someone to stop participating to discussions, unless it goes off topic or the tone is not appropriate (had one recently where my tone was not the best, I stopped :). I didn't ask him to stop participating: I asked him to stop dominating every discussion. There is a significant difference. I must say, that I share this opinion. I follow this list quite a while now and it is not the first time, that the discussion about a quite promising proposal were "dominated" until one after the other leaves the discussion -- annoyed and demotivated. That being said, there is always a point in a RFC discussion where there is nothing left to discuss or argue about, we are so far with this one. We've been at this point for a while; no new arguments have been raised despite several people asking to bring it back in focus. -- github.com/KingCrunch •  at Sep 5, 2013 at 8:51 am ⇧ On Thu, Sep 5, 2013 at 10:23 AM, Sebastian Krebs wrote: That being said, there is always a point in a RFC discussion where there is nothing left to discuss or argue about, we are so far with this one. We've been at this point for a while; no new arguments have been raised despite several people asking to bring it back in focus. I totally understand your view on how such discussions go. However it was (for what I read) about technical issues and the tones were correct, could have been more diplomatic but that's fine imho. I am not sure how to solve this problem as we have to discuss things deeply and be sure that active core developers actually understand all the impact of a given proposal will have, that's a must. I am also relatively happy with the situation compared to other projects (try to do it on the kernel mailing list f.e.) while we have to put more efforts to be contributors friendly, like on the cairo project (best ever). Sadly Anthony took this whole thing way too personally and is leaving php.net, I'm not sure it is a definitive choice but it is a bad move, in many ways and for both php.net and himself. It is very common that not everyone agree with a proposal, or do not see the needs of it, trying to understand its impact or the reasoning behind it. If everyone begins to leave as soon as it happens, OSS would die, right now. Conclusion: We are a tech group, keep that in mind :) Cheers. -- Pierre @pierrejoye | http://www.libgd.org •  at Sep 5, 2013 at 9:35 am ⇧ On Thu, Sep 5, 2013 at 10:51 AM, Pierre Joye wrote: On Thu, Sep 5, 2013 at 10:23 AM, Sebastian Krebs wrote: That being said, there is always a point in a RFC discussion where there is nothing left to discuss or argue about, we are so far with this one. We've been at this point for a while; no new arguments have been raised despite several people asking to bring it back in focus. I totally understand your view on how such discussions go. However it was (for what I read) about technical issues and the tones were correct, could have been more diplomatic but that's fine imho. I am not sure how to solve this problem as we have to discuss things deeply and be sure that active core developers actually understand all the impact of a given proposal will have, that's a must. I don't think this discussion was about technical issues. Let me summarize the main discussion points: * "This will make function calls slower!". Many complaints about this change hurting performance, even though it was pointed out early on (and detailed in the RFC) that this is not true. * "Will you put every function in it's own file?!". This has been repeated *a lot* in this thread, even though again it has been pointed out early that there are more reasonable autoloading schemes for functions (e.g. namespace-to-file) * "Just use static methods instead". I don't need to comment on the absurdity of this statement. * "Which function is autoloaded?" Is the namespaced version or the global fallback loaded? Of these, only the last point has been of any benefit to this discussion. There has also been some minor discussion regarding the API, which is also relevant. But why does 80% of this thread deal with performance (known incorrect assumption), unreasonable suggestions of function-to-file mappings (even though alternatives are known) and suggestions to just not use functions? It's really hard to fish out the 10 relevant mails in a discussion spanning 70 in total. Sadly Anthony took this whole thing way too personally and is leaving php.net, I'm not sure it is a definitive choice but it is a bad move, in many ways and for both php.net and himself. It is very common that not everyone agree with a proposal, or do not see the needs of it, trying to understand its impact or the reasoning behind it. If everyone begins to leave as soon as it happens, OSS would die, right now. I'm pretty sure that Anthony's reaction is not directly related to this particular thread - rather it is an accumulation of the very same kind of discussion we have on nearly every RFC. Discussion is always very circular, covering issues that have already been addressed (usually even written down in the RFCs). Typically this kind of pointless discussion happens between just three or so people and fills the largest part of the thread. Stas is usually one of those "three" people, though of course I will not imply causation from correlation. Nikita •  at Sep 5, 2013 at 10:32 am ⇧ On Thu, Sep 5, 2013 at 11:34 AM, Nikita Popov wrote: On Thu, Sep 5, 2013 at 10:51 AM, Pierre Joye wrote: On Thu, Sep 5, 2013 at 10:23 AM, Sebastian Krebs <krebs.seb@gmail.com> wrote: That being said, there is always a point in a RFC discussion where there is nothing left to discuss or argue about, we are so far with this one. We've been at this point for a while; no new arguments have been raised despite several people asking to bring it back in focus. I totally understand your view on how such discussions go. However it was (for what I read) about technical issues and the tones were correct, could have been more diplomatic but that's fine imho. I am not sure how to solve this problem as we have to discuss things deeply and be sure that active core developers actually understand all the impact of a given proposal will have, that's a must. I don't think this discussion was about technical issues. Let me summarize the main discussion points: * "This will make function calls slower!". Many complaints about this change hurting performance, even though it was pointed out early on (and detailed in the RFC) that this is not true. * "Will you put every function in it's own file?!". This has been repeated *a lot* in this thread, even though again it has been pointed out early that there are more reasonable autoloading schemes for functions (e.g. namespace-to-file) * "Just use static methods instead". I don't need to comment on the absurdity of this statement. * "Which function is autoloaded?" Is the namespaced version or the global fallback loaded? Of these, only the last point has been of any benefit to this discussion. There has also been some minor discussion regarding the API, which is also relevant. But why does 80% of this thread deal with performance (known incorrect assumption), unreasonable suggestions of function-to-file mappings (even though alternatives are known) and suggestions to just not use functions? It's really hard to fish out the 10 relevant mails in a discussion spanning 70 in total. Right, it goes circular way too often. I see that in many other MLs. I however do not see it as a reason to leave, no matter how much it happens. I also see these questions, discussions or arguing session as technical matters, be semantic, common sense or anything else. It is all about being sure about what php will be after a given feature is added. I'm pretty sure that Anthony's reaction is not directly related to this particular thread - rather it is an accumulation of the very same kind of discussion we have on nearly every RFC. Discussion is always very circular, covering issues that have already been addressed (usually even written down in the RFCs). Typically this kind of pointless discussion happens between just three or so people and fills the largest part of the thread. Stas is usually one of those "three" people, though of course I will not imply causation from correlation. I very much respect Stas, both for his constructive attitude and the insane amount of work he puts in PHP and the related projects. As anyone else, he is however a human, with needs to understand a specific point very clearly. I do not think there any evil or domination behavior here. About the N people trying to control everything, that's why we have RFCs. Maybe we should scan discussions more frequently and stop them when it goes circular, ask to update the RFC accordingly and move forward. This is something I tried to do. Sadly I was busy with other stuff in the last couple of months and was not able to follow each recent RFC discussions closely. Cheers, -- Pierre @pierrejoye | http://www.libgd.org •  at Sep 11, 2013 at 3:00 pm ⇧ On 9/5/13 3:32 AM, Pierre Joye wrote: On Thu, Sep 5, 2013 at 11:34 AM, Nikita Popov wrote: On Thu, Sep 5, 2013 at 10:51 AM, Pierre Joye wrote: On Thu, Sep 5, 2013 at 10:23 AM, Sebastian Krebs <krebs.seb@gmail.com> wrote: That being said, there is always a point in a RFC discussion where there is nothing left to discuss or argue about, we are so far with this one. We've been at this point for a while; no new arguments have been raised despite several people asking to bring it back in focus. I totally understand your view on how such discussions go. However it was (for what I read) about technical issues and the tones were correct, could have been more diplomatic but that's fine imho. I am not sure how to solve this problem as we have to discuss things deeply and be sure that active core developers actually understand all the impact of a given proposal will have, that's a must. I don't think this discussion was about technical issues. Let me summarize the main discussion points: * "This will make function calls slower!". Many complaints about this change hurting performance, even though it was pointed out early on (and detailed in the RFC) that this is not true. * "Will you put every function in it's own file?!". This has been repeated *a lot* in this thread, even though again it has been pointed out early that there are more reasonable autoloading schemes for functions (e.g. namespace-to-file) * "Just use static methods instead". I don't need to comment on the absurdity of this statement. * "Which function is autoloaded?" Is the namespaced version or the global fallback loaded? Of these, only the last point has been of any benefit to this discussion. There has also been some minor discussion regarding the API, which is also relevant. But why does 80% of this thread deal with performance (known incorrect assumption), unreasonable suggestions of function-to-file mappings (even though alternatives are known) and suggestions to just not use functions? It's really hard to fish out the 10 relevant mails in a discussion spanning 70 in total. Right, it goes circular way too often. I see that in many other MLs. I however do not see it as a reason to leave, no matter how much it happens. I also see these questions, discussions or arguing session as technical matters, be semantic, common sense or anything else. It is all about being sure about what php will be after a given feature is added. I'm pretty sure that Anthony's reaction is not directly related to this particular thread - rather it is an accumulation of the very same kind of discussion we have on nearly every RFC. Discussion is always very circular, covering issues that have already been addressed (usually even written down in the RFCs). Typically this kind of pointless discussion happens between just three or so people and fills the largest part of the thread. Stas is usually one of those "three" people, though of course I will not imply causation from correlation. I very much respect Stas, both for his constructive attitude and the insane amount of work he puts in PHP and the related projects. As anyone else, he is however a human, with needs to understand a specific point very clearly. I do not think there any evil or domination behavior here. About the N people trying to control everything, that's why we have RFCs. Maybe we should scan discussions more frequently and stop them when it goes circular, ask to update the RFC accordingly and move forward. This is something I tried to do. Sadly I was busy with other stuff in the last couple of months and was not able to follow each recent RFC discussions closely. Cheers, I agree with Pierre on all his points in this mail. (Note I haven't done more than skim the fuss around "the post I wish I didn't have to read" so I won't comment further, nor wish my thoughts to be extrapolated in any related direction). Chris •  at Sep 2, 2013 at 12:48 pm ⇧ namespace foo { something(); // autoloaded as "something" } That makes sense *for me* for many reasons, but IMHO that's too confusing for a wider adoption. Because this doesn't work for function foo\strlen, the only reasonable way to work with such an autoloader would be to avoid using dynamic namespace resolution by always using some "use function" or "use namespace". That's very fragile... I order not to be the one who kills a proposal and be constructive: Would some kind of namespace initializers be a good idea? That could work this way: Any time a non existing function or constant is required, a registered namespace initializer would be loaded. The big difference being that it would happen *BEFORE* fallback namespace resolution. The registered namespace loader would be given only the namespace part of the required symbol, and that would happen only once per namespace. That would have a performance impact, but I would be interested in seeing real benchmarks. May be we can find a way to make the mechanism light enough. For this performance reason, I would suggest having a registering function that take the exact namespace for which the loader matches as first argument: spl_namespace_register($namespace[, callable $autoload_function)$autoload_function would be called only for symbols in $namespace. What do you think ? Is it worth discussing that further? Nicolas •  at Sep 2, 2013 at 1:23 pm ⇧ Nicolas, namespace foo { something(); // autoloaded as "something" } That makes sense *for me* for many reasons, but IMHO that's too confusing for a wider adoption. Because this doesn't work for function foo\strlen, the only reasonable way to work with such an autoloader would be to avoid using dynamic namespace resolution by always using some "use function" or "use namespace". That's very fragile... How is it fragile? In fact, I would argue that relying on dynamic namespace resolution (as happens today) is fragile. Because you can't know at compile time (or before hand) what a function will resolve to. That's fine when you want polymorphism, but when you don't (which is most of the time that you're calling a named function) it's not much short of fragile. This encourages explicit, one-execution-path code. I fail to see how that makes things worse than today... In fact, I see it making this better... I order not to be the one who kills a proposal and be constructive: Would some kind of namespace initializers be a good idea? That could work this way: Any time a non existing function or constant is required, a registered namespace initializer would be loaded. The big difference being that it would happen *BEFORE* fallback namespace resolution. The registered namespace loader would be given only the namespace part of the required symbol, and that would happen only once per namespace. That would have a performance impact, but I would be interested in seeing real benchmarks. May be we can find a way to make the mechanism light enough. For this performance reason, I would suggest having a registering function that take the exact namespace for which the loader matches as first argument: spl_namespace_register($namespace[, callable $autoload_function)$autoload_function would be called only for symbols in $namespace. What do you think ? Is it worth discussing that further? It's an interesting thought. I think I'd rather see first-class support for modules, but not quite sure there. Actually, thinking about it slightly more, this appears to be trying to hack namespaces into first-class modules. Right now, a namespace is nothing more than compiler aided copy/paste (with the exception of global fallback for functions and constants). It's just a prefix added on to the construct's name. To do this right, you could do it by parsing the name at each dispatch, and then doing a hash table lookup to see if it's been loaded or not yet. But if we're going down that route, why not take the next logical step and make modules first class citizens (with a symbol table, where classes, functions and constants are members of said module, rather than just floating with prefixed names. That way we can attach metadata, access permissions, events, etc around the module, and not just hack in one additional thing. Obviously this is a massive undertaking and quite off topic from here. But if it's worth discussing further, let's open another thread. Anthony •  at Aug 31, 2013 at 11:27 pm ⇧ On Sun, Sep 1, 2013 at 12:36 AM, Vartolomei Nicolae wrote: personally Ithink it would be nice if we could provide a way for const/function autoloading. So you will create files for constants? One file with a single line defining a constant? Did I understood something wrong? yes, you did. I never mentioned that I would use this feature, nor that I would put one constant in a file if I would. I suppose those who use it would use namespaces(either native namespaces or some prefix/suffix in the name which their autoloader understands) to group the functions/constants and when a const/func is referenced from a namespace include the file which contains all of the funcs/consts from that namespace. -- Ferenc Kovács @Tyr43l - http://tyrael.hu •  at Aug 31, 2013 at 10:39 pm ⇧ Python packages often place convenience functions (e.g., factory methods) in __init__.py files. There's nothing wrong with that. It would be great to be able to do something similar in PHP. Sure beats creating classes called Util. Thanks, Michael On Aug 31, 2013, at 2:57 PM, Vartolomei Nicolae wrote: On Saturday, August 31, 2013 at 9:03 PM, Sebastian Krebs wrote: I already _have_ create files for functions of a namespace... Closed source. Can we take a look at them as an example? Maybe we can give you some advice how to refactor this code :) Not everything can be found in the 5 most popular frameworks. Sure, but best practices usually are found there. The lack of logic is: Why is it actually missing? Why humans don’t have one leg more, on head? I really want to look at an example for this. Looks like you are the only one who needs this. Oh, is OOP that bad for you? Also constant autoloading looks so bad, I want to see an example of this too for sure. Please don’t consider these questions like you need to prove something to me, I’m asking them hoping that anwers will help all internals to understand problem you are trying to solve. kindly, nvartolomei -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php •  at Sep 1, 2013 at 8:05 am ⇧ On Sat, Aug 31, 2013 at 11:57 PM, Vartolomei Nicolae wrote: On Saturday, August 31, 2013 at 9:03 PM, Sebastian Krebs wrote: I already _have_ create files for functions of a namespace... Closed source. Can we take a look at them as an example? Maybe we can give you some advice how to refactor this code :) So you will create files for constants? One file with a single line defining a constant? It seems like many people in this thread can't even imagine that there are reasonable schemes for function autoloading. So let me give you a practical autoloading scheme as an example. I have a library (https://github.com/nikic/iter) - it's not important what it does, just that it's function based -, which uses the namespaces iter, iter\fn and iter\rewindable. All functions (and classes!) belonging to the respective namespaces are stored in iter.php, iter.fn.php and iter.rewindable.php. [*] An autoloader for this scheme (according to current proposal) would look like this: php\autoload_register(function($name, $type) { if (0 !== strpos($name, 'iter\\')) return;

// extract namespace portion of name
$namespace = substr($name, 0, strrpos($name, '\\')); require __DIR__ . '/' . str_replace('\\', '.',$namespace) . '.php';

As you can see, this is a simple autoloader, verify similar to what you'd
write for classes. Differences being a) only the namespace is used to
locate the file, rather than the full name and b) I'm using . instead of /,
but that's really irrelevant here.

and classes with the same scheme. As such I find it useful to specify
something like FUNCTION|CLASS a the type.

function in its own file" or something like that. "Every namespace in its
own file" works fine. This is somewhat akin to how Python modules are
structured.

Thanks,
Nikita

[*] This is not exactly true. There are functions located in the "wrong"
no problem to put all functions in the file belonging to their namespace.
•  at Aug 30, 2013 at 6:02 pm ⇧
2013/8/30 Stas Malyshev <smalyshev@sugarcrm.com>
Hi!
Well, static methods aren't the same as functions.
The big difference being?
A function is stateless [1], a method isn't. A function operates only on
the passed parameters [1], the method operates on the parameters and the
context it inherits from the instance (non-static), or class (static and
non-static).

[1] Beside IO and "global variables"-hacks

--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

--
github.com/KingCrunch
•  at Aug 30, 2013 at 6:14 pm ⇧
Hi!
A function is stateless [1], a method isn't. A function operates only on
the passed parameters [1], the method operates on the parameters and the
context it inherits from the instance (non-static), or class (static and
non-static).
Static method is stateless in the same meaning as unattached function
is. Both can keep state in static variables if you wish. So no
difference at all, public static method is just a namespaced function.

--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
•  at Sep 1, 2013 at 9:38 am ⇧

-----Original Message-----
From: Sebastian Krebs
Sent: Friday, August 30, 2013 9:02 PM
To: Stas Malyshev
Cc: Sara Golemon; Anthony Ferrara; internals@lists.php.net

2013/8/30 Stas Malyshev <smalyshev@sugarcrm.com>
Hi!
Well, static methods aren't the same as functions.
The big difference being?
A function is stateless [1], a method isn't. A function operates only on the
passed parameters [1], the method operates on the parameters and the
context it inherits from the instance (non-static), or class (static and non-
static).
Static methods are equally stateless as global functions. A class state
(static members) is no different from global variables (except for a tiny
bit of lipstick in the form of encapsulation). There's no argument
methods are different from global functions, not so with static methods
which are essentially the same as global functions.

Zeev
•  at Sep 1, 2013 at 4:23 pm ⇧
I can accept not supporting PSR directly but implementing the class
doesn't specify/support any particular implementation", this makes sense,
although I like PSR and don't really see others that make (as much) sense.

This means internally we recognise an issue, resolve it in a general manner
and allow some decisions up to the developer.

Most of us developing now have the dreaded Utils class, it's an ugly hack
filled with static methods... Yes, it might be almost the same as a
namespaced bunch of classes, if you don't share states between those
methods.

Now consider this: PSR or any autoloader implementation allows for better
sharing and code reuse; AND it makes sense to allow this for OOP as well as
procedural code!

I think Anthony and Nikki can see the forest from the trees, and that the
core should support a number of use cases, not just what you currently use
(and developers miss this functionality Anthony proposes)

Having namespaced functions now allows for a function autoloader that uses
the namespace as the file: awesome, great, let's do this!

If not by looking at others code, or at Python, or at the
Class/Constants/Namespaced-Functions all needing to have and being
positively impacted by an autoloader... at least try and foresee the sense
it makes for non-oop-but-maintained-by-smart-people to have an autoloader!

Try to understand that this need exists and, it makes sense as a step into
organising and refactoring legacy applications and for structure/grouping
of classes, functions and constants, if only for the sake of organisation,
but also for code-sharing, code reuse AND less managing of 20 *_once calls
on top of every file in legacy applications! ;)

Also as a bonus, a bunch of functions/constants filled files could got
through a request never being read/included if never used, this alone
should warrant pause!
•  at Dec 30, 2013 at 4:18 pm ⇧

Daniel Macedo wrote:
I can accept not supporting PSR directly but implementing the class
doesn't specify/support any particular implementation", this makes sense,
although I like PSR and don't really see others that make (as much) sense.

This means internally we recognise an issue, resolve it in a general
manner and allow some decisions up to the developer.

Most of us developing now have the dreaded Utils class, it's an ugly hack
filled with static methods... Yes, it might be almost the same as a
namespaced bunch of classes, if you don't share states between those methods.

Now consider this: PSR or any autoloader implementation allows for better
sharing and code reuse; AND it makes sense to allow this for OOP as well
as procedural code!

I think Anthony and Nikki can see the forest from the trees, and that the
core should support a number of use cases, not just what you currently
use (and developers miss this functionality Anthony proposes)

Having namespaced functions now allows for a function autoloader that
uses the namespace as the file: awesome, great, let's do this!

If not by looking at others code, or at Python, or at the
Class/Constants/Namespaced-Functions all needing to have and being
positively impacted by an autoloader... at least try and foresee the
sense it makes for non-oop-but-maintained-by-smart-people to have an autoloader!

Try to understand that this need exists and, it makes sense as a step
into organising and refactoring legacy applications and for
structure/grouping of classes, functions and constants, if only for the
sake of organisation, but also for code-sharing, code reuse AND less
managing of 20 *_once calls on top of every file in legacy applications! ;)

Also as a bonus, a bunch of functions/constants filled files could got
through a request never being read/included if never used, this alone should warrant pause!
From a user land developer, having the option of doing something is always
better then not. You guys are doing a lot of great work for us mere
mortals, why not also give us this option? It's been stated that thanks to
a function short circuit that it would not cost performance and would add
functionally. To me that seems like a win, win.

--
•  at Aug 30, 2013 at 7:30 am ⇧
2013/8/30 Stas Malyshev <smalyshev@sugarcrm.com>
Hi!
I have created a new draft RFC implementing function and constant

All feedback is welcome.
I think it is an unnecessary complication. Classes fit autoloader
paradigm nicely, since the usual pattern is one class per one file
(actually recommended in PSR), so it is easy to establish one-to-one
automatic mapping between classes and files (also recommended in the
PSR).

Autoloading was introduced long before PSR-0 and PSR-0 is also only a
because there was _always_ a class<->file mapping" is somehow misleading.

But for functions nobody does this. This means that to implement
function autoloader one will need to have a complicated and fragile
logic (since there's no way to ensure this logic would be in sync with
actual content of files containing multiple functions).
This is the same complicated and fragile logik you need for class loading.
For example compared to PSR-0 functions could be implemented in a file
named after the namespace. An autoloader would be very similar to every

Moreover, since this replaces a simple hash lookup with additional two
function calls (and also other operations included in those) everywhere
in the engine, it will also have performance impact of one of the most
frequently used operations in the engine - function calls - while
providing absolutely no benefit for 100% of existing code and 99.99% of
future code.

little sense to me - why would the same code load both classes and
functions? How would it do that besides ugly switch that just stuffs two
completely different logic pieces into one function for no reason? The
example given in the RFC is certainly not what anybody would actually
want their autoloaders to do, so I fail to see any case for doing it and
for putting loading more than one entity into one function (that given
doesn't seem so for me).
It is
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

--
github.com/KingCrunch
•  at Aug 30, 2013 at 9:42 am ⇧

On Fri, Aug 30, 2013 at 6:57 AM, Stas Malyshev wrote:

I think it is an unnecessary complication. Classes fit autoloader
paradigm nicely, since the usual pattern is one class per one file
(actually recommended in PSR), so it is easy to establish one-to-one
automatic mapping between classes and files (also recommended in the
PSR). But for functions nobody does this. This means that to implement
function autoloader one will need to have a complicated and fragile
logic (since there's no way to ensure this logic would be in sync with
actual content of files containing multiple functions).
For functions people do not commonly use a one-to-one mapping between a
function name and a file, that's true. But there commonly *is* a one-to-one
mapping between a *namespace* and a file. So if you have a function
foo\bar\baz it will be in the file foo/bar.php (which defines all functions
of namespace foo\bar). I think this is a rather common pattern in
functional (or function-heavy) libraries and I use this myself too.

Apart from such a namespace-to-file mapping you can also use the same
approach some people use for classes: Just pregenerate the name-to-file
mappings in an array, then loop up from there (e.g. theseer/autoload). This
is one of the rare autoloading concepts that actually properly works in PHP
(much unlike PSR-0, which fails to honor case-insensitivity).

Moreover, since this replaces a simple hash lookup with additional two
function calls (and also other operations included in those) everywhere
in the engine, it will also have performance impact of one of the most
frequently used operations in the engine - function calls - while
providing absolutely no benefit for 100% of existing code and 99.99% of
future code.
I'd assume that this isn't yet the final patch and it will be improved to
make sure that there is no significant performance regression for function
calls not making use of autoloading. This should just be a matter of
inlining the part of the function with the direct hash lookup and avoiding
a duplicate lcname call. (Maybe in the engine just keep the old if

little sense to me - why would the same code load both classes and
functions?

I don't think it makes much sense to use the same function to autoload
classes and functions, but I think it makes sense to autoload both
functions and constants with the same mechanism, because presumably both
would follow the same naming-convention (e.g. the namespace-to-file mapping
mentioned above). So I think this is a useful feature and I definitely
don't see a reason why we need to explicitly prevent it.

Anyway, I'm +1 on this :) PHP has been neglecting it's functional sides.
The "use function" RFC and this one work on improving this a bit.

Nikita
•  at Aug 30, 2013 at 11:17 am ⇧
Stas,

Moreover, since this replaces a simple hash lookup with additional two
function calls (and also other operations included in those) everywhere
in the engine, it will also have performance impact of one of the most
frequently used operations in the engine - function calls - while
providing absolutely no benefit for 100% of existing code and 99.99% of
future code.

Basically, two new macros are introduced which expand directly to hash
lookups.

#define ZEND_LOOKUP_FUNCTION_BY_NAME(name, name_length, fbc)
(zend_hash_find(EG(function_table), (name), (name_length) + 1,
(void**) (fbc)) == SUCCESS || zend_lookup_function((name),
(name_length), (fbc)) == SUCCESS)

So nothing changes from present (at all) unless a function is not defined.
Today, that's an error case. So the only performance change occurs if
zend_hash_find (which is already there) returns FAILURE. THEN the logic

So no, there should be no performance impact at all to existing code thanks
to operator short circuiting.

Anthony
•  at Aug 30, 2013 at 5:19 pm ⇧
Hi!
So nothing changes from present (at all) unless a function is not
defined. Today, that's an error case. So the only performance change
occurs if zend_hash_find (which is already there) returns FAILURE. THEN
I see a number of places where hash lookup is replaced with
zend_lookup_function, not with the macro. Moreover, zend_lookup_function
for some reason copies and lowercases the argument, even though for hash
lookup it should already be lowercased.

--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
•  at Aug 30, 2013 at 5:36 pm ⇧
Stas,

I see a number of places where hash lookup is replaced with
zend_lookup_function, not with the macro. Moreover, zend_lookup_function
for some reason copies and lowercases the argument, even though for hash
lookup it should already be lowercased.

There was quite literally one place I forgot to switch to the macro
expansion (in zend_API.c, zend_is_callable_check_func). I'm sorry. That has
been rectified.

As far as it being already lowercased, based on the original implementation
before refactor, I couldn't hold that as true. So I had implemented it very
similar to lookup_class.

However, after the refactor (the current state of the patch), it is
redundant. I have pushed a commit to refactor that away.

Thanks

Anthony

## Related Discussions

Discussion Overview
 group php-internals categories php posted Aug 30, '13 at 1:23a active Dec 30, '13 at 4:18p posts 72 users 24 website php.net

### 24 users in discussion

Content

People

Support

Translate

site design / logo © 2019 Grokbase