Re: Unifying logical operators
| From: | Walter Parker | Date: | Tue, 10 Jul 2018 06:26:32 +0000 |
| Subject: | Re: Unifying logical operators | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-102682@lists.php.net to get a copy of this message | ||
On Mon, Jul 9, 2018 at 9:03 PM Ryan <iggyvolz@gmail.com> wrote:
> Hello all! Longtime PHP user, first-time contributor to internals (sorry
> if I screw anything up)!
>
> I'd like to propose either the deprecation (7.next - likely 7.4 at this
> point) and removal (8.0) of the T_LOGICAL_OR (or), T_LOGICAL_AND (and), and
> T_LOGICAL_XOR (xor) tokens, or aliasing them to ||, &&, and !=
> respectively.
>
> The behaviours of the two sets of logical operators are very similar (it's
> incredibly unclear how $x or $y would differ from $x||$y). They perform
> almost identically except for the fact that the former set has a precedence
> lower that the assignment, null coalescing, and ternary operators[1]. The
> page on logical operators[2] states that the reason the two variations
> exist is that they "operate at different precedences" (which isn't a reason
> for existence, but rather a statement of differences).
>
> Example #1 on the logical operators page[2] gives an example of this
> difference:
> $e = false || true; // true
> $f = false or true; // false
>
> Because of the difference of precedence, the second line is evaluated as
> ($f = false) or true;
>
> In my mind (and in the mind of every programmer I've spoken to about this),
> this violates the principle of least astonishment[3]. The assignment
> operator is usually thought to be the lowest level of precedence other than
> parenthesis (as a typical statement would be "do some thing, then assign
> its value to this varible").
>
> This[4] stackoverflow question sheds some light on the intent of the
> alternative operators - they are used for "control flow" in the style of
> Ruby's "unless" operator[5]:
>
> defined("SOME_CONSTANT") or die("SOME_CONSTANT was not defined");
>
> However, this behaviour has nothing to do with the difference of precedence
> - rather this is due to short circuiting.
>
> The only difference between the two (unless there are interactions I'm not
> aware of with the ternary or null coalescing operator) is the precedence
> with the assignment operator, causing the return value to be assigned
> without respect to the conditional. I ran a quick (possibly imperfect)
> script on GitHub's top 30 repositories, and of the usages of the
> T_LOGICAL_* operators all but this one[6] operated equivalently to the
> symbolic ones:
> $gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD
> image stream');
>
> In this case, the result of imagecreatetruecolor is intended to be placed
> in $gdImage, or if it is falsey, die with an error. This could be
> rewritten as:
> ($gdImage = @imagecreatetruecolor(120, 20)) || die('Cannot Initialize new
> GD image stream');
>
> Or, in my opinion, more cleanly:
> $gdImage = @imagecreatetruecolor(120, 20);
> if(!$gdImage) die('Cannot Initialize new GD image stream');
>
That is a matter of style, as I find $a = func() or die more clear that the
version that uses ||
Not chaining stuff together is a third style.
This feels like a Python PEP request. By that I mean that Python wants to
have only one way to do any one task. Perl style is there’s more than one
way to do it.
PHP has been a mix of these styles.
The big question I have is how much PHP code will break due to an enforced
style requirement?
Removing them for style seems like it would be a big BC break. Aliasing
them might lead to more subtle bugs in legacy code.
>
> I've written a very rough draft RFC here[7] - and I would love feedback.
> If it's taken well I can put it up on the wiki.
>
> Thanks,
> Ryan "Iggy" Volz
>
> [1]: http://php.net/manual/en/language.operators.precedence.php
> [2]: http://php.net/manual/en/language.operators.logical.php
> [3]:
> https://en.wikipedia.org/wiki/Principle_of_least_astonishment
> [4]: https://stackoverflow.com/a/5998351
> [5]:
>
>
> https://www.tutorialspoint.com/ruby/ruby_if_else.htm#Ruby%20unless%20modifier
> [6]:
>
>
> https://github.com/PHPOffice/PhpSpreadsheet/blob/aa5b0d0236c907fd8dba0883f3ceb97cc52e46ec/samples/Basic/25_In_memory_image.php#L24
> - likely copied from
> http://php.net/manual/en/function.imagecreatetruecolor.php
> [7]: https://github.com/iggyvolz/Unifying-Operators-RFC
>
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis