On Mon, Jul 29, 2019 at 10:40 AM Claude Pache <claude.pa...@gmail.com> wrote:
> > > > Le 28 juil. 2019 à 21:12, Marco Pivetta <ocram...@gmail.com> a écrit : > > > > On Sun, Jul 28, 2019 at 9:06 PM Stanislav Malyshev <smalys...@gmail.com> > > wrote: > > > >> Hi! > >> > >>> Nah, by-ref is pretty much avoided in OSS packages, but we can surely > >>> survey the ecosystem to verify this. > >> > >> I literally work with code that uses references every day. So may be you > >> haven't encountered it but the attitude of "nah, never happens" I think > >> is a bit misplaced. > >> Also please remember not all PHP code is latest composer packages. In > >> fact, most of it isn't. > >> > > > > I do work with code like that: the teams maintaining these codebases are > > actively removing by-ref calls when they encounter them. > > > > Marco Pivetta > > Do your teams actively remove direct calls to array_push() and > array_multisort()? In any case, I’m sure that most PHP developers don’t. > This discussion seems to have lost track of the context ... the original quote (which Stas cherry-picked in a way that lost the original meaning): > I think nowadays it is well known that by-reference passing is to be avoided and I don't see it particularly commonly in user code. By-reference passing is mainly used when it is needed to interact with existing by-reference functions such as preg_match(). We can hardly switch these functions to use out/inout if we require the corresponding keyword on the call-site. You seem to be agreeing with what I originally said: That by-reference passing is mainly useful to interoperate with by-reference internal functions, which don't exactly leave you with a choice. --- In any case, I think the popularity of by-reference passing ultimately doesn't really matter much: By-reference passing still exists, will continue to exist and we have to deal with it. Which is also why I think that the question of out/inout parameters is quite orthogonal to this proposal: The problem I'm trying to address is that currently, both humans, static analyzers and the engine have a hard time telling whether an argument is going to be passed by reference (or otherwise indirectly modified) or not. Humans may use API familiarity to help them, static analyzers can (unreliably) try to infer this through global analysis, while the engine is entirely out of luck apart from the simplest of cases. 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). --- 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). I'm not sure whether I like that idea or not. I think there's value in making it clear that an unpack may be by reference, but at the same time I find the discrepancy between foo(&$a) (*must* be ref) and foo(&...$a) (*may* be ref) somewhat confusing. Regards, Nikita