Just a quick thought.
Since the autoloading functions proposal is stalled, how about allowing for
import of static functions instead?
use function Foo::bar;
bar(); // calls Foo::bar()
There are two benefits to this approach:
-
There is immediate support for autoloading without any need for adoption
or support in existing autoloaders. -
Pseudo-namespaces (abstract classes with stateless static functions) are
already widely practiced in PHP - a lot of existing code would be supported
as is.
The syntax when calling functions would be the same.
If we had function autoloading, we would likely collect related functions
in a file anyway - putting them in a class instead gives more less the same
exact result.
The only drawback I can see, is the inability to import a whole set of
functions with one statement - but being explicit about external imports is
widely considered best practice for classes and interfaces, so why not for
functions. Yeah, it's a bit inconvenient, but at least we can move ahead
and leverage existing code without changes or BC breaks. It's not all bad.
It's better than nothing perhaps? :-)
Thoughts?
Just a quick thought.
Since the autoloading functions proposal is stalled, how about allowing for
import of static functions instead?use function Foo::bar; bar(); // calls Foo::bar()
There are two benefits to this approach:
There is immediate support for autoloading without any need for adoption
or support in existing autoloaders.Pseudo-namespaces (abstract classes with stateless static functions) are
already widely practiced in PHP - a lot of existing code would be supported
as is.The syntax when calling functions would be the same.
If we had function autoloading, we would likely collect related functions
in a file anyway - putting them in a class instead gives more less the same
exact result.The only drawback I can see, is the inability to import a whole set of
functions with one statement - but being explicit about external imports is
widely considered best practice for classes and interfaces, so why not for
functions. Yeah, it's a bit inconvenient, but at least we can move ahead
and leverage existing code without changes or BC breaks. It's not all bad.
It's better than nothing perhaps? :-)Thoughts?
I actually like this idea a lot, something similar is possible in Rust
with Enums.
pub use self::Foo::{A, B};
pub enum Foo {
A,
B
}
fn main() {
let a = A;
}
Loading a set of static methods could look similar.
final class Foo {
public static function A(): self {
return new self;
}
public static function B(): self {
return new self;
}
}
use function Foo::{A, B};
$a = A();
--
Richard "Fleshgrinder" Fussenegger
Just a quick thought.
Since the autoloading functions proposal is stalled, how about allowing for
import of static functions instead?use function Foo::bar;
bar(); // calls Foo::bar()
...
at least we can move ahead
and leverage existing code without changes or BC breaks. It's not all bad.
It's better than nothing perhaps? :-)
I find this intuitively appealing. It's an incremental change with tangible benefit in an imaginable timeframe, as vs a dramatic change in an unknowable timeframe.
However, I am not an internals expert, so I'll leave it to them to say how big a deal it would be to implement, and what the drawbacks are.
--
Paul M. Jones
pmjones88@gmail.com
http://paul-m-jones.com
Modernizing Legacy Applications in PHP
https://leanpub.com/mlaphp
Solving the N+1 Problem in PHP
https://leanpub.com/sn1php
Hi!
Since the autoloading functions proposal is stalled, how about allowing for
import of static functions instead?use function Foo::bar; bar(); // calls Foo::bar()
I'm not sure why it is good. This would certainly be confusing, if you
call strlen and turns out it's completely different function from what
you thought. One thing when it's the same namespace, at least you can be
aware what this package does, but if it's just an arbitrary function
from anywhere, it's really bad for understanding the code.
How hard is it to write Foo::bar? You never have to go more
than one level. I don't see a point in mixing internal function
namespace with class methods for the sake of saving typing couple of
characters.
--
Stas Malyshev
smalyshev@gmail.com
On Fri, Jan 20, 2017 at 7:55 PM, Stanislav Malyshev smalyshev@gmail.com
wrote:
Hi!
Since the autoloading functions proposal is stalled, how about allowing
for
import of static functions instead?use function Foo::bar; bar(); // calls Foo::bar()
I'm not sure why it is good. This would certainly be confusing, if you
call strlen and turns out it's completely different function from what
you thought. One thing when it's the same namespace, at least you can be
aware what this package does, but if it's just an arbitrary function
from anywhere, it's really bad for understanding the code.
How is that different from the already existing "use function foo\bar\baz
as strlen"?
How hard is it to write Foo::bar? You never have to go more
than one level. I don't see a point in mixing internal function
namespace with class methods for the sake of saving typing couple of
characters.--
Stas Malyshev
smalyshev@gmail.com
On Fri, Jan 20, 2017 at 7:55 PM, Stanislav Malyshev smalyshev@gmail.com
wrote:Hi!
Since the autoloading functions proposal is stalled, how about allowing
for
import of static functions instead?use function Foo::bar; bar(); // calls Foo::bar()
I'm not sure why it is good. This would certainly be confusing, if you
call strlen and turns out it's completely different function from what
you thought. One thing when it's the same namespace, at least you can be
aware what this package does, but if it's just an arbitrary function
from anywhere, it's really bad for understanding the code.How is that different from the already existing "use function foo\bar\baz
as strlen"?
Or any other function that has no namespace separator in front.
<?php
namespace Fleshgrinder\Examples;
function strlen($string) {
return 42; // Troll! =)
}
final class SomeClass {
public function __construct() {
echo strlen('f');
}
}
new SomeClass;
This is actually used by some in tests to provoke error conditions in
built-in PHP functions to verify their error handling.
--
Richard "Fleshgrinder" Fussenegger
How hard is it to write Foo::bar? You never have to go more
than one level. I don't see a point in mixing internal function
namespace with class methods for the sake of saving typing couple of
characters.
I'm not suggesting we mix namespaces - this of course would be file-local,
same as use-statements in general.
You likely have to write a use-statement either way, if you're going to
call a static function, e.g.:
use Foo\Bar\HtmlHelper;
echo HtmlHelper::escape($text);
Versus:
use Foo\Bar\HtmlHelper::escape;
echo escape($text);
It's not about "saving characters", that's not what use-statements are for
- it's to avoid qualifying the same references repeatedly, which (for one)
is better for source-control, whether that's a namespace or a class-name
being repeated.
Anyhow, it sounds like most of you are positive about this idea, so I will
ponder the details and post a small RFC :-)
Hi!
Since the autoloading functions proposal is stalled, how about allowing
for
import of static functions instead?use function Foo::bar; bar(); // calls Foo::bar()
I'm not sure why it is good. This would certainly be confusing, if you
call strlen and turns out it's completely different function from what
you thought. One thing when it's the same namespace, at least you can be
aware what this package does, but if it's just an arbitrary function
from anywhere, it's really bad for understanding the code.
How hard is it to write Foo::bar? You never have to go more
than one level. I don't see a point in mixing internal function
namespace with class methods for the sake of saving typing couple of
characters.
--
Stas Malyshev
smalyshev@gmail.com
Hi, Rasmus!
2017-01-21 4:14 GMT-04:00 Rasmus Schultz rasmus@mindplay.dk:
How hard is it to write Foo::bar? You never have to go more
than one level. I don't see a point in mixing internal function
namespace with class methods for the sake of saving typing couple of
characters.I'm not suggesting we mix namespaces - this of course would be file-local,
same as use-statements in general.You likely have to write a use-statement either way, if you're going to
call a static function, e.g.:use Foo\Bar\HtmlHelper;
echo HtmlHelper::escape($text);Versus:
use Foo\Bar\HtmlHelper::escape;
echo escape($text);It's not about "saving characters", that's not what use-statements are for
- it's to avoid qualifying the same references repeatedly, which (for one)
is better for source-control, whether that's a namespace or a class-name
being repeated.Anyhow, it sounds like most of you are positive about this idea, so I will
ponder the details and post a small RFC :-)Hi!
Since the autoloading functions proposal is stalled, how about allowing
for
import of static functions instead?use function Foo::bar; bar(); // calls Foo::bar()
I'm not sure why it is good. This would certainly be confusing, if you
call strlen and turns out it's completely different function from what
you thought. One thing when it's the same namespace, at least you can be
aware what this package does, but if it's just an arbitrary function
from anywhere, it's really bad for understanding the code.How hard is it to write Foo::bar? You never have to go more
than one level. I don't see a point in mixing internal function
namespace with class methods for the sake of saving typing couple of
characters.--
Stas Malyshev
smalyshev@gmail.com
I think this idea looks like the easiest way to avoid fixing the underlying
problem. But it would irrevocably push
functions to a "second class citizenship" of the language, in favor of
static classes. It also would blurry
the lines between namespaces and classes in a way we haven't seen before.
Even though it feels pragmatic to do so, I'd prefer the harder path or at
least wait for the next major until commit to this.
Thanks,
Márcio.
Hi,
Rasmus Schultz wrote:
Since the autoloading functions proposal is stalled, how about allowing for
import of static functions instead?
The problem with stop-gap measures is they become entrenched, and the
proper solution doesn't get implemented. But we may be at the risk of
the latter anyway.
--
Andrea Faulds
https://ajf.me/
The problem with stop-gap measures is they become entrenched, and the
proper solution doesn't get implemented
This would be my general point of view - unfortunately, functions are
essentially useless at present, in a world with Composer, unless you're
willing to preload all functions from all packages up-front.
The only suggested solutions I've heard for the name resolution issue with
function autoloading frankly are all horrible - much worse than this simple
alternative.
Add to that the fact that likely 90% of all functions in the wild (at least
in Composer packages) are currently implemented as public static functions,
and in my opinion, this is starting to sound less like a stop-gap and more
like a simple solution to a problem we've been solving with a stop-gap for,
oh, 10 years or so...
Hi,
Rasmus Schultz wrote:
Since the autoloading functions proposal is stalled, how about allowing
for
import of static functions instead?The problem with stop-gap measures is they become entrenched, and the
proper solution doesn't get implemented. But we may be at the risk of the
latter anyway.--
Andrea Faulds
https://ajf.me/
The problem with stop-gap measures is they become entrenched, and the
proper solution doesn't get implementedThis would be my general point of view - unfortunately, functions are
essentially useless at present, in a world with Composer, unless you're
willing to preload all functions from all packages up-front.The only suggested solutions I've heard for the name resolution issue with
function autoloading frankly are all horrible - much worse than this simple
alternative.Add to that the fact that likely 90% of all functions in the wild (at least
in Composer packages) are currently implemented as public static functions,
and in my opinion, this is starting to sound less like a stop-gap and more
like a simple solution to a problem we've been solving with a stop-gap for,
oh, 10 years or so...
Again, if you choose to use static methods instead of functions, why do you
need this special syntax for calling them then?
Regards, Niklas
if you choose to use static methods instead of functions
It's not a choice - functions are practically useless in a Composer
context, and most everything PHP is now Composer packages.
why do you need this special syntax for calling them then?
Yeah, but the same logic applies to namespaces and classes:
If you choose to use namespaces, why do you need aliases for classes?
Strictly speaking, you don't - but it would be really ugly and
inconvenient. Forcing you to qualify a namespace or the parent class of a
function repeatedly is just noise, same as qualifying the namespace before
every class or interface-reference.
Agreed, it has no functional value, but neither does namespace-aliasing.
Both have a considerable organizational benefit though: the ability to list
all your class, interface and function imports at the top of a file.
To me, that's valuable.
Either way, guys, here's a preliminary RFC:
https://wiki.php.net/rfc/use-static-function
While trying to describe this, I have to say, this doesn't appear to be the
slam-dunk it seemed to be - you can read the details on that page, but
given the two alternative approaches described on this page, it seems this
feature is likely to create just as many problems and WTF as the
auto-loading RFC.
I'm afraid one isn't much better or worse than the other in that sense
really...
Oh well :-/
The problem with stop-gap measures is they become entrenched, and the
proper solution doesn't get implementedThis would be my general point of view - unfortunately, functions are
essentially useless at present, in a world with Composer, unless you're
willing to preload all functions from all packages up-front.The only suggested solutions I've heard for the name resolution issue with
function autoloading frankly are all horrible - much worse than this
simple
alternative.Add to that the fact that likely 90% of all functions in the wild (at
least
in Composer packages) are currently implemented as public static
functions,
and in my opinion, this is starting to sound less like a stop-gap and more
like a simple solution to a problem we've been solving with a stop-gap
for,
oh, 10 years or so...Again, if you choose to use static methods instead of functions, why do
you need this special syntax for calling them then?Regards, Niklas
if you choose to use static methods instead of functions
It's not a choice - functions are practically useless in a Composer
context, and most everything PHP is now Composer packages.Why are functions useless when using Composer? Is it because functions
can't be autoloaded?
Is this about getting functions to load without having to stick them in
classes that can be autoloaded?
why do you need this special syntax for calling them then?
Yeah, but the same logic applies to namespaces and classes:
If you choose to use namespaces, why do you need aliases for classes?
Strictly speaking, you don't - but it would be really ugly and
inconvenient. Forcing you to qualify a namespace or the parent class of a
function repeatedly is just noise, same as qualifying the namespace before
every class or interface-reference.Agreed, it has no functional value, but neither does namespace-aliasing.
Both have a considerable organizational benefit though: the ability to list
all your class, interface and function imports at the top of a file.To me, that's valuable.
Either way, guys, here's a preliminary RFC:
https://wiki.php.net/rfc/use-static-function
While trying to describe this, I have to say, this doesn't appear to be the
slam-dunk it seemed to be - you can read the details on that page, but
given the two alternative approaches described on this page, it seems this
feature is likely to create just as many problems and WTF as the
auto-loading RFC.I'm afraid one isn't much better or worse than the other in that sense
really...Oh well :-/
The problem with stop-gap measures is they become entrenched, and the
proper solution doesn't get implementedThis would be my general point of view - unfortunately, functions are
essentially useless at present, in a world with Composer, unless you're
willing to preload all functions from all packages up-front.The only suggested solutions I've heard for the name resolution issue
with
function autoloading frankly are all horrible - much worse than this
simple
alternative.Add to that the fact that likely 90% of all functions in the wild (at
least
in Composer packages) are currently implemented as public static
functions,
and in my opinion, this is starting to sound less like a stop-gap and
more
like a simple solution to a problem we've been solving with a stop-gap
for,
oh, 10 years or so...Again, if you choose to use static methods instead of functions, why do
you need this special syntax for calling them then?Regards, Niklas
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
Why are functions useless when using Composer? Is it because functions
can't be autoloaded?
Is this about getting functions to load without having to stick them in
classes that can be autoloaded?
Yes, and yes. The subject line of this thread is an allusion to a
conversation that resurfaces every now and then but always hits one
roadblock or another.
In short: the majority of PHP applications and frameworks are based
around autoloading rather than long lists of explicit dependencies;
functions can be inside a namespace; but such a function must be
explicitly defined before use.
Regards,
--
Rowan Collins
[IMSoP]
Either way, guys, here's a preliminary RFC:
Just to pick up on one thing you mention on there, declaring static
classes. This has been discussed before, and an RFC went to a vote a
couple of years ago and failed:
https://wiki.php.net/rfc/abstract_final_class
Part of the reasoning there was that people should be using namespaced
functions instead - although that just leads us back to the autoloading
debate...
Regards,
--
Rowan Collins
[IMSoP]
Since the autoloading functions proposal is stalled, how about allowing for
import of static functions instead?use function Foo::bar; bar(); // calls Foo::bar()
There are two benefits to this approach:
- There is immediate support for autoloading without any need for adoption
or support in existing autoloaders.
It adds "support". Just use a static method then instead of inventing some
new alias system.
- Pseudo-namespaces (abstract classes with stateless static functions) are
already widely practiced in PHP - a lot of existing code would be supported
as is.
That same code is already supported, no need for a language change here.
The syntax when calling functions would be the same.
If we had function autoloading, we would likely collect related functions
in a file anyway - putting them in a class instead gives more less the same
exact result.The only drawback I can see, is the inability to import a whole set of
functions with one statement - but being explicit about external imports is
widely considered best practice for classes and interfaces, so why not for
functions.
Just import the class and you're fine, you have just imported a group of
functions.
Yeah, it's a bit inconvenient, but at least we can move ahead
and leverage existing code without changes or BC breaks. It's not all bad.
It's better than nothing perhaps? :-)Thoughts?
I don't see any benefits here, just drawbacks. It adds yet another alias
system, function calls can now be function calls and static methods. What's
with the static scope? It gets lost here. Nothing shows there's a static
scope.
Strong -1 from me, sorry.
Regards, Niklas
Since the autoloading functions proposal is stalled, how about allowing
for
import of static functions instead?use function Foo::bar; bar(); // calls Foo::bar()
There are two benefits to this approach:
- There is immediate support for autoloading without any need for
adoption
or support in existing autoloaders.It adds "support". Just use a static method then instead of inventing some
new alias system.
- Pseudo-namespaces (abstract classes with stateless static functions)
are
already widely practiced in PHP - a lot of existing code would be
supported
as is.That same code is already supported, no need for a language change here.
The syntax when calling functions would be the same.
If we had function autoloading, we would likely collect related functions
in a file anyway - putting them in a class instead gives more less the
same
exact result.The only drawback I can see, is the inability to import a whole set of
functions with one statement - but being explicit about external imports
is
widely considered best practice for classes and interfaces, so why not
for
functions.Just import the class and you're fine, you have just imported a group of
functions.Yeah, it's a bit inconvenient, but at least we can move ahead
and leverage existing code without changes or BC breaks. It's not all
bad.
It's better than nothing perhaps? :-)Thoughts?
I don't see any benefits here, just drawbacks. It adds yet another alias
system, function calls can now be function calls and static methods. What's
with the static scope? It gets lost here. Nothing shows there's a static
scope.
A question in conjunction with this: How would this call actually treat the
LSB and $this scope? Would it follow the normal rules for scoped method
calls, or prevent adoption of scopes? For example:
use A::__construct as ctor;
class A { public function __construct() {} }
class B extends A { public function __construct() { ctor(); } }
Would this become an alternative way of writing parent::__construct() in B?
Would it behave the same?
Nikita
On Fri, 20 Jan 2017 10:04:44 +0300, Rasmus Schultz rasmus@mindplay.dk
wrote:
Just a quick thought.
Since the autoloading functions proposal is stalled, how about allowing
for
import of static functions instead?use function Foo::bar; bar(); // calls Foo::bar()
There are two benefits to this approach:
There is immediate support for autoloading without any need for
adoption
or support in existing autoloaders.Pseudo-namespaces (abstract classes with stateless static functions)
are
already widely practiced in PHP - a lot of existing code would be
supported
as is.The syntax when calling functions would be the same.
If we had function autoloading, we would likely collect related functions
in a file anyway - putting them in a class instead gives more less the
same
exact result.The only drawback I can see, is the inability to import a whole set of
functions with one statement - but being explicit about external imports
is
widely considered best practice for classes and interfaces, so why not
for
functions. Yeah, it's a bit inconvenient, but at least we can move ahead
and leverage existing code without changes or BC breaks. It's not all
bad.
It's better than nothing perhaps? :-)Thoughts?
Maybe we might think about modules this time?
Lots of languages use this approach and they seem to be pretty happy
with it.
Here's how it could look like, very abstractly. I don't really see
any big issues with the way how to implement it either.
https://gist.github.com/nikita2206/2e4ab1b314e840f93ed75a0b88266d35