On Sat, Jul 11, 2020, at 9:06 AM, Olle Härstedt wrote:
> Dear internals,
>
> I'd like to discuss the concept of ownership in PHP, from the point of
> view of a new interface UniqueInterface (or SplUniqueInterface or
> something), which will throw a UniqueException if refcount > 1.
>
> Use-case: Mutable objects that cannot be shared (without (deep) cloning).
>
> Rational: Immutable objects are considered "easier to reason about"
> and generally more safe, and as a way to avoid
> spooky-action-at-a-distance. I argue that mutability is totally fine
> as long as it's not *being shared*. Currently, there's no way to
> enforce this in PHP, *but* PHP has a refcounting GC which could do
> this. This would be a more performant alternative than to build lots
> of immutable objects using $obj->whereSomething('bla') constructs.
>
> Cons: If PHP switches to tracing GC, it will be unusable.
>
> What do you think? Should I write it down as an RFC? Implementation
> should be straight-forward, assuming refcount is manipulated at a
> single place in the source.
>
> Regards
> Olle
I like the goal of addressing shared mutable state is a laudable one and I
think most here share it. However, I think uniqueness checking is the wrong
approach, for reasons others have already explained.
You're correct that the thing to avoid is shared mutable state. That can be
avoided either by getting rid of mutable state or shared state. Either would
work. (Channeling Kevlin Henny here.)
In the case of PHP, since we don't have threads to worry about the main source
of shared state is reference variables, or refrence-esque objects. (Or
globals, but I'm assuming most here know to avoid those already.) That is,
mutability or shared-ness within a function is, meh, who cares. It's at
function boundaries that we care.
As others noted, a ref count check wouldn't help with that much, because the
act of passing an object to another function necessarily increases the
refcount, thus eliminating the main benefit.
Rather, the way to eliminate shared-ness is to have "structs," that is, objects
that pass by value-ish rather than pass-by-reference-ish. (Yes it's more
complicated than that, I know, I'm talking about the user-space implications.)
PHP 4 objects all worked that way, which was a problem for anything with
services our resources behind it. That's why it changed in PHP 5 to the more
common by-ref-ish behavior, which... is a problem for value objects.
Both use cases are valid. It's why newer languages like Go and Rust take a
completely different approach to what "object" even means in the first place.
It's been discussed before but never really implemented; I do think the way to
help break the "shared state" side is to allow objects to get flagged as "will
use by-value passing" or "will use by-reference passing" (again, implications,
not implementation). That is, if you have a by-val object and pass it to a
function, it behaves the same way as passing a string or an array:
Copy-on-write of the object when any changes are made to properties of the
object. Probably we'd also need to require that properties of by-val objects
cannot be by-ref objects or resources, which seems reasonable to me.
I think that would do a far better job of addressing the shared-mutable-state
issue than reference counting, because it attacks the root problem rather than
a symptom.
--Larry Garfield
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php