Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:79341 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 19866 invoked from network); 1 Dec 2014 15:28:11 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Dec 2014 15:28:11 -0000 Authentication-Results: pb1.pair.com header.from=guilhermeblanco@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=guilhermeblanco@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.213.173 as permitted sender) X-PHP-List-Original-Sender: guilhermeblanco@gmail.com X-Host-Fingerprint: 209.85.213.173 mail-ig0-f173.google.com Received: from [209.85.213.173] ([209.85.213.173:37406] helo=mail-ig0-f173.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 43/20-18127-9098C745 for ; Mon, 01 Dec 2014 10:28:10 -0500 Received: by mail-ig0-f173.google.com with SMTP id r2so13193119igi.6 for ; Mon, 01 Dec 2014 07:28:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=JrWsl2psux6+epAqFvCYGX8OZIXd5NLdKLinK7qKbAw=; b=0Eg595qBSaYa66+66lywi7MjVFQdM9ou7U4/3KrBS50uIn1fd1B5F+bpwPCRfJah6p ysLQUUG/2e0nz2G557ixz6iDcMDmRyOQq9U3tMLoLR6UiE4INumTHRk0Dm1CXGne9Ksl g+Lw3r7Soo1XGSy89zZC0GXsVR2PZoV/rfNodrXSJtyj7ariotzMLl+KCni7Pejx2YeP 3EB36ZtE8qt7NUEFLvGm50wgxwQe5WDpjCs/N5YfBZU9Uq3fIb5UyOehYBtwOsN1jNID p5WwbT+Y5pBBMsEMIBKyaJjNKMpVbTGJ9iaR+2KQywDAPVEO2JXTYap3OppY9bsfpuV6 acNw== X-Received: by 10.50.47.14 with SMTP id z14mr46000378igm.38.1417447686990; Mon, 01 Dec 2014 07:28:06 -0800 (PST) MIME-Version: 1.0 Received: by 10.64.238.75 with HTTP; Mon, 1 Dec 2014 07:27:46 -0800 (PST) In-Reply-To: <868FD3D8-4E80-46F4-872A-125D3FD8F40D@ajf.me> References: <003c01d00d6e$f4fd77c0$def86740$@tutteli.ch> <868FD3D8-4E80-46F4-872A-125D3FD8F40D@ajf.me> Date: Mon, 1 Dec 2014 10:27:46 -0500 Message-ID: To: Andrea Faulds Cc: Robert Stoll , internals Content-Type: multipart/alternative; boundary=089e013d0b74def12505092941e7 Subject: Re: [PHP-DEV] [RFC] Static classes (Was Abstract final classes) From: guilhermeblanco@gmail.com ("guilhermeblanco@gmail.com") --089e013d0b74def12505092941e7 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 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 wrote: > Hi all! > > > On 1 Dec 2014, at 13:58, Robert Stoll wrote: > > > > I read your updated RFC: > > https://wiki.php.net/rfc/abstract_final_class > > Hmm, I don=E2=80=99t like this new RFC either. Static classes in language= s like C# > exist because the language designers made the dogmatic decision to requir= e > everything to be a class. Thus, to make collections of functions, your on= ly > choice is to make a =E2=80=9Cutility class" with a bunch of static method= s. To make > this easier, the `static` keyword was added to make this easier in C# - > Java doesn=E2=80=99t have this keyword, but it has the same pattern of st= atic > method-only classes. But PHP is not one of these dogmatic =E2=80=9Ceveryt= hing must > be a class=E2=80=9D 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 a= n > anti-pattern, the =E2=80=9Cutility class=E2=80=9D. If they are solved, th= e 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=E2=80=99ve said he=E2=80= =99d write a patch > for that, but I may be wrong. I=E2=80=99d certainly like to help with thi= s effort. > > Implementing (2) is more difficult. We currently don=E2=80=99t have file-= local > variables like C has, we don=E2=80=99t 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 > =E2=80=9Cspooky action at a distance=E2=80=9D and we shouldn=E2=80=99t be= encouraging it. In this > case we encourage users to simply make normal, non-static/abstract classe= s > and to pass an instance around. This is generally good programming practi= se > anyway. > > (2) Add lexically-scoped variables, and allow normal global functions t= o > be closures. By this I mean we add something like JavaScript=E2=80=99s `l= et` > keyword that would make a variable that is unset when it falls out of sco= pe > (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=E2=80=99d look= something > like this: > > let $x =3D 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=E2=80=99d quite like this, as the introduction of lexically-scope= d > variables would have other advantages, too. They would make foreach() > by-reference much less error-prone, for example: > > 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 (=C3=A0 la C). = That=E2=80=99d > work something like this: > > static $x =3D 0; > function getCounter() { > global $x; > return $x; > } > // etc. > > This would work similarly to `let`, I suppose, it=E2=80=99d just on= ly be > useful for files. > > (4) Add namespace-local variables. No idea quite how this=E2=80=99d wor= k. > > I=E2=80=99m not sure which of these is the best, though I=E2=80=99d leans= towards (1) or > (2). But I definitely feel that adding a `static` modifier for classes is > solving the wrong problem. We don=E2=80=99t 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/ > > > > > --=20 Guilherme Blanco MSN: guilhermeblanco@hotmail.com GTalk: guilhermeblanco Toronto - ON/Canada --089e013d0b74def12505092941e7--