-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Implement explicit send-by-ref #2958
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Sounds like a great idea, however, it seems to me that it would be much more useful if there were an optional way to require this mode, and also an optional way to issue warnings when this flag is not passed. To avoid creating more "strict modes" for users to think about, what if implicit pass-by-reference was deprecated in strict mode, issuing a warning to users who have enabled warnings? |
I really like this proposal. @elijah-120 such a change to the strict mode would be possible in PHP 8. I think it's a good idea to think about that. However, that can easily be another RFC. |
@elijah-120 I don't like the idea of rolling other, unrelated "strictness" features into the existing strict_types flag. I think the best way to do handle this would be through a separate option in combination with https://wiki.php.net/rfc/namespace_scoped_declares, but that proposal did not seem to be well-received. |
Another possible solution would be to simply deprecate the implicit feature language wide and issuing a warning with PHP 8, remove it in 10-15 years. Warnings are pretty harmless and this one is easy to correct, as opposed to deprecating something like preg_replace /e for which there is no easy fix. The idea is that users who read the code will not have any idea that their variable is being modified. No doubt this was taken from C++, but in that case, they have both pointers and const in case they wish to do something more declarative. It is debatable, but some style dialects (ie. google https://google.github.io/styleguide/cppguide.html#Reference_Arguments) forbid the non-const pass by reference. Lets say you wanted to write a function that returns an additional value to a parameter - you would use a pointer, rather than trick the user with a hidden &, if not careless. PHP is pass reference for objects and copy-on-write for arrays and strings, so valid uses of pass-by-reference are limited to returning extra values and sorting an array. |
I was about to say that a fuction like "sort()" is an exception (as it is void return), but actually php array functions are not consistent about whether they modify in place or have return. For example, a user might write array_change_key_case($array) and think that it changed the case of $array, when really it does nothing. So just because you didn't assign sort($array) doesn't mean it is pass-by-reference. You have to know that. |
I like this idea although I was wondering how will this compare against typehints, both in function parameters and return typehints. Am I mistaking or this will look like this: function &func(int &$var): int IMHO more reasonable place for function func(int &$var): &int Although when not using typehints the |
@prgTW Yes, you are mistaken about the examples and the typehints. Check the examples in the p/r desc. My idea was just to add a warning when a variable is passed by reference but not using & at call time, but no new syntax from the proposal above. |
858c374
to
9128867
Compare
9128867
to
223dd72
Compare
Currently, in order to pass an argument by reference, the reference has to be declared at the definition-site, but not at the call-site: function byRef(&$ref) {} byRef($var); This change adds the ability to specify the by reference pass at *both* the definition-site and the call-site: function byRef(&$ref) {} byRef(&$var); Importantly, specifying a reference during the call will generate an error if the argument is not also declared by-reference at the declaration site: function byVal($val) {} byVal(&$val); // ERROR This makes it different from the call-time-pass-by-reference feature in PHP 4. If this feature is used, the reference has to be declared at both the call- *and* declaration-site. Note that it is still possible to not explicitly specify the use of by-reference passing at the call-site. As such, the following code remain legal: function byRef(&$ref) {} byRef($var);
This is a placeholder for a mode in which & annotations are required.
Swap the numbers for the PREFER_REF and PREFER_VAL passing modes to make the SHOULD_BE_SENT_BY_REF check more efficient.
Today we already have PHP 8 beta1! |
No. |
@nikic Is it ok to close this PR and the associated RFC? |
Yeah, don't plan any immediate work here. |
RFC: https://wiki.php.net/rfc/explicit_send_by_ref
Currently, in order to pass an argument by reference, the reference
has to be declared at the definition-site, but not at the call-site:
This change adds the ability to specify the by reference pass at
both the definition-site and the call-site:
Importantly, specifying a reference during the call will generate
an error if the argument is not also declared by-reference at the
declaration site:
This makes it different from the call-time-pass-by-reference
feature in PHP 4. If this feature is used, the reference has to
be declared at both the call- and declaration-site.
Note that it is still possible to not explicitly specify the use
of by-reference passing at the call-site. As such, the following
code remain legal: