Hi all!
> On 1 Dec 2014, at 13:58, Robert Stoll <[email protected]> wrote:
>
> I read your updated RFC:
> https://wiki.php.net/rfc/abstract_final_class
Hmm, I don’t like this new RFC either. Static classes in languages like C#
exist because the language designers made the dogmatic decision to require
everything to be a class. Thus, to make collections of functions, your only
choice is to make a “utility class" with a bunch of static methods. To make
this easier, the `static` keyword was added to make this easier in C# - Java
doesn’t have this keyword, but it has the same pattern of static method-only
classes. But PHP is not one of these dogmatic “everything must be a class”
languages: it has true global functions which can be namespaced.
So, why, then, does PHP need static classes? As I see it, there are two reasons:
(1) Functions currently cannot be autoloaded
(2) Encapsulation of state (private/protected static properties)
I think both of these can be solved without perpetuating what I feel is an
anti-pattern, the “utility class”. If they are solved, the need for utility
classes goes away.
To implement (1), someone just needs to go and finally implement function
autoloading. I think Joe Watkins (krakjoe) might’ve said he’d write a patch for
that, but I may be wrong. I’d certainly like to help with this effort.
Implementing (2) is more difficult. We currently don’t have file-local
variables like C has, we don’t even have namespaced variables. We do have
static variables within functions, however. I can think of a few possible
approaches to this:
(1) Say that global state is evil and refuse to implement it. Some people
(myself included, to an extent) would argue that global state is “spooky action
at a distance” and we shouldn’t be encouraging it. In this case we encourage
users to simply make normal, non-static/abstract classes and to pass an
instance around. This is generally good programming practise anyway.
(2) Add lexically-scoped variables, and allow normal global functions to be
closures. By this I mean we add something like JavaScript’s `let` keyword that
would make a variable that is unset when it falls out of scope (end of a {}
block, end of a file etc.). Then, we allow normal functions to use the `use
($var)` syntax and close over variables. That’d look something like this:
<?php
let $x = 0;
function getCounter() use(&$x) {
return $x;
}
function incrementCounter() use(&$x) {
return $x++;
}
// since this is the end of the file, $x falls out of scope
I’d quite like this, as the introduction of lexically-scoped variables
would have other advantages, too. They would make foreach() by-reference much
less error-prone, for example:
<?php
foreach ($array as let &$item) {
// do stuff with $item
}
// $item is unset here, since it fell out of scope when we left the {}
block
(3) Add file-local variables using the `static` keyword (à la C). That’d work
something like this:
<?php
static $x = 0;
function getCounter() {
global $x;
return $x;
}
// etc.
This would work similarly to `let`, I suppose, it’d just only be useful
for files.
(4) Add namespace-local variables. No idea quite how this’d work.
I’m not sure which of these is the best, though I’d leans towards (1) or (2).
But I definitely feel that adding a `static` modifier for classes is solving
the wrong problem. We don’t need to make utility classes easier to create.
Rather, we need to solve the long-standing problems which force people to
create utility classes in the first place.
Thanks!
--
Andrea Faulds
http://ajf.me/
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php