On Mon, 29 Jul 2019 at 15:41, Nikita Popov <nikita....@gmail.com> wrote:
> This proposal (at least combined with a declare that enforces use of > call-site annotations) addresses that concern. out/inout parameters do not > address this concern, because they are an mechanism that would be used *in > addition* to normal by-ref passing, and as such not address any problems it > has. > > The only way I see in which out/inout would actually address the concern > of this proposal is if out/inout were used instead of & at the call-site, > but the parameter were still a normal reference. I don't think that's a > good idea because it breaks symmetry between arguments and parameters, and > also squanders any future potential to use out/inout as a way to reduce > reference-use in this context. > > Does that make sense, Rowan? To put is more compactly, what I want is an > eventual state where given $fn($a) I have a guarantee that $a is not going > to be magically modified, without having to perform any global reasoning > about what $fn may refer to. If an alternative proposal does not result in > this eventual state, then it is not an alternative to this proposal (but > possibly still a valuable addition in itself). > It does, yes. I guess what I had in mind was that *in the long-term*, out/inout parameters would replace & parameters, so rather than declare(require_reference_at_call_site=1) you would have declare(disable_reference_parameters=1). Whether or not it's a direct alternative to this proposal, I also worry that out/inout parameters are somewhat mutually exclusive with it: the more effort is spent on making reference parameters "better", the less appetite there will be for replacing them altogether. I agree the behaviour of type annotations would need deciding, but arguably that should have been true for by-reference parameters; it's somewhat bizarre that you can write "function foo(SomeClass &$x) { $x=42; }" The solution would probably be to reuse the "typed references" from the typed property implementation. > Bob has brought up another interesting issue: This proposal currently does > not address the case of foo(...$a), where references into $a may be added > if foo() has by-reference parameters. The suggestion was to use foo(&...$a) > -- however in this case only to *allow* the use of references, not require > it (some args may be by-val while others may be by-ref). > There's probably a bit of a rabbit-hole if the mission is "make references explicit". An array containing a reference can be passed by value, for instance, so $fn($a) might not technically modify $a, but still modify elements inside it. So it seems like we come back to "this is kind of useful information but may not actually offer a hard guarantee". Regards, -- Rowan Collins [IMSoP]