Function auto-loading

php.internals

Rasmus Schultz

10 years ago
I'd really like to see the function auto-loading proposal revived and/or possibly simplified. The fact that functions are hard (in some cases impossible) to reach by manually issuing require/include statements is, in my opinion, half the difficulty, and a much more deeply rooted language problem exacerbating what should be trivial problems - e.g. install a Composer package, import (use) and call the functions. Looks like a fair amount of work and discussion was done in 2013 on this RFC: https://wiki.php.net/rfc/function_autoloading There was a (now stale) proof of concept implementation for the parent RFC as well: https://wiki.php.net/rfc/function_autoloading2 What happened? It looks like the discussion stalled mostly over some concerns, including reservations about performance, which were already disproved? One issue apparently was left unaddressed, that of whether a call to an undefined function should generate an auto-load call to a namespaced or global function - I think this would not be difficult to address: trigger auto-loading of the namespaced function first, check if it was loaded, and if not, trigger auto-loading of the global function. Most likely a PSR along with Composer auto-loading features will favor a best practice of shipping packages with namespaced functions only, so the performance implications of checking twice would be negligible in practice. Being basically unable to ship or consume purely functional packages leaves the functional side of the language largely an unused historical artifact, which is sad. Keeping things functional and stateless often lead to more predictable and obvious code - I think the absence of good support for functions encourages a lot of over-engineering, e.g. developers automatically making everything a class, not as a design choice, for the sole reason of being able to ship and reuse what should be simple functions. This RFC looks pretty solid to me. What will it take to get this rolling again?

Fleshgrinder

10 years ago
On 8/7/2016 1:19 PM, Rasmus Schultz wrote:
> I'd really like to see the function auto-loading proposal revived and/or > possibly simplified. >
+1 from my side for the revival. I would also love to see auto-loading of namespaced constants like we have it for class constants.
-- Richard "Fleshgrinder" Fussenegger

Nikita Popov

10 years ago
On Sun, Aug 7, 2016 at 1:19 PM, Rasmus Schultz <rasmus@mindplay.dk> wrote:
> I'd really like to see the function auto-loading proposal revived and/or > possibly simplified. > > The fact that functions are hard (in some cases impossible) to reach by > manually issuing require/include statements is, in my opinion, half the > difficulty, and a much more deeply rooted language problem exacerbating > what should be trivial problems - e.g. install a Composer package, import > (use) and call the functions. > > Looks like a fair amount of work and discussion was done in 2013 on this > RFC: > > https://wiki.php.net/rfc/function_autoloading > > There was a (now stale) proof of concept implementation for the parent RFC > as well: > > https://wiki.php.net/rfc/function_autoloading2 > > What happened? > > It looks like the discussion stalled mostly over some concerns, including > reservations about performance, which were already disproved? > > One issue apparently was left unaddressed, that of whether a call to an > undefined function should generate an auto-load call to a namespaced or > global function - I think this would not be difficult to address: trigger > auto-loading of the namespaced function first, check if it was loaded, and > if not, trigger auto-loading of the global function.
I feel like the problem here did not get across properly. Calling the autoloader if a global function with the name exists will totally kill performance. This means that every call to strpos() or any of the other functions in the PHP standard library will have to go through the autoloader first, unless people use fully qualified names (which, currently, they don't). This is completely out of the question. (The case where neither the namespaced nor the global function exists is not the problem. In that case calling the autoloader for the namespaced and non-namespaced names in sequence is of course unproblematic.) Nikita

Rasmus Schultz

10 years ago
Of course calling e.g. strpos() should not trigger the auto-loader repeatedly - can we cache the information that the auto-loader was attempted once during the current script execution? so that e.g. only the first call to strpos() triggers the auto-loader? I suppose it would still happen once for every namespace from which strpos() gets called, so maybe this optimization doesn't help much. I guess I'd say, benchmark it before making assumptions? Maybe the performance hit turns out to be negligible in practice. Hard to say. If a performance hit is inevitable, but marginal, I hope that we do not let micro-benchmarks stand in the way of improving the language? With PHP 7, the language is in many ways almost twice as fast as it was before. I think it's fair to say, PHP has problems that are much bigger than performance - to most developers, performance is not a pain point anymore, if it was before PHP 7. I wish that I could change your focus from performance concerns to actually focusing on the language itself. It seems that me that recent performance improvements have become somewhat of a bottleneck that *prevents* new features and (worse) missing features from completing and improving the language? The performance improvements could just as well be viewed as a factor that creates new elbow room for new features and language improvements, which, long term, likely have much more value to more developers than the performance of micro-benchmarks. At the end of the day, for like 9 our of 10 projects, PHP's core performance is not the bottleneck - things like database queries are. The cost of developing a project is also generally unrelated to core performance of the language. Hardware gets cheaper and faster every day. So who or what are we optimizing for? I don't mean to get too side-tracked from the original conversation here, but we should be designing for developers - not for machines. The language is more than fast enough for what most developers need it for - and still nowhere near fast enough for, say, a JSON or XML parser, the kind of things that require C or assembly level performance, and I really don't believe there's a substantial segment of use-cases that fall in between - for most things, either you need performance that PHP can't get near, or you need language features and convenience that low-level languages can't deliver. We're not competing with C - and if we're competing with other scripting languages on performance, we're already in a pretty good position, and people who select a scripting language aren't basing their choice on raw performance in the first place; if that was their concern, they'd pick C. We should focus on competing with other scripting languages on features, convenience, productivity, etc. - if our main concern is competing on low-level concerns like performance, those concerns will override the points that really matter to developers who choose a high-level scripting language, and we will lose. On Sun, Aug 7, 2016 at 1:29 PM, Nikita Popov <nikita.ppv@gmail.com> wrote:

David Rodrigues

10 years ago
What should be the difference between a static method on a autoloaded class? I guess that it could be done currently by use a static method. In this case, I know exactly what method should be called, without depends of an autoloader response. class String { public static function strpos(...) { ... } } In this case, I just need to call String::strpos(...) and done. I don't know if I'm missing something. 2016-08-07 9:07 GMT-03:00 Rasmus Schultz <rasmus@mindplay.dk>:
> Of course calling e.g. strpos() should not trigger the auto-loader > repeatedly - can we cache the information that the auto-loader was > attempted once during the current script execution? so that e.g. only the > first call to strpos() triggers the auto-loader? > > I suppose it would still happen once for every namespace from which > strpos() gets called, so maybe this optimization doesn't help much. > > I guess I'd say, benchmark it before making assumptions? Maybe the > performance hit turns out to be negligible in practice. Hard to say. > > If a performance hit is inevitable, but marginal, I hope that we do not let > micro-benchmarks stand in the way of improving the language? > > With PHP 7, the language is in many ways almost twice as fast as it was > before. I think it's fair to say, PHP has problems that are much bigger > than performance - to most developers, performance is not a pain point > anymore, if it was before PHP 7. > > I wish that I could change your focus from performance concerns to actually > focusing on the language itself. > > It seems that me that recent performance improvements have become somewhat > of a bottleneck that *prevents* new features and (worse) missing features > from completing and improving the language? > > The performance improvements could just as well be viewed as a factor that > creates new elbow room for new features and language improvements, which, > long term, likely have much more value to more developers than the > performance of micro-benchmarks. > > At the end of the day, for like 9 our of 10 projects, PHP's core > performance is not the bottleneck - things like database queries are. The > cost of developing a project is also generally unrelated to core > performance of the language. Hardware gets cheaper and faster every day. So > who or what are we optimizing for? > > I don't mean to get too side-tracked from the original conversation here, > but we should be designing for developers - not for machines. The language > is more than fast enough for what most developers need it for - and still > nowhere near fast enough for, say, a JSON or XML parser, the kind of things > that require C or assembly level performance, and I really don't believe > there's a substantial segment of use-cases that fall in between - for most > things, either you need performance that PHP can't get near, or you need > language features and convenience that low-level languages can't deliver. > > We're not competing with C - and if we're competing with other scripting > languages on performance, we're already in a pretty good position, and > people who select a scripting language aren't basing their choice on raw > performance in the first place; if that was their concern, they'd pick C. > > We should focus on competing with other scripting languages on features, > convenience, productivity, etc. - if our main concern is competing on > low-level concerns like performance, those concerns will override the > points that really matter to developers who choose a high-level scripting > language, and we will lose. > > > On Sun, Aug 7, 2016 at 1:29 PM, Nikita Popov <nikita.ppv@gmail.com> wrote: > >> On Sun, Aug 7, 2016 at 1:19 PM, Rasmus Schultz <rasmus@mindplay.dk> wrote: >> >>> I'd really like to see the function auto-loading proposal revived and/or >>> possibly simplified. >>> >>> The fact that functions are hard (in some cases impossible) to reach by >>> manually issuing require/include statements is, in my opinion, half the >>> difficulty, and a much more deeply rooted language problem exacerbating >>> what should be trivial problems - e.g. install a Composer package, import >>> (use) and call the functions. >>> >>> Looks like a fair amount of work and discussion was done in 2013 on this >>> RFC: >>> >>> https://wiki.php.net/rfc/function_autoloading >>> >>> There was a (now stale) proof of concept implementation for the parent RFC >>> as well: >>> >>> https://wiki.php.net/rfc/function_autoloading2 >>> >>> What happened? >>> >>> It looks like the discussion stalled mostly over some concerns, including >>> reservations about performance, which were already disproved? >>> >>> One issue apparently was left unaddressed, that of whether a call to an >>> undefined function should generate an auto-load call to a namespaced or >>> global function - I think this would not be difficult to address: trigger >>> auto-loading of the namespaced function first, check if it was loaded, and >>> if not, trigger auto-loading of the global function. >> >> >> I feel like the problem here did not get across properly. Calling the >> autoloader if a global function with the name exists will totally kill >> performance. This means that every call to strpos() or any of the other >> functions in the PHP standard library will have to go through the >> autoloader first, unless people use fully qualified names (which, >> currently, they don't). This is completely out of the question. >> >> (The case where neither the namespaced nor the global function exists is >> not the problem. In that case calling the autoloader for the namespaced and >> non-namespaced names in sequence is of course unproblematic.) >> >> Nikita >> >> >>> Most likely a PSR >>> along with Composer auto-loading features will favor a best practice of >>> shipping packages with namespaced functions only, so the performance >>> implications of checking twice would be negligible in practice. >>> >>> Being basically unable to ship or consume purely functional packages >>> leaves >>> the functional side of the language largely an unused historical artifact, >>> which is sad. Keeping things functional and stateless often lead to more >>> predictable and obvious code - I think the absence of good support for >>> functions encourages a lot of over-engineering, e.g. developers >>> automatically making everything a class, not as a design choice, for the >>> sole reason of being able to ship and reuse what should be simple >>> functions. >>> >>> This RFC looks pretty solid to me. >>> >>> What will it take to get this rolling again? >>> >> >>
-- David Rodrigues

Davey

10 years ago
On Sun, Aug 7, 2016 at 12:32 PM, David Rodrigues <david.proweb@gmail.com> wrote:
> What should be the difference between a static method on a autoloaded > class? > > I guess that it could be done currently by use a static method. > In this case, I know exactly what method should be called, without > depends of an autoloader response. > > class String { > public static function strpos(...) { ... } > } > > In this case, I just need to call String::strpos(...) and done. > > I don't know if I'm missing something. > > 2016-08-07 9:07 GMT-03:00 Rasmus Schultz <rasmus@mindplay.dk>: > > Of course calling e.g. strpos() should not trigger the auto-loader > > repeatedly - can we cache the information that the auto-loader was > > attempted once during the current script execution? so that e.g. only the > > first call to strpos() triggers the auto-loader? > > > > I suppose it would still happen once for every namespace from which > > strpos() gets called, so maybe this optimization doesn't help much. > > > > I guess I'd say, benchmark it before making assumptions? Maybe the > > performance hit turns out to be negligible in practice. Hard to say. > > > > If a performance hit is inevitable, but marginal, I hope that we do not > let > > micro-benchmarks stand in the way of improving the language? > > > > With PHP 7, the language is in many ways almost twice as fast as it was > > before. I think it's fair to say, PHP has problems that are much bigger > > than performance - to most developers, performance is not a pain point > > anymore, if it was before PHP 7. > > > > I wish that I could change your focus from performance concerns to > actually > > focusing on the language itself. > > > > It seems that me that recent performance improvements have become > somewhat > > of a bottleneck that *prevents* new features and (worse) missing features > > from completing and improving the language? > > > > The performance improvements could just as well be viewed as a factor > that > > creates new elbow room for new features and language improvements, which, > > long term, likely have much more value to more developers than the > > performance of micro-benchmarks. > > > > At the end of the day, for like 9 our of 10 projects, PHP's core > > performance is not the bottleneck - things like database queries are. The > > cost of developing a project is also generally unrelated to core > > performance of the language. Hardware gets cheaper and faster every day. > So > > who or what are we optimizing for? > > > > I don't mean to get too side-tracked from the original conversation here, > > but we should be designing for developers - not for machines. The > language > > is more than fast enough for what most developers need it for - and still > > nowhere near fast enough for, say, a JSON or XML parser, the kind of > things > > that require C or assembly level performance, and I really don't believe > > there's a substantial segment of use-cases that fall in between - for > most > > things, either you need performance that PHP can't get near, or you need > > language features and convenience that low-level languages can't deliver. > > > > We're not competing with C - and if we're competing with other scripting > > languages on performance, we're already in a pretty good position, and > > people who select a scripting language aren't basing their choice on raw > > performance in the first place; if that was their concern, they'd pick C. > > > > We should focus on competing with other scripting languages on features, > > convenience, productivity, etc. - if our main concern is competing on > > low-level concerns like performance, those concerns will override the > > points that really matter to developers who choose a high-level scripting > > language, and we will lose. > > > > > > On Sun, Aug 7, 2016 at 1:29 PM, Nikita Popov <nikita.ppv@gmail.com> > wrote: > > > >> On Sun, Aug 7, 2016 at 1:19 PM, Rasmus Schultz <rasmus@mindplay.dk> > wrote: > >> > >>> I'd really like to see the function auto-loading proposal revived > and/or > >>> possibly simplified. > >>> > >>> The fact that functions are hard (in some cases impossible) to reach by > >>> manually issuing require/include statements is, in my opinion, half the > >>> difficulty, and a much more deeply rooted language problem exacerbating > >>> what should be trivial problems - e.g. install a Composer package, > import > >>> (use) and call the functions. > >>> > >>> Looks like a fair amount of work and discussion was done in 2013 on > this > >>> RFC: > >>> > >>> https://wiki.php.net/rfc/function_autoloading > >>> > >>> There was a (now stale) proof of concept implementation for the parent > RFC > >>> as well: > >>> > >>> https://wiki.php.net/rfc/function_autoloading2 > >>> > >>> What happened? > >>> > >>> It looks like the discussion stalled mostly over some concerns, > including > >>> reservations about performance, which were already disproved? > >>> > >>> One issue apparently was left unaddressed, that of whether a call to an > >>> undefined function should generate an auto-load call to a namespaced or > >>> global function - I think this would not be difficult to address: > trigger > >>> auto-loading of the namespaced function first, check if it was loaded, > and > >>> if not, trigger auto-loading of the global function. > >> > >> > >> I feel like the problem here did not get across properly. Calling the > >> autoloader if a global function with the name exists will totally kill > >> performance. This means that every call to strpos() or any of the other > >> functions in the PHP standard library will have to go through the > >> autoloader first, unless people use fully qualified names (which, > >> currently, they don't). This is completely out of the question. > >> > >> (The case where neither the namespaced nor the global function exists is > >> not the problem. In that case calling the autoloader for the namespaced > and > >> non-namespaced names in sequence is of course unproblematic.) > >> > >> Nikita > >> > >> > >>> Most likely a PSR > >>> along with Composer auto-loading features will favor a best practice of > >>> shipping packages with namespaced functions only, so the performance > >>> implications of checking twice would be negligible in practice. > >>> > >>> Being basically unable to ship or consume purely functional packages > >>> leaves > >>> the functional side of the language largely an unused historical > artifact, > >>> which is sad. Keeping things functional and stateless often lead to > more > >>> predictable and obvious code - I think the absence of good support for > >>> functions encourages a lot of over-engineering, e.g. developers > >>> automatically making everything a class, not as a design choice, for > the > >>> sole reason of being able to ship and reuse what should be simple > >>> functions. > >>> > >>> This RFC looks pretty solid to me. > >>> > >>> What will it take to get this rolling again? >
Perhaps the solution is to look at this as a forward-only feature, rather than a backfill. We only support autoloading for unambiguous names — if you want the autoloader to be called, either import the function with use, or use a [fully] qualified name. This should remove the ambiguities and performance concerns. - Davey

Rowan Collins

10 years ago
On 07/08/2016 23:42, Davey Shafik wrote:
> Perhaps the solution is to look at this as a forward-only feature, rather > than a backfill. > > We only support autoloading for unambiguous names — if you want the > autoloader to be called, either > import the function with use, or use a [fully] qualified name. > > This should remove the ambiguities and performance concerns.
I actually quite like this suggestion, because it fits with the use case I see as being most common: replacing static-only classes with a namespace of related functions. (Remember that "static classes" were rejected at RFC in favour of exactly this.) To be clear, the case we'd be "refusing" to autoload (other than global functions themselves) would be a function in the *exact* current namespace: namespace Acme\Foo\Bar; do_something(); // won't autoload But that only matters if namespace "\Acme\Foo\Bar" is split over multiple files. In this case, the declaration of "Acme\Foo\Bar\do_something()" would probably be in the same file anyway, so not need autoloading. Given that we have hierarchical namespaces, this seems a more likely scenario: namespace Acme\Foo\Bar; // function autoload for 'Acme\Foo\Bar\Utilities\do_something' Utilities\do_something(); Or importing as an alias: namespace Acme\Foo\Bar; use Acme\Stuff\Utilities as Util; // function autoload for 'Acme\Stuff\Utilities\do_something' Util\do_something(); Note that an unqualified function call "do_something()" already doesn't look in any imported namespaces, so "use Acme\Stuff\Utilities;" doesn't do anything to function name resolution. So we would be defining a simple rule: "the function autoloader will be called at run time for any namespace-qualified function name which is not already defined". This feels like a better compromise than an autoload cache, because I can see the invalidation rules getting messy, and heavily-used global functions still firing the autoloader for many different possible prefixes. Regards,
-- Rowan Collins [IMSoP]

Nikita Popov

10 years ago
On Mon, Aug 8, 2016 at 12:51 PM, Rowan Collins <rowan.collins@gmail.com> wrote:
> On 07/08/2016 23:42, Davey Shafik wrote: > >> Perhaps the solution is to look at this as a forward-only feature, rather >> than a backfill. >> >> We only support autoloading for unambiguous names — if you want the >> autoloader to be called, either >> import the function with use, or use a [fully] qualified name. >> >> This should remove the ambiguities and performance concerns. >> > > I actually quite like this suggestion, because it fits with the use case I > see as being most common: replacing static-only classes with a namespace of > related functions. (Remember that "static classes" were rejected at RFC in > favour of exactly this.) > > > To be clear, the case we'd be "refusing" to autoload (other than global > functions themselves) would be a function in the *exact* current namespace: > > namespace Acme\Foo\Bar; > do_something(); // won't autoload > > But that only matters if namespace "\Acme\Foo\Bar" is split over multiple > files. In this case, the declaration of "Acme\Foo\Bar\do_something()" would > probably be in the same file anyway, so not need autoloading. > > > Given that we have hierarchical namespaces, this seems a more likely > scenario: > > namespace Acme\Foo\Bar; > // function autoload for 'Acme\Foo\Bar\Utilities\do_something' > Utilities\do_something(); > > Or importing as an alias: > > namespace Acme\Foo\Bar; > use Acme\Stuff\Utilities as Util; > // function autoload for 'Acme\Stuff\Utilities\do_something' > Util\do_something(); > > > Note that an unqualified function call "do_something()" already doesn't > look in any imported namespaces, so "use Acme\Stuff\Utilities;" doesn't do > anything to function name resolution. > > So we would be defining a simple rule: "the function autoloader will be > called at run time for any namespace-qualified function name which is not > already defined". > > > This feels like a better compromise than an autoload cache, because I can > see the invalidation rules getting messy, and heavily-used global functions > still firing the autoloader for many different possible prefixes. >
I like this idea as well. In a previous thread I suggested to delay the autoloader call for unqualified function calls until after the check for an existing global function. But just not calling the autoloader at all for unqualified calls is the better solution, as it removes one pretty arbitrary factor (does this global function exist?) from the autoloader behavior. Nikita

Stas Malyshev

10 years ago
Hi!
> Of course calling e.g. strpos() should not trigger the auto-loader > repeatedly - can we cache the information that the auto-loader was > attempted once during the current script execution? so that e.g. only the > first call to strpos() triggers the auto-loader?
I think triggering it even once for *every* internal function in the code may be too much.
> I suppose it would still happen once for every namespace from which > strpos() gets called, so maybe this optimization doesn't help much.
Exactly. Also, caching stuff assumes static environment. What if it changes, e.g. autoloader gets different configuration?
-- Stas Malyshev smalyshev@gmail.com

Levi Morrison

10 years ago
> > > I feel like the problem here did not get across properly. Calling the > autoloader if a global function with the name exists will totally kill > performance. This means that every call to strpos() or any of the other > functions in the PHP standard library will have to go through the > autoloader first, unless people use fully qualified names (which, > currently, they don't). This is completely out of the question. >
Interesting. I come to a different conclusion: this a great opportunity to get developers to use the fully qualified names. Performance is an incredibly motivating force even in many situations when it shouldn't be.

Rowan Collins

10 years ago
On 08/08/2016 15:36, Levi Morrison wrote:
>> I feel like the problem here did not get across properly. Calling the >> autoloader if a global function with the name exists will totally kill >> performance. This means that every call to strpos() or any of the other >> functions in the PHP standard library will have to go through the >> autoloader first, unless people use fully qualified names (which, >> currently, they don't). This is completely out of the question. >> > > Interesting. I come to a different conclusion: this a great opportunity to > get developers to use the fully qualified names. Performance is an > incredibly motivating force even in many situations when it shouldn't be.
An example just to focus the mind: namespace Lovely\New\Code; class Blah { function __construct(array $foo) { foreach ( $foo as $item ) { if ( strpos('blah', $item) !== 0 ) { // ... } } } } This will *repeatedly* call the function autoloader for "Lovely\New\Code\strpos". The fully qualified name in this case is "\strpos". I think saying "add a backslash in front of your function names to avoid them being slow" will just lead to lots of "lol wtf php sux". If we wanted to make the \ mandatory, then the name resolution for functions could have had no fallback, just like class names. The reasons for having that fallback presumably still apply, so it doesn't make sense to now declare it "broken by design, please avoid". On the other hand, saying "you can autoload functions from another namespace using qualified names or 'use function'" sidesteps the fallback issue, and sounds like a reasonable, non-BC-breaking, feature. Regards,
-- Rowan Collins [IMSoP]

Michał Brzuchalski

10 years ago
IMHO if there were possibility to provide scalar objects like in Nikic extension https://nikic.github.io/2014/03/14/Methods-on-primitive-types-in-PHP.html most of str* and many other functions could be called wythout FQN simply from variable. Most of global scope functions interacting with scalars could be called throught object handlers. In many legacy applications there still could be possibility to call global functions. Most of legacy applications have no namespace (Wordpress) so there is even no need for FQN for function calls. 2016-08-08 16:56 GMT+02:00 Rowan Collins <rowan.collins@gmail.com>:
> On 08/08/2016 15:36, Levi Morrison wrote: > >> I feel like the problem here did not get across properly. Calling the >>> autoloader if a global function with the name exists will totally kill >>> performance. This means that every call to strpos() or any of the other >>> functions in the PHP standard library will have to go through the >>> autoloader first, unless people use fully qualified names (which, >>> currently, they don't). This is completely out of the question. >>> >>> >> Interesting. I come to a different conclusion: this a great opportunity to >> get developers to use the fully qualified names. Performance is an >> incredibly motivating force even in many situations when it shouldn't be. >> > > An example just to focus the mind: > > namespace Lovely\New\Code; > > class Blah { > function __construct(array $foo) { > foreach ( $foo as $item ) { > if ( strpos('blah', $item) !== 0 ) { > // ... > } > } > } > } > > > This will *repeatedly* call the function autoloader for > "Lovely\New\Code\strpos". The fully qualified name in this case is > "\strpos". > > I think saying "add a backslash in front of your function names to avoid > them being slow" will just lead to lots of "lol wtf php sux". > > If we wanted to make the \ mandatory, then the name resolution for > functions could have had no fallback, just like class names. The reasons > for having that fallback presumably still apply, so it doesn't make sense > to now declare it "broken by design, please avoid". > > On the other hand, saying "you can autoload functions from another > namespace using qualified names or 'use function'" sidesteps the fallback > issue, and sounds like a reasonable, non-BC-breaking, feature. > > > Regards, > -- > Rowan Collins > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- pozdrawiam -- Michał Brzuchalski

Levi Morrison

10 years ago
> > I think saying "add a backslash in front of your function names to avoid > them being slow" will just lead to lots of "lol wtf php sux". >
They'll say the same when function and class autoloading don't work the same way anyway. I think unifying their behavior over time is the best solution forward. Yes, I'm talking about a BC break eventually, but the suggestion to autoload only fully qualified function names could buy us the time to make that BC break less severe.

Niklas Keller

10 years ago
2016-08-08 18:00 GMT+02:00 Levi Morrison <levim@php.net>:
> > > > I think saying "add a backslash in front of your function names to avoid > > them being slow" will just lead to lots of "lol wtf php sux". > > > > They'll say the same when function and class autoloading don't work the > same way anyway. I think unifying their behavior over time is the best > solution forward. Yes, I'm talking about a BC break eventually, but the > suggestion to autoload only fully qualified function names could buy us the > time to make that BC break less severe. >
Loading only full qualified names will lead to strange bugs.

Rowan Collins

10 years ago
On 08/08/2016 17:23, Niklas Keller wrote:
> Loading only full qualified names will lead to strange bugs.
The suggestion is to require *qualified* names (at least one \ in the call), not to require *fully qualified* names (leading \ and full namespace path). Function name resolution already requires that to reference anything other than a global function, or the exact current namespace. The only scheme I can think of where it would matter is one-function-per-file, like Smarty's plugin loader. # file foo.php namespace Acme\Plugins; function foo() { echo 'Hello world'; } # file bar.php namespace Acme\Plugins; function bar() { foo(); } # will not autoload Compared to "hundreds of lines of existing code will go slowly unless you liberally sprinkle with \", having to remind people not to do that seems like a small price to pay. Regards,
-- Rowan Collins [IMSoP]

Rowan Collins

10 years ago
On 08/08/2016 17:00, Levi Morrison wrote:
> I think saying "add a backslash in front of your function names to > avoid them being slow" will just lead to lots of "lol wtf php sux". > > > They'll say the same when function and class autoloading don't work the > same way anyway. I think unifying their behavior over time is the best > solution forward. Yes, I'm talking about a BC break eventually, but the > suggestion to autoload only fully qualified function names could buy us > the time to make that BC break less severe.
Do you mean eventually changing the name resolution rules for functions to match those for classes? I wasn't around at the time it was discussed, and if we were adding them now would be tempted to say the leading \ should always be mandatory, just like it is for classes. But since we have what we have, I don't see that big an advantage to changing it. If not, I don't see why we ever need to be able to autoload global functions. "You want autoloading? Put it in a namespace." Like I say, that leaves the very small edge case of a single namespace spanning multiple files, and an autoloader implementation able to include one of them when a function is called from another. Regards,
-- Rowan Collins [IMSoP]

Levi Morrison

10 years ago
> > If not, I don't see why we ever need to be able to autoload global > functions. "You want autoloading? Put it in a namespace." Like I say, that > leaves the very small edge case of a single namespace spanning multiple > files, and an autoloader implementation able to include one of them when a > function is called from another.
I'm not sure why you would think a single namespace spanning multiple files is a "very small edge case". I disagree. Here are some libraries I am aware of *off the top of my head* that use functions the same namespace across multiple files: - https://github.com/nikic/iter - https://github.com/lstrojny/functional-php As well as several of my personal projects. I do not think this is a "very small edge case."

Rowan Collins

10 years ago
On 08/08/2016 18:03, Levi Morrison wrote:
> If not, I don't see why we ever need to be able to autoload global > functions. "You want autoloading? Put it in a namespace." Like I > say, that leaves the very small edge case of a single namespace > spanning multiple files, and an autoloader implementation able to > include one of them when a function is called from another. > > > I'm not sure why you would think a single namespace spanning multiple > files is a "very small edge case". I disagree. Here are some libraries I > am aware of *off the top of my head* that use functions the same > namespace across multiple files: > > * https://github.com/nikic/iter > * https://github.com/lstrojny/functional-php > > As well as several of my personal projects. I do not think this is a > "very small edge case."
The "iter" example looks a long way from being autoloadable whatever we supported, but the example of one-function-per-file is definitely relevant, so I stand corrected. After a bit of clicking, I even managed to find a line which would fail to autoload under the proposed limitation: https://github.com/lstrojny/functional-php/blob/master/src/Functional/CompareObjectHashOn.php
> return compare_on($comparison, $keyFunction);
Although interestingly, at the top of the file there is a (technically unnecessary) "use function Functional\compose;" If there was a "use function Functional\compare_on;" as well, we'd be fine. (The function name would then become qualified at compile time and trigger autoloading at run time.) On 08/08/2016 18:06, Rasmus Schultz wrote:
> Unless there's a demonstrated, critical performance issue with > auto-loading of global functions, please, let's not cripple this feature > with inconsistencies from the get-go!
Sure, we could try to measure it, but remember that it's not just the engine code that has the extra cost, it will actually call a userland function every time you use a global function from inside a namespace if you don't add a leading "\". That userland function will probably do a bunch of string comparisons before deciding it's not interested, and may even try to stat a file or two. Those are really expensive operations, so I think it's a long way from "micro-optimisation". Unfortunately, function name resolution has this quirk that class name resolution doesn't, so something's got to give. Regards,
-- Rowan Collins [IMSoP]

Rasmus Schultz

10 years ago
> Unfortunately, function name resolution has this quirk that class name
resolution doesn't, so something's got to give. I suppose. Well, then, how about making the feature work consistently for all functions, by coupling it directly to the "use function" statement? In other words, the feature changes from being strictly about auto-loading functions, to instead resolving an imported function - so it would be triggered by the "use function" statement only, rather than by the use of the function, and the resolved function pertains only to the scope of the file. A function resolver would simply need to return a callable: register_function_resolver(function ($name) { if ($name === "html") { return function ($str) { return htmlspecialchars($str, ENT_HTML5); }; } if (substr($name, 0, 5) === "iter\\") { require_once VENDOR_PATH."/nikic/iter/src/bootstrap.php"; return $name; } }); This mechanism is probably a lot easier to explain and understand - and works equally for global or namespaced functions. It also lets you potentially do other weird shit, like overriding var_dump() or hooking into certain function calls - which could enable you to do a bunch of evil, but I'm not really big on complicating features solely to keep users from doing harm; simpler language features tend to allow you to do more stuff - good or evil. Likely the 99% use-case is simply for Composer to bootstrap your packages for you, and this feature will permit you to do that. Okay, so it doesn't deal with namespaced constants, and maybe this is me being opinionated, but who's going to import constants one by one? Constants are usually better off grouped together in a class. Although I don't suppose there's any reason this concept couldn't be expanded to work for constants as well, for completeness at least - though I have doubts that very many people would care... Anyways, just spitballing here :-) On Mon, Aug 8, 2016 at 7:54 PM, Rowan Collins <rowan.collins@gmail.com> wrote:

Davey

10 years ago
On Mon, Aug 8, 2016 at 1:15 PM, Rasmus Schultz <rasmus@mindplay.dk> wrote:
> > Unfortunately, function name resolution has this quirk that class name > resolution doesn't, so something's got to give. > > I suppose. > > Well, then, how about making the feature work consistently for all > functions, by coupling it directly to the "use function" statement? > > In other words, the feature changes from being strictly about auto-loading > functions, to instead resolving an imported function - so it would be > triggered by the "use function" statement only, rather than by the use of > the function, and the resolved function pertains only to the scope of the > file. > > A function resolver would simply need to return a callable: > > register_function_resolver(function ($name) { > if ($name === "html") { > return function ($str) { > return htmlspecialchars($str, ENT_HTML5); > }; > } > > if (substr($name, 0, 5) === "iter\\") { > require_once VENDOR_PATH."/nikic/iter/src/bootstrap.php"; > return $name; > } > }); > > This mechanism is probably a lot easier to explain and understand - and > works equally for global or namespaced functions. > > It also lets you potentially do other weird shit, like overriding > var_dump() or hooking into certain function calls - which could enable you > to do a bunch of evil, but I'm not really big on complicating features > solely to keep users from doing harm; simpler language features tend to > allow you to do more stuff - good or evil. > > Likely the 99% use-case is simply for Composer to bootstrap your packages > for you, and this feature will permit you to do that. > > Okay, so it doesn't deal with namespaced constants, and maybe this is me > being opinionated, but who's going to import constants one by one? > Constants are usually better off grouped together in a class. Although I > don't suppose there's any reason this concept couldn't be expanded to work > for constants as well, for completeness at least - though I have doubts > that very many people would care... > > Anyways, just spitballing here :-) > > > On Mon, Aug 8, 2016 at 7:54 PM, Rowan Collins <rowan.collins@gmail.com> > wrote: > > > On 08/08/2016 18:03, Levi Morrison wrote: > > > >> If not, I don't see why we ever need to be able to autoload global > >> functions. "You want autoloading? Put it in a namespace." Like I > >> say, that leaves the very small edge case of a single namespace > >> spanning multiple files, and an autoloader implementation able to > >> include one of them when a function is called from another. > >> > >> > >> I'm not sure why you would think a single namespace spanning multiple > >> files is a "very small edge case". I disagree. Here are some libraries I > >> am aware of *off the top of my head* that use functions the same > >> namespace across multiple files: > >> > >> * https://github.com/nikic/iter > >> * https://github.com/lstrojny/functional-php > >> > >> As well as several of my personal projects. I do not think this is a > >> "very small edge case." > >> > > > > The "iter" example looks a long way from being autoloadable whatever we > > supported, but the example of one-function-per-file is definitely > relevant, > > so I stand corrected. > > > > After a bit of clicking, I even managed to find a line which would fail > to > > autoload under the proposed limitation: > > > > https://github.com/lstrojny/functional-php/blob/master/src/ > > Functional/CompareObjectHashOn.php > > > > > return compare_on($comparison, $keyFunction); > > > > Although interestingly, at the top of the file there is a (technically > > unnecessary) "use function Functional\compose;" If there was a "use > > function Functional\compare_on;" as well, we'd be fine. (The function > name > > would then become qualified at compile time and trigger autoloading at > run > > time.) > > > > > > On 08/08/2016 18:06, Rasmus Schultz wrote: > > > Unless there's a demonstrated, critical performance issue with > > > auto-loading of global functions, please, let's not cripple this > feature > > > with inconsistencies from the get-go! > > > > Sure, we could try to measure it, but remember that it's not just the > > engine code that has the extra cost, it will actually call a userland > > function every time you use a global function from inside a namespace if > > you don't add a leading "\". That userland function will probably do a > > bunch of string comparisons before deciding it's not interested, and may > > even try to stat a file or two. Those are really expensive operations, > so I > > think it's a long way from "micro-optimisation". > > > > Unfortunately, function name resolution has this quirk that class name > > resolution doesn't, so something's got to give. > > > > > > Regards, >
Related to this, I'd like to see stream (and stream filter) autoloading. Essentially, if you fopen("random://foo") it'll pass that string to an autoloader that will load and register the stream. It fails if at the end of the autoloader the stream isn't registered. Similar for filter and stream_filter_(pre|ap)pend() and loading stream filters. - Davey

Rowan Collins

10 years ago
On 08/08/2016 21:15, Rasmus Schultz wrote:
> A function resolver would simply need to return a callable: > > register_function_resolver(function ($name) { > if ($name === "html") { > return function ($str) { > return htmlspecialchars($str, ENT_HTML5); > }; > } > > if (substr($name, 0, 5) === "iter\\") { > require_once VENDOR_PATH."/nikic/iter/src/bootstrap.php"; > return $name; > } > }); > > This mechanism is probably a lot easier to explain and understand - > and works equally for global or namespaced functions.
I don't quite follow what you're suggesting here. When does this "function resolver" get called? Why does returning a callable rather than just defining the function help with the problems we've been discussing?
> Okay, so it doesn't deal with namespaced constants, and maybe this is > me being opinionated, but who's going to import constants one by one? > Constants are usually better off grouped together in a class. Although > I don't suppose there's any reason this concept couldn't be expanded > to work for constants as well, for completeness at least - though I > have doubts that very many people would care...
It's not a case of importing constants - or, in most cases, functions - one by one. As I've mentioned a couple of times, an RFC on static classes [https://wiki.php.net/rfc/abstract_final_class] and various similar discussions are frequently met with "you shouldn't be using a class to group static items, use a namespace instead". For that we need "namespace autoloading", which in practice means autoloading any of the items you can put in a namespace. We can already autoload classes, so that leaves constants and functions. Regards,
-- Rowan Collins [IMSoP]

Rasmus Schultz

10 years ago
> If not, I don't see why we ever need to be able to autoload global
functions Well, for consistency. For one, if you're refactoring a global function to a namespaced one, this inconsistency is going to be surprising. In general, any inconsistency in a language is surprising. Why only non-global functions can autoload, is going to require a longer explanation. And that's bad. If we support auto-loading only for namespaced functions, we're actively favoring (potentially micro-) performance over consistency. I use global functions. I know that's not popular, but it's a language feature, and I use it - for things like test-frameworks and global view helper-functions. Single namespace spanning multiple files is also a case for me - that's not a decision we should make; likely, a PSR and Composer auto-loading features will drive those decisions. One should have the freedom to add a new function to an existing namespace, and make that function auto-load, while packaging that function as a separate optionally-installable package. I can't see the introduction of arbitrary restrictions or limitations leading to anything good, language-wise. Unless there's a demonstrated, critical performance issue with auto-loading of global functions, please, let's not cripple this feature with inconsistencies from the get-go! On Mon, Aug 8, 2016 at 6:46 PM, Rowan Collins <rowan.collins@gmail.com> wrote:

Niklas Keller

10 years ago
2016-08-08 19:06 GMT+02:00 Rasmus Schultz <rasmus@mindplay.dk>:
> > If not, I don't see why we ever need to be able to autoload global > functions > > Well, for consistency. >
Not only for consistency, but also for things like polyfills, e.g. random_compat. Regards, Niklas

Lester Caine

10 years ago
On 07/08/16 12:19, Rasmus Schultz wrote:
> Being basically unable to ship or consume purely functional packages leaves > the functional side of the language largely an unused historical artifact, > which is sad. Keeping things functional and stateless often lead to more > predictable and obvious code - I think the absence of good support for > functions encourages a lot of over-engineering, e.g. developers > automatically making everything a class, not as a design choice, for the > sole reason of being able to ship and reuse what should be simple functions.
I can understand a little the overwhelming desire to wrap everything in it's own set of name spaces, but is that REALLY essential to make PHP 'work better'. What is wrong with a simple 'include_once' of the library you want to use globally across all the code? I have a set of legacy libraries who's function is not going to change any time soon which works just the same on old setup's as it does on PHP7. And I see no reason to even bother with namespace's ... they simply make a lot of mess for no apparent gain! Where I could see a gain is if those libraries were simply additional extensions pre-loaded into the engine rather than something which needs 'auto-loading' at all.
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Rasmus Schultz

10 years ago
On Mon, Aug 8, 2016 at 10:54 PM, Lester Caine <lester@lsces.co.uk> wrote:
> I can understand a little the overwhelming desire to wrap everything in > it's own set of name spaces, but is that REALLY essential to make PHP > 'work better'. What is wrong with a simple 'include_once' of the library > you want to use globally across all the code?
Doesn't work with Composer packages, because you can't (and aren't supposed to) know where a package is installed. That is, when I'm running the test-suite of my package, the Composer project is the root folder of that package - but when the package is being consumed by another project, it's installed in a sub-folder in that project's "vendor" folder. The whole point of auto-loading is you don't need to know where things are installed - a class will simply auto-load, regardless of whether or not the package is the root project package of the consuming package. Composer takes care of the bootstrapping. If we didn't care about that, we wouldn't need auto-loading at all. Or in other words, your argument works against auto-loading of functions and classes equally. What's wrong with a simple require/include statement when you need a class? Nothing per se. It's horribly inconvenient. The main reason you're not feeling the same inconvenience when it comes to functions, is likely because you avoid using them - which is likely because using functions isn't practical. Likely because they don't auto-load, like functions. So we use classes as pseudo-namespaces, because they can auto-load - but that's not what classes are for; you could just as well argue the language shouldn't have functions at all, then. In a nut-shell: functions are inconvenient because they don't auto-load, so we don't use functions, so we don't need auto-loading; but that's a circular argument. Of course we need functions to auto-load. For all the same reasons we need classes to auto-load. Nobody wants to stop and have to figure out in which file a function is located before they can call it, anymore than they want to do so for classes. Nobody wants breaking changes in 50 different files because they renamed a file or decided to split/join some functions across some files. The auto-loading requirement for functions is the same as for classes. There's no difference.

Lester Caine

10 years ago
On 08/08/16 22:59, Rasmus Schultz wrote:
> Doesn't work with Composer packages, because you can't (and aren't > supposed to) know where a package is installed. > > That is, when I'm running the test-suite of my package, the Composer > project is the root folder of that package - but when the package is > being consumed by another project, it's installed in a sub-folder in > that project's "vendor" folder.
So Composer IS now the rule rather than some optional extra? It is OK for users who only want to load the one application, but when one is running a large number of different packages it's a major hindrance. I don't need to know where my Linux install has put the include files ... it takes care of that and then finding the pigging things again is the problem. Much the same with finding the source of problems in the mess that composer has created!
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Sara Golemon

10 years ago
On Mon, Aug 8, 2016 at 9:59 PM, Lester Caine <lester@lsces.co.uk> wrote:
>> That is, when I'm running the test-suite of my package, the Composer >> project is the root folder of that package - but when the package is >> being consumed by another project, it's installed in a sub-folder in >> that project's "vendor" folder. > > So Composer IS now the rule rather than some optional extra? >
Yes, the community has decided that for us. Or at least, Composer is a *significant* player in the ecosystem of PHP development. require_once() might be fine for NiH applications, but for the collaborative world of modern PHP, it's the defacto standard.
> It is OK > for users who only want to load the one application, but when one is > running a large number of different packages it's a major hindrance. >
You'll need to back that up with some more detail. Composer is specifically designed to _compose_ through multiple packages and also allows for isolation when that sort of blending doesn't make sense. Far from a hinderance.
> I don't need to know where my Linux install has put the include files ... > it takes care of that and then finding the pigging things again is the > problem. >
So, autotools and cmake and the like exist for what purpose then? Even pkg-config, which was supposed to solve much of this problem is incomplete, at least on GNU distributions, falls short.
> Much the same with finding the source of problems in the mess > that composer has created! >
[citation required] -Sara

Lester Caine

10 years ago
On 09/08/16 06:54, Sara Golemon wrote:
> On Mon, Aug 8, 2016 at 9:59 PM, Lester Caine <lester@lsces.co.uk> wrote: >>> That is, when I'm running the test-suite of my package, the Composer >>> project is the root folder of that package - but when the package is >>> being consumed by another project, it's installed in a sub-folder in >>> that project's "vendor" folder. >> >> So Composer IS now the rule rather than some optional extra? >> > Yes, the community has decided that for us. Or at least, Composer is > a *significant* player in the ecosystem of PHP development. > require_once() might be fine for NiH applications, but for the > collaborative world of modern PHP, it's the defacto standard.
Much as PSR also does. This is probably fine if one is starting a project from scratch, but with now 15+ years worth of code that does not follow this 'modern style' it's another barrier to moving code forward. There is nothing wrong with the code other than newer users done approve of the style of working :(
>> It is OK >> for users who only want to load the one application, but when one is >> running a large number of different packages it's a major hindrance. >> > You'll need to back that up with some more detail. Composer is > specifically designed to _compose_ through multiple packages and also > allows for isolation when that sort of blending doesn't make sense. > Far from a hinderance.
Several packages that I have been trying to update have said that it's better NOT to use composer if you need to maintain a legacy view in addition to the newer code. Certainly having to keep different installs of PHP with different structures does not help the development process. It's bad enough running PHP5.4, 5.6 and 7 in parallel without also changing the framework as well.
>> I don't need to know where my Linux install has put the include files ... >> it takes care of that and then finding the pigging things again is the >> problem. >> > So, autotools and cmake and the like exist for what purpose then? > Even pkg-config, which was supposed to solve much of this problem is > incomplete, at least on GNU distributions, falls short.
There is not a 'single solution' that will fit the vast range of users of PHP but current targeting seems to be aimed at a subset of both coding style and practice at the expense of perfectly safe and functional existing code.
>> Much the same with finding the source of problems in the mess >> that composer has created! >> > [citation required]
I need to find the write-up on that. It was a well laid out blog on why pdt/eclipse had problems with the composer approach to managing legacy code.
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Peter Lind

10 years ago
On 10 August 2016 at 10:51, Lester Caine <lester@lsces.co.uk> wrote:
> On 09/08/16 06:54, Sara Golemon wrote: > > On Mon, Aug 8, 2016 at 9:59 PM, Lester Caine <lester@lsces.co.uk> wrote: > >> So Composer IS now the rule rather than some optional extra? > >> > > Yes, the community has decided that for us. Or at least, Composer is > > a *significant* player in the ecosystem of PHP development. > > require_once() might be fine for NiH applications, but for the > > collaborative world of modern PHP, it's the defacto standard. > > Much as PSR also does. > This is probably fine if one is starting a project from scratch, but > with now 15+ years worth of code that does not follow this 'modern > style' it's another barrier to moving code forward. There is nothing > wrong with the code other than newer users done approve of the style of > working :( > >
EVERYTHING is a barrier to moving your code forward. You tell the mailing this on a regular basis. Perhaps you should just migrate your 15+ year old code already and be done with it? Either that or fork PHP and never upgrade again. If you're this unhappy with any/all changes to PHP, that seems a viable option. Regards Peter
-- CV: careers.stackoverflow.com/peterlind LinkedIn: plind Twitter: kafe15

Bishop Bettini

10 years ago
On Wed, Aug 10, 2016 at 5:37 AM, Peter Lind <peter.e.lind@gmail.com> wrote:
> On 10 August 2016 at 10:51, Lester Caine <lester@lsces.co.uk> wrote: > > > On 09/08/16 06:54, Sara Golemon wrote: > > > On Mon, Aug 8, 2016 at 9:59 PM, Lester Caine <lester@lsces.co.uk> > wrote: > > >> So Composer IS now the rule rather than some optional extra? > > >> > > > Yes, the community has decided that for us. Or at least, Composer is > > > a *significant* player in the ecosystem of PHP development. > > > require_once() might be fine for NiH applications, but for the > > > collaborative world of modern PHP, it's the defacto standard. > > > > Much as PSR also does. > > This is probably fine if one is starting a project from scratch, but > > with now 15+ years worth of code that does not follow this 'modern > > style' it's another barrier to moving code forward. There is nothing > > wrong with the code other than newer users done approve of the style of > > working :( > > > > > EVERYTHING is a barrier to moving your code forward. You tell the mailing > this on a regular basis. > Perhaps you should just migrate your 15+ year old code already and be done > with it? > > Either that or fork PHP and never upgrade again. If you're this unhappy > with any/all changes to PHP, that seems a viable option. >
Please, let's keep the list clean of *ad hominem* reactions. Lester has a valid opinion, based on what seems to be a successful legacy of working code. That kind of code is essential PHP, and I, for one, value his perspective and welcome his feedback. If we break his code, or establish barriers to his code modernization efforts, we're probably doing the same to a whole class of users whom we might not hear from otherwise.

Peter Lind

10 years ago
On 10 Aug 2016 19:05, "Bishop Bettini" <bishop@php.net> wrote:
> > On Wed, Aug 10, 2016 at 5:37 AM, Peter Lind <peter.e.lind@gmail.com>
wrote:
>> >> On 10 August 2016 at 10:51, Lester Caine <lester@lsces.co.uk> wrote: >> >> > On 09/08/16 06:54, Sara Golemon wrote: >> > > On Mon, Aug 8, 2016 at 9:59 PM, Lester Caine <lester@lsces.co.uk>
wrote:
>> > >> So Composer IS now the rule rather than some optional extra? >> > >> >> > > Yes, the community has decided that for us. Or at least, Composer is >> > > a *significant* player in the ecosystem of PHP development. >> > > require_once() might be fine for NiH applications, but for the >> > > collaborative world of modern PHP, it's the defacto standard. >> > >> > Much as PSR also does. >> > This is probably fine if one is starting a project from scratch, but >> > with now 15+ years worth of code that does not follow this 'modern >> > style' it's another barrier to moving code forward. There is nothing >> > wrong with the code other than newer users done approve of the style of >> > working :( >> > >> > >> EVERYTHING is a barrier to moving your code forward. You tell the mailing >> this on a regular basis. >> Perhaps you should just migrate your 15+ year old code already and be
done
>> with it? >> >> Either that or fork PHP and never upgrade again. If you're this unhappy >> with any/all changes to PHP, that seems a viable option. > > > Please, let's keep the list clean of ad hominem reactions. Lester has a
valid opinion, based on what seems to be a successful legacy of working code. That kind of code is essential PHP, and I, for one, value his perspective and welcome his feedback. If we break his code, or establish barriers to his code modernization efforts, we're probably doing the same to a whole class of users whom we might not hear from otherwise. That was not an ad hominem attack. It was a description of the emails Lester send to the list. "Update your code or fork PHP" is not a particularly constructive comment. Neither, of course, is "don't make changes to my programming language of choice". Especially given that the feature discussed here would not actually directly influence Lester - he does not have to use it. In essence, Lester was arguing against this feature because others in the community would use it, and that would be a problem for him. From what i can tell, Lester has an infrastructure problem. Not a PHP problem. But he still wants to halt language development so the community doesn't pick up new features that might make problems in his code. That does not seem reasonable to me.

Lester Caine

10 years ago
On 10/08/16 20:36, Peter Lind wrote:
>>From what i can tell, Lester has an infrastructure problem. Not a PHP > problem. But he still wants to halt language development so the community > doesn't pick up new features that might make problems in his code. That > does not seem reasonable to me.
Yes I do have an infrastructure problem ... I can't see an easy way to switch from a traditional PHP model to one based on composer and PSR rules. Even processing legacy code much of which still uses little things like 'short tags' into a format that runs cleanly on later versions of PHP takes time. The scripts I have do a good job, but almost every site has had several hours bug checking to clear the remaining missed <?XXX elements and other errors just to make it run clean. With no changes to what the site actually does ... which is why there is no urgency to do that work ... and no 'pay' for doing it. The problem much of the time is that using third party libraries creates a minefield when those libraries decide now is the time to switch programming style and re-factor the whole code base. Does one stick with an older version and maintain that. Which is what I was doing with ADOdb, or do you re-factor the whole code base to work with the new style version ... to pick up the changes needed to work with other developments. Smarty is another key element of my infrastructure and I have at least four versions running across the system. The improvement in speed in PHP7 is now working in my code base, but I don't need any of the overheads of 'strict' mode simply because it's the wrong solution to the problem of data validation. Exceptions re-factoring is needed, but the piecemeal way exceptions are being hacked in is now showing the mistakes made so far, but 'traditional' code flow does not need exceptions so making them the only error return in new cases cases problems when they are not catered for in legacy code moved forward.
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Stas Malyshev

10 years ago
Hi!
> EVERYTHING is a barrier to moving your code forward. You tell the mailing > this on a regular basis. > Perhaps you should just migrate your 15+ year old code already and be done > with it?
I would like to note two things here: 1. We have a very diverse community and people have a lot of different needs and use cases. It is inevitable that some of these needs would be radically different from yours. Reacting with hostility to expressing such needs is not helping anybody. Anything of substance can be said in a neutral or cooperative tone. Let's strive for it. 2. Old code is literally 100% of code run on PHP now, with regard to 7.1 or any next.next version. Every application deployed is old code. And due to PHP's by now venerable history - yes, some of this code is very old, sometimes originating in PHP 4 code bases and beyond. This does not mean we have to be bound forever by it, but this also does not mean we should be dismissive about it and ignore it completely. As I said many times - and will say many times in the future, undoubtedly, until it improves - our adoption numbers for latest versions is nothing to be proud of. It is a problem we need to be aware of. If we design tons of new and shiny features and 0.0001% of the community ends up using them, it's not worth wasting the time IMHO. So in my opinion we should not be callous about the "never upgrade" option - because right now it's what a very sizeable part of the community already doing, and IMO this is *our* problem, not *theirs*.
-- Stas Malyshev smalyshev@gmail.com

Lester Caine

10 years ago
On 10/08/16 20:55, Stanislav Malyshev wrote:
> So in my opinion we should not be callous about the "never upgrade" > option - because right now it's what a very sizeable part of the > community already doing, and IMO this is *our* problem, not *theirs*.
I set up http://phpsurgery.org/ a few years back with every intention of adding content and tools to help with the upgrade process for users who in many cases do not know they are even running their sites on PHP :( If people have suitable material to help populate it then please feel free to forward it or contact me off list to set up a account. At some point I'll being THAT site up to the latest versions ... it's on a PHP5.4 base at the moment.
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Rowan Collins

10 years ago
On 10/08/2016 09:51, Lester Caine wrote:
> There is not a 'single solution' that will fit the vast range of users > of PHP but current targeting seems to be aimed at a subset of both > coding style and practice at the expense of perfectly safe and > functional existing code.
This entire thread is about trying to find ways for a new feature *not* to be "at the expense of" anything. If you don't want autoloading, that's fine. It was fine in 2004 when PHP 5 first allowed it; it was fine in 2009 when PHP 5.3 introduced namespaces; and it will be fine in 2017 even if we add something new to PHP 7.2. Perhaps rather than complaining that people are focussing on the "wrong" improvements to the language, you could come up with some well-thought-out suggestions of things you *would* like to see added. Regards,
-- Rowan Collins [IMSoP]

Michał Brzuchalski

10 years ago
@Peter and @Rowan: Very good point and sounds reasonable, I also thing there is need for evolution. Idea of fork PHP and never update made me laugh to tears :) 2016-08-10 11:42 GMT+02:00 Rowan Collins <rowan.collins@gmail.com>:
> On 10/08/2016 09:51, Lester Caine wrote: > >> There is not a 'single solution' that will fit the vast range of users >> of PHP but current targeting seems to be aimed at a subset of both >> coding style and practice at the expense of perfectly safe and >> functional existing code. >> > > This entire thread is about trying to find ways for a new feature *not* to > be "at the expense of" anything. If you don't want autoloading, that's > fine. It was fine in 2004 when PHP 5 first allowed it; it was fine in 2009 > when PHP 5.3 introduced namespaces; and it will be fine in 2017 even if we > add something new to PHP 7.2. > > Perhaps rather than complaining that people are focussing on the "wrong" > improvements to the language, you could come up with some well-thought-out > suggestions of things you *would* like to see added. > > Regards, > -- > Rowan Collins > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- pozdrawiam -- Michał Brzuchalski

Lester Caine

10 years ago
On 10/08/16 12:14, Michał Brzuchalski wrote:
> @Peter and @Rowan: Very good point and sounds reasonable, I also thing > there is need for evolution. Idea of fork PHP and never update made me > laugh to tears :)
To be quite honest ... I do now wish that I had simply forked PHP5.3 and maintained that with security fixes, although the ISP's who still support that have done a reasonable job. I decided that it was better to pull everybody over to PHP5.4 and so all the older services could be shut down, but it is not a 5 minute job transferring a legacy site and there are still a large number left to resolve. More irritating is that I have a framework that I've moved everything onto so as to loose the the legacy problems altogether, but while it runs perfectly cleanly on PHP7, it is not written in a style that allows things like 'namespace' to be integrated. Some of the libraries ARE being reworked in a manor that 'modernises' them, but most definitely breaks compatibility with existing code. Things like moving from Smarty 2 to Smarty 3 and then loosing the compatibility wrapper took months, but now the new 'loader' for Smarty 3 is clashing with the legacy Smarty based projects and it is that sort of hassle that simply crushes any pleasure in coding these days, when there is nothing gained by this move to 'auto-loading' libraries as the standard for everybody.
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk