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

Reply via email to