10 ms·
Critiquing Facebook's new PHP spec
- wvenable 12y agoUnder GC: > I read this as saying that when a variable dies, you must immediately clear it up. I suspect that this will make the GC a little less flexible than it has to be. I think the key reason for this is that objects have deterministic destruction in PHP which allows for the RAII pattern. This is in contrast with garbage collection in Java or C# where finalizers aren't called immediately (or sometimes at all) and the RAII pattern is impossible. I suspect if you could leave memory lying longer around as long as you destructed objects and resources immediately but there probably isn't any advantage to that. But changing the destruction characteristics would break code that depends on it.
- pbiggar 12y agoThat part of the spec refers to variables (which the spec calls VSlots), not objects (which the spec calls HStores). Objects have different lifetimes, and the spec actually allows the destructors to be run anytime between the object being dead and the program ending. So it looks like there won't be any RAII here.
- wvenable 12y agoNo RAII would be a big change in the behavior of PHP; you should add that information to your critique. I have code that relies on RAII for error recovery and rollback. Any PHP implementation that doesn't do RAII is going to subtly break a lot of code. It doesn't make sense to force very specific memory lifetimes for variables and then also not do it for objects.
- pbiggar 12y agoYeah, I think you're right. The specific language is: > Later, if a VStore or HStore becomes unreachable through any existing variable, they become eligible for reclamation to release the memory they occupy. The engine may reclaim a VStore or HStore at any time between when it becomes eligible for reclamation and when the script exits. Before reclaiming an HStore that represents an object, the Engine will invoke the object's destructor if one is defined. I'll put it in now. Thanks - and great catch!
- masklinn 12y agoThe problem being it's not RAII but a side-effect of reference-counting[0] (Python had the same issue, it's been a pain for alternative implementations and a big reason for `with` being added to the language) [0] it doesn't work when there's a cycle for instance
- wvenable 12y agoPHP developers specifically took into consideration RAII when designing the language. This is why the finally clause for exceptions was not originally part of the language -- it was unnecessary for cleanup if you have RAII. Cycles don't really affect RAII in meaningful way.
- masklinn 12y ago> PHP developers specifically took into consideration RAII when designing the language. No part of that phrase matches reality. > Cycles don't really affect RAII in meaningful way. Which is irrelevant because once again what PHP has is not RAII it's reference counting, same as CPython and Objective-C. And because it's refcounting it does have an impact: objects involved in or linked from a cycle are not immediately cleaned up once the cycle goes out of scope because all objects still have a refcount of at least 1. Cycles which, by the way, PHP did not bother breaking until 5.3: http://php.net/manual/en/features.gc.collecting-cycles.php http://php.net/manual/en/features.gc.collecting-cycles.php so these objects would live until process death.
- wvenable 12y ago> No part of that phrase matches reality. It's true. When exception handling was added to PHP, RAII was absolutely factored into the design. This is why it didn't get a finally clause to start with -- it's unnecessary. > Which is irrelevant because once again what PHP has is not RAII it's reference counting http://www.hackcraft.net/raii/ http://www.hackcraft.net/raii/ http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initial... If you have reference counting or stack allocated objects than you can do RAII. You seem to be confused as what these terms mean -- they are not contradictory, they are complimentary. Ref counting allows RAII.
- webkike 12y agoWhen I read the new PHP spec, I threw up in my mouth after I saw that empty("0") was a special case of empty that returned TRUE. I know that's how PHP normally works, but that doesn't really make my mouth taste any better.
- wvenable 12y agoThe thing you have to understand about PHP, is it's meant to easily work in a world where every value is in a string. You get strings from the browser, you get strings from the database, and strings from the file system. It was expected that these strings contain numbers and that you should be able to rationally use them as numbers without conversion. So "10" > "5" returns true in PHP where as that would be false in most other languages. The underlying representation of the value (sequence of characters, 2s compliment binary, or IEEE 754 double) means nothing in PHP; they are all supposed to be equivalent. So "12", 12, and 12.0 are the same and "0" and 0 are the same. The consequence of this design ripples through to every aspect of the language. And it ripples down to the implementation of empty. Empty(0) is true. So therefore Empty("0") is also true. The fact that one is an integer and the other is a string is not a distinction that exists in PHP. It's super weird and unexpected but it's not illogical given the rules of the language.
- leeoniya 12y agowhat threw me personally about empty() is that it doesn't invoke magic getters: "__get".
- wvenable 12y agoThat's not true, empty() will call __isset() first, and only if it returns true will it call __get(). This is because empty() is the compliment to the isset() function. There is no reason to use empty() over the not (!) operator unless there is the potential your property doesn't exist.
- leeoniya 12y ago
- arenaninja 12y agoAfter reading your critique, I'm now very confused on where this spec stands. Is Zend bound by it (I don't think so)? For example, you mention absence of RAII, I don't think that Zend's PHP will lack RAII (because they don't break BC), but new implementations following this (proposed?) spec are free to disallow it
- pbiggar 12y agoNo, but I believe they're excited by it (according to Facebook's post at least). I'd expect Zend to keep supporting RAII, but I doubt new implementations will - its a real drag on building better GCs, and that can be as much as half the performance of a program.
- wvenable 12y agoI think the language would really need more features, like using blocks from C#, to be effective without RAII. The finally clause was only just added in the last release. The spec, as it stands, is flawed. Any removal of RAII should be left to major version (e.g. PHP7). Since this spec is meant to represent the current state of PHP, it's completely incorrect in this area.
- arenaninja 12y agoI think your latter point is part of my confusion. Is this a proposal for what PHP should be or what it currently is? I'm as excited as anyone for the upcoming jPHP but, array bug aside, breaking BC is huge in PHP. I've used the __destruct method plenty of times to automate DB changes without explicitly calling a function to save those changes
- pbiggar 12y agoI disagree. They underspecified the language, so it still technically represents the current state of the Zend implementation of PHP. (I take no position on RAII being useful or not, I don't write PHP for a living).
- brian_mingus 12y agoCritiquing the critique of Facebook's new PHP spec: You used affect when you should have used effect. They probably don't teach that in the CS PhD program:) Of course my post may be subject to Muphry's Law. But still. If you're going to spend so much time establishing your credibility, do you really want to ruin it by demonstrating you don't have a basic understanding of English grammar? http://en.wikipedia.org/wiki/Muphry's_law http://en.wikipedia.org/wiki/Muphry's_law
- arenaninja 12y agoI'm not sure I would place any significance on something I have seen many native speakers screw up consistently. If you're not familiar with the author, you could take the time to read the blog post he linked to where he talked about HPHP and phc
- brian_mingus 12y agoIf the affect/effect error was in isolation it wouldn't have been a big deal. When combined with a rant of how much of an expert he was the contrast led to quite a bit of cognitive dissonance.
- kansface 12y agoHe never claims to be an expert on English grammar.
- Dewie 12y agoAny grammar mistake negates any intellectual merit on the Internet...
- arenaninja 12y agoFair enough. It's possible I skipped that section because I was already familiar with his HPHP/phc post. Regardless of why, I never noticed it
- deleted 12y ago
- thedufer 12y ago>Rather than trying to specify the exact algorithm for everything (which is what the JS spec typically does, for example), they chose to describe the Zend model (or close enough) and say “it has to appear to work like this”. To be fair, the JS spec may say those things but no modern JS engine actually does it that way. Despite the wording, "must appear to..." is the common interpretation of that spec. It is nice that this one makes that explicit, though.
- gsnedders 12y agoOn the other hand, there's been a fair bit of work (esp. for ES6, and to a lesser extent ES5) to minimize the number of things the specification states contrary to implementations.
- timdierks 12y agoI can see the appeal of allowing behavior variant from Zend in areas where there is a big benefit, and I like the approach of defining these areas as "implementation-dependent" rather than specifying one or the other. However, it seems to me that some of these are in areas where PHP code would need to know the runtime behavior of the platform they're on; the alternative is just to avoid all such areas ("there be dragons here") or to give up on portability and be implementation-dependent, in which case it seems to me that there's not much value in having a PHP standard (other than as a base document on which to build the Zend or HHVM specifications). Why not have the specification allow runtimes to expose their choices of behavior into the runtime to allow code to determine what their platform does? Of course, one can probably write tests for these behaviors and build a library, but it seems like it would be better to just delineate the alternative behaviors and put them into the ABI.
- coldtea 12y ago>Why not have the specification allow runtimes to expose their choices of behavior into the runtime to allow code to determine what their platform does? Because the idea is that it should be transparent to the code. If you start doing that you get into mess like the "feature sniffing" BS JS does in browsers, IFDEFs etc... So, which of these specifically seem to you to be "on areas were code would need to know the runtime behavior"?
- timdierks 12y agoI don't know the details of PHP, but it seems to me that all the areas that are referred to as "implementation-dependent" are code-observable: e.g. the deferred array copying decision discussed in the critique: if your code depends on a behavior, you'll get different results on the other platform. So if you want to be portable, you need to sniff the behavior and take a different route on the alternate platform, or you need to avoid the quicksand in the first place.
- coldtea 12y ago>are code-observable: e.g. the deferred array copying decision discussed in the critique: if your code depends on a behavior, you'll get different results on the other platform. I don't see how the "deferred array copying" ever leak to the program you write. Copy-on-write and such is a classic example of implementation detail that the higher layer is not concerned about.
- jerf 12y ago"One other thing they specified is that array cursors are internal.... This would manifests if a new PHP implementation wanted to use a different threading model: would two threads looping through the same array use the same cursor? Sounds pretty racy." Is it even worth it to leave room for a threaded PHP? At this point that would de facto be another language anyhow... the changes required to add threading to a language like PHP [1] 20 years after it was born are too insane to even think about. It would be so many years before it was stable enough to begin building any sort of library infrastructure that would make it into any sort of common use that the language would probably be on the way out by the time this gauntlet could be run. See Perl's experience with trying to add threading. It would certainly require another specification document anyhow. I'm of the opinion that languages around the 10 year mark (which PHP is obviously well past) really ought to focus on becoming the best X they can be, rather than chasing the tail lights of constantly-moving best practice. Seems like you're better off just making PHP be the best PHP it can be rather than try to add threading in to the mix. PHP certainly simply isn't going to be able to compete with existing languages that build some sort of solid threading story in from day 1, and, frankly, it shouldn't try. (And most of those languages simply can't compete with PHP on its home turf, after all.) [1]: Mutable-state imperative dynamic. Basically, the answer to the question "What's the hardest sort of common language to add threading to after the fact?"
- damncabbage 12y agoI'm of the opinion that languages around the 10 year mark (which PHP is obviously well past) really ought to focus on becoming the best X they can be, rather than chasing the tail lights of constantly-moving best practice. Would that include not adding: * Anonymous functions and closures * Namespaces * Late static binding * Dynamic dispatching to static methods * Rackup/SimpleHTTPServer-like web server * "finally" in exception-handling * Being able to call foo()[0] instead of the clumsy assign-then-dereference two-step. What does "the best PHP it can be" mean? Anonymous functions (for example) are arguably way outside the style of the PHP from ten years ago, but they're tremendously useful. (I used to use PHP. I dislike it as a language, but I have nothing against them continuing to improve it like they have over the last nine years.) PS: PHP already supports threading via a PECL module. http://php.net/manual/en/class.thread.php http://php.net/manual/en/class.thread.php
- ars 12y agoI don't understand what you wrote about "deferred array copying". When I ran your code I got "PHP Notice: Undefined offset: 1" If I removed that line then I got "2 3" which seemed wrong to me since those two variables should have been aliases to the same thing. But copying the values instead of the reference seems slower, not faster.
- georgelund 12y agoI don't think your comment on Overflows - "Zend is by definition a correct implementation" - is necessarily right - elsewhere we're definitely looking at Zend having to change their implementation, right? Great article, BTW.
- TazeTSchnitzel 12y agoNo, the spec leaves implementing it open. Something I'm trying to change as the behaviour in the spec is wrong.
- dancecodes 12y agoIm sorry for my English. All rotating around zend, refs, memory, these variable's copy... Good question: Who cares about Zend? I monitor my application under kcachegrind and xdebug/tracefile-analyser.php: in generally its array-copy operations, classes load, require/include, and strings and its definitely are slow. Why no types like: lists, tuples, ascii-string (I think it fastest, than unicode or any latin)? Array its multi-paradigm? Ok. Nice YAGNI implementation. I try prevent pass arrays and replace it with ArrayObject or stdClass or any custom object because objects its reference by defenition. It help improve memory consumption but not so effective. I think PHP needs improve internal components first and also Zend that nailed down to PHP. But its good of course that spec under public discussion, hope this help improve language.
- Kiro 12y ago> describe the difference between $a = new Point(1, 3) and $a =& new Point (1, 3) Answer: I forget! I think it’s that the next assignment to “$a` will do something odd, but honestly I don’t remember the subtleties. So what is the difference exactly?
- dfilaretti 12y agoGood to finally see a PHP spec! You might also be interested in a formal semantics for PHP which has been presented today at the ECOOP'14 conference in Uppsala, Sweden. Details can be found at www.phpsemantics.org. As I wrote before, I wish we had this spec a couple of years before - our life would have been so much easier! :)
- benth 12y agoGlad the conditional/ternary operator's atypical associativity is documented now...
- deleted 12y ago[deleted]