Hi Andrea,

Thanks a lot for putting efforts thinking through this problem.
Indeed we have 3 problems that leads to "static classes". You detailed 2 of
them.
The third is around encapsulation. I may want functions that are reused by
other functions at the namespace level, but that shouldn't be used outside
of it. By purely supporting (1), you still didn't address this issue. That
would be easily addressed by having private static functions inside of the
static class.
So, let me recap the 3 motivations:

(1) Function/Namespaced function autoloading
(2) State encapsulation
(3) Function scoping

Heading back to your drill down in (2), I feel that we're adding more
complexity to something that can and it is at some extent be easily
supported through classes.
I actually thought about having "let" originally and using as "global", but
I gave up on the idea due to patch's complexity and also because it didn't
matter how far I was thinking through this, something was popping up my
head telling it was wrong. I decided to share my idea with a friend which
pointed me to HHVM's support and then I decided to work on that original
patch.
So, as you walk through your options, didn't it feel wrong to you? Static
classes are an easy addiction to the language and would have a negligent
performance impact, since it just adds 2 conditions in zend_vm and zend_api.

Again, I wouldn't necessarily use this concept I'm proposing right out the
bet, but I do see there are use cases.
I plan to redo my patch and get back for review once I finalize.

Cheers,

On Mon, Dec 1, 2014 at 9:32 AM, Andrea Faulds <a...@ajf.me> wrote:

> Hi all!
>
> > On 1 Dec 2014, at 13:58, Robert Stoll <p...@tutteli.ch> 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/
>
>
>
>
>


-- 
Guilherme Blanco
MSN: guilhermebla...@hotmail.com
GTalk: guilhermeblanco
Toronto - ON/Canada

Reply via email to