4 ms·
After 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,
by arenaninja 12y ago
After 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).
- wvenable 12y agoIt's in direct conflict with the PHP manual: http://php.net/manual/en/language.oop5.decon.php#language.oop5.decon.destructor http://php.net/manual/en/language.oop5.decon.php#language.oo... "PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence." It's very common to rely on this behavior to do cleanup as PHP did not have a finally clause (like C++) until recently.
- pbiggar 12y agoI think we're talking at cross-purposes. I'm just saying that because it's underspecified, the Zend engine can be both accurate to what's in the PHP manual, and to what's in the spec. Anyway, it's a slightly pedantic point, so I'm probably not contributing much to the conversation here :)
- wvenable 12y agoI understand your point. The spec as written means the Zend Engine itself is accurate the spec. The problem is the spec isn't accurate to the language, as it exists, in the wild. Existing correct and valid PHP code executed to this spec will behave incorrectly. Therefore, it's not really a PHP spec. PHP Code > PHP Spec > PHP Engine
- dparoski 12y agoFirst, I want to thank you, Paul, for writing this critique. It's great to read well thought-out feedback about the draft spec that was announced yesterday. Before getting into technical nitty gritty, I wanted to clarify that the spec in its current state is a draft offered to the PHP community as a starting point for specifying the PHP language. It now belongs in the php-src repository and can be updated through the standard commit processes for that repository as the community sees fit. Some decisions about specificity were made for the initial draft, but these decisions are by no means final and the hope is that the community will settle on what's right for the PHP ecosystem overall. Regarding RAII, I'd argue that __destruct methods in PHP are a bit different than stack-allocated variables in C++. Stack allocated variables in C++ have a strictly defined lifetime based on the scope of the variable. In PHP on the other hand, objects are heap allocated and when they are destroyed is not as well defined. For example, you can have a cycle of two or more objects pointing to each other that are unreachable (i.e. cyclical garbage), and it such cases any __destruct methods for these objects are not immediately invoked when the objects become unreachable. I considered requiring refcounting-based automatic memory management for the initial draft of the memory model, but describing in detail cyclical garbage felt really implementation specific and so at a gut level it seemed better to not require RC-based automatic memory management and see how people reacted. Based on my personal programming tastes, I'd argue that try/finally is a cleaner, more robust way to ensure certain cleanup happens when a scope is exited rather than relying on __destruct. However, I understand that there are some PHP programs out there that rely on __destruct being invoked eagerly in non-cyclical-garbage cases, and that such code will probably exist in the wild for a quite a while regardless of whether try/finally is "superior" or not. I'm curious to see how this issue settles over time. For the record, HHVM uses RC-based automatic memory management and will eagerly call __destruct on objects that become unreachable that are not part of cyclical garbage. The initial choice to be a bit more liberal about reclamation was not essential to make sure that HHVM was compliant with the spec.
- wvenable 12y agoRAII simply requires that resource allocation is tied to object lifetime. It requires that destructors are called deterministically and immediately once all references to an object no longer exist. (In the case of cycles, a reference remains until otherwise broken -- a non-issue for this definition). I personally prefer RAII to finally for object-related cleanup because finally is fallible. If you have a File object instance whose destructor calls fclose() automatically then I don't have to remember to call a Close() method inside a finally block. It happens automatically. But if you don't have RAII then you must remember to put in try blocks and finally clauses everywhere you create an instance. Multiply that by every database connection, network connection, and file and that is a lot of work and potential to miss something. And finally doesn't work at all if your object lifetimes aren't tied to scope. Finally is inferior to RAII in almost all cases except where you aren't using nicely defined objects. If you use an fopen() call directly, finally is your only recourse to fclose() it properly. The only criticism of RAII is that does limit concurrency and garbage collection options.