On Fri, Feb 21, 2020 at 12:05 AM Larry Garfield <la...@garfieldtech.com>
wrote:

> On Thu, Feb 20, 2020, at 8:47 AM, Levi Morrison via internals wrote:
> > Just chiming in to voice strong support for this RFC. This is a key
> > piece toward making PHP code statically analyzable. If it becomes
> > required at the call site, such as in an edition of the language, it
> > will significantly enhance the ability to reason about code and
> > probably make it more correct as well. As a small example, consider
> > this method on an Optional type class:
> >
> > function map(callable $f): Optional {
> >   if ($this->enabled) {
> >     return new Optional($f($this->data));
> >   } else {
> >     return $this;
> >   }
> > }
> >
> > The intent is to return a new optional or an empty one, but if you
> > pass a closure that accepts something by reference you can change the
> > original, which is not intended at all. For people who defend against
> > it, it requires saving `$this->data` to a local variable, then passing
> > in the local. Then if the user does a call-by-reference it will affect
> > the local, not the object's data.
>
>
> If $this->data is itself an object, then you have a concern for data
> manipulation (spooky action at a distance) even if it's passed by value.
> Given how much data these days is objects, and thus the problem exists
> regardless of whether it's by value or by reference passing, adding steps
> to make pass-by-reference harder doesn't seem to help much.
>

If you will allow me some exaggeration, what you're basically saying here
is that all the const / readonly / immutability features in (nearly) all
programming languages are useless, because they (nearly) always allow for
interior mutability in one way or another. "const" in JavaScript doesn't
allow you to rebind the object, but you can still modify the object. Same
with "final" in Java. Similar things hold in C/C++/Rust when it comes to
const pointers/references to structs that contain non-const
pointers/references. And of course, the "readonly" RFC for PHP that is
currently under discussion has the same characteristics.

What I'm trying to say here: All of these features do not guarantee
recursive immutability, but that doesn't render them useless in the least.
In fact, the outer-most layer is where immutability is the most important,
because there's a lot of difference between

    $i = 0;
    var_dump($i); // int(0)
    foo($i);
    var_dump($i); // array(7) { ... }
    // WTF just happened???

and

    $o = new Foo();
    var_dump($o); // object(Foo) #42 { xxx }
    foo($o);
    var_dump($o); // object(Foo) #42 { yyy }
    // Did something change in there? Doesn't really matter for this code!

One of the big differences is that by-reference passing can change the
*type* of the variable, while by-object passing cannot. It cannot even
change object identity.

On a closing note: I don't think this RFC makes passing by reference
"harder" in any meaningful sense. Yes, you do need to write one extra
character. In exchange, every time you read code you will immediately see
that by-reference passing is used, here be dragons.

Regards,
Nikita

Reply via email to