Live data from Hacker News

Critiquing Facebook's new PHP spec

blog.circleci.com

31–40 of 70 posts

Re: Critiquing Facebook's new PHP spec

#31
post #8

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

No, 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.

First, 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.

Re: Critiquing Facebook's new PHP spec

#32
I 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.

Re: Critiquing Facebook's new PHP spec

#33
post #4

Earlier quoted context omitted.

No 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.

The 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

PHP 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.

Re: Critiquing Facebook's new PHP spec

#34

Earlier quoted context omitted.

what threw me personally about empty() is that it doesn't invoke magic getters: "__get".

That'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.

ah, good to know. thx.

Re: Critiquing Facebook's new PHP spec

#35
post #8

Earlier quoted context omitted.

No, 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.

First, 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…

RAII 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.

Re: Critiquing Facebook's new PHP spec

#36

I 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 drag…

>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"?

Re: Critiquing Facebook's new PHP spec

#37

>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…

On 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.

Re: Critiquing Facebook's new PHP spec

#38

Earlier quoted context omitted.

If 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.

He never claims to be an expert on English grammar.

Any grammar mistake negates any intellectual merit on the Internet...

Re: Critiquing Facebook's new PHP spec

#39

Critiquing 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/…

Here's how I would rewrite your post:

"I noticed a typo -- should be instead. And since I'm not being a smartass, I don't have to go through all the trouble of citing . Yay!"

Re: Critiquing Facebook's new PHP spec

#40

Earlier quoted context omitted.

First, 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…

RAII 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…

Hmm, IMHO it feels like you're bending the definition of "lifetime" a bit in a manner that already presumes RC-based automatic memory management, and once one accepts that assumption then naturally one concludes that the lifetime ends when refcounting says it ends. To me, the lifetime of a heap allocated thing effectively ends when it is no longer reachable via any existing variables (though perhaps this definition is biased towards a tracing-GC view of the world).

I agree with your points about "finally". It can definitely be a bit clunky, and this is why some languages have introduced scoped cleanup constructs such as C#'s "using" statement, Python's "with" statement, and D's "scope" statement. I guess what I was getting at with my original comment is that I feel scoped cleanup constructs are a better way to go vs. relying on heap allocated things being reclaimed at a certain time, given that the lifetime of a heap allocated thing can depend on non-local state outside of the current function/method.

Post reply on HN