Welcome! Log In Create A New Profile

Advanced

[PHP-DEV] Unifying logical operators

Posted by Ryan 
Ryan
[PHP-DEV] Unifying logical operators
July 10, 2018 05:10AM
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');

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
Walter Parker
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 08:30AM
On Mon, Jul 9, 2018 at 9:03 PM Ryan <[email protected]> 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
Rowan Collins
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 11:10AM
On 10 July 2018 at 04:02, Ryan <[email protected]> wrote:

>
> 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.
>


As your own next example demonstrates, it does rely on the difference in
precedence, because without it, you could only use this idiom after
carefully checking that the left-hand side would be evaluated in one go,
and probably using an extra set of parentheses.


> ($gdImage = @imagecreatetruecolor(120, 20)) || die('Cannot Initialize new
GD image stream');

This is less readable both because of the extra parentheses, and because
the || operator is not as easily read as the English word "or".

While I've not seen it used much in PHP code, the "do this or die" idiom is
common in Perl (which also has post-fix "if" and "unless" modifiers, so
those are a different feature again).

IF there is sufficient harm in having the extra operators, I would say
removal is the only option - making them behave as aliases for || etc would
just lead to even more confusion when they *don't* work the same way as in
Perl, and in earlier versions of PHP. I'm not 100% convinced by the harm,
though.


Finally, a note on the "xor" operator - your draft says that this is
equivalent to "!=", but that is not the case, because both can operate on
non-boolean values. Consider "1 != 2" (true) vs "1 xor 2" (false). I don't
think I've ever had a use for logical xor in PHP code, but there isn't
anything to confuse it with, so no reason to remove it.

Regards,
--
Rowan Collins
[IMSoP]
Christoph M. Becker
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 01:20PM
On 10.07.2018 at 11:01, Rowan Collins wrote:

> While I've not seen it used much in PHP code, the "do this or die" idiom is
> common in Perl (which also has post-fix "if" and "unless" modifiers, so
> those are a different feature again).

It seems to me the “do this or die” idiom at least has been very common
in PHP. There may still be some occurences in the manual proper, and
definitely there are occurences in user contributed notes.

> Finally, a note on the "xor" operator - your draft says that this is
> equivalent to "!=", but that is not the case, because both can operate on
> non-boolean values. Consider "1 != 2" (true) vs "1 xor 2" (false). I don't
> think I've ever had a use for logical xor in PHP code, but there isn't
> anything to confuse it with, so no reason to remove it.

“xor” is equivalent to ^ (sans the precedence).

--
Christoph M. Becker

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Rowan Collins
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 01:50PM
On 10 July 2018 at 12:09, Christoph M. Becker <[email protected]> wrote:

>
> “xor” is equivalent to ^ (sans the precedence).
>


No, that's a *bitwise* XOR, which is a completely different operation:

var_dump(1 xor 2); // bool(false)
var_dump(1 ^ 2); // int(3)

A consistent logical XOR with the same precedence as || and && could
perhaps be spelled ^^, but there is no such operator in PHP.

Regards,
--
Rowan Collins
[IMSoP]
Christoph M. Becker
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 02:20PM
On 10.07.2018 at 13:41, Rowan Collins wrote:

> On 10 July 2018 at 12:09, Christoph M. Becker <[email protected]> wrote:
>
>> “xor” is equivalent to ^ (sans the precedence).
>
> No, that's a *bitwise* XOR, which is a completely different operation:
>
> var_dump(1 xor 2); // bool(false)
> var_dump(1 ^ 2); // int(3)
>
> A consistent logical XOR with the same precedence as || and && could
> perhaps be spelled ^^, but there is no such operator in PHP.

Thanks. I stand corrected!

--
Christoph M. Becker

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Larry Garfield
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 08:30PM
On Tuesday, July 10, 2018 6:09:22 AM CDT Christoph M. Becker wrote:
> On 10.07.2018 at 11:01, Rowan Collins wrote:
> > While I've not seen it used much in PHP code, the "do this or die" idiom
> > is
> > common in Perl (which also has post-fix "if" and "unless" modifiers, so
> > those are a different feature again).
>
> It seems to me the “do this or die” idiom at least has been very common
> in PHP. There may still be some occurences in the manual proper, and
> definitely there are occurences in user contributed notes.

"do() or die()" code is/was very common in example code, tutorials, and other
intro material because it means you don't need to think about error handling.

I haven't seen it in actual production code in about 14 yeas, I think, and
anyone who tried submitting it would get their patch rejected so hard it would
make their head spin. It's a terrible pattern outside of fly-by-night
tutorials.

--Larry Garfield
Kalle Sommer Nielsen
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 08:40PM
Den tir. 10. jul. 2018 kl. 20.22 skrev Larry Garfield <[email protected]>:
> "do() or die()" code is/was very common in example code, tutorials, and other
> intro material because it means you don't need to think about error handling.

I personally wanted to extend this syntax but I never got around to it
to support: "do() or throw new Exception(...);", tho its just a code
style over: "if(!do()){ throw new Exception(...); }"



--
regards,

Kalle Sommer Nielsen
kalle@php.net

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Andrey Andreev
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 09:10PM
Hi,

On Tue, Jul 10, 2018 at 9:37 PM, Kalle Sommer Nielsen <[email protected]> wrote:
> Den tir. 10. jul. 2018 kl. 20.22 skrev Larry Garfield <[email protected]>:
>> "do() or die()" code is/was very common in example code, tutorials, and other
>> intro material because it means you don't need to think about error handling.
>
> I personally wanted to extend this syntax but I never got around to it
> to support: "do() or throw new Exception(...);", tho its just a code
> style over: "if(!do()){ throw new Exception(...); }"
>

I sometimes declare a closure that throws an exception to do just
that. It's very convenient in short(ish) scripts.

isset($foo) OR $foo = 'bar'; (and similar variations using empty()
and/or &&) is another pattern I use often to set fallback values for
empty or missing inputs.

An eventual deprecation would make literally all of my code output
entire screens of warnings.

Cheers,
Andrey.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
David Rodrigues
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 09:10PM
I think that "or" could be removed if PHP could supports inline
conditionals like:

die() if !$connected;
throw Exception() if fail();
$x = $y if (z() && w());

Or "when": die() when !$connected;

It seems more clear than $connected or die().

Em ter, 10 de jul de 2018 às 15:59, Andrey Andreev <[email protected]>
escreveu:

> Hi,
>
> On Tue, Jul 10, 2018 at 9:37 PM, Kalle Sommer Nielsen <[email protected]>
> wrote:
> > Den tir. 10. jul. 2018 kl. 20.22 skrev Larry Garfield <
> [email protected]>:
> >> "do() or die()" code is/was very common in example code, tutorials, and
> other
> >> intro material because it means you don't need to think about error
> handling.
> >
> > I personally wanted to extend this syntax but I never got around to it
> > to support: "do() or throw new Exception(...);", tho its just a code
> > style over: "if(!do()){ throw new Exception(...); }"
> >
>
> I sometimes declare a closure that throws an exception to do just
> that. It's very convenient in short(ish) scripts.
>
> isset($foo) OR $foo = 'bar'; (and similar variations using empty()
> and/or &&) is another pattern I use often to set fallback values for
> empty or missing inputs.
>
> An eventual deprecation would make literally all of my code output
> entire screens of warnings.
>
> Cheers,
> Andrey.
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

--
David Rodrigues
Kalle Sommer Nielsen
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 09:20PM
Den tir. 10. jul. 2018 kl. 21.08 skrev David Rodrigues <[email protected]>:
>
> I think that "or" could be removed if PHP could supports inline conditionals like:
>
> die() if !$connected;
> throw Exception() if fail();
> $x = $y if (z() && w());
>
> Or "when": die() when !$connected;
>
> It seems more clear than $connected or die().

I in fact find that more unreadable as you first got to dig through
the error handling before you actually get to the logic that triggered
it.


--
regards,

Kalle Sommer Nielsen
kalle@php.net

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Rowan Collins
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 09:30PM
On 10/07/2018 20:11, Kalle Sommer Nielsen wrote:
> Den tir. 10. jul. 2018 kl. 21.08 skrev David Rodrigues <[email protected]>:
>> I think that "or" could be removed if PHP could supports inline conditionals like:
>>
>> die() if !$connected;
>> throw Exception() if fail();
>> $x = $y if (z() && w());
>>
>> Or "when": die() when !$connected;
>>
>> It seems more clear than $connected or die().
> I in fact find that more unreadable as you first got to dig through
> the error handling before you actually get to the logic that triggered
> it.


A more readable syntax, if we were designing from scratch, might be to
look at SmallTalk, where ifTrue and ifFalse are methods on the boolean
class, so can appear post-fix after any boolean, giving you something like:

$connected ifFalse: die();


Regards,

--
Rowan Collins
[IMSoP]


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Michael Morris
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 09:50PM
On Mon, Jul 9, 2018 at 10:03 PM Ryan <[email protected]> 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.
>

While having these behave they do is unfortunate, it is hardly the only one
of PHP's quirks. Ever looked at the ramifications of loose typing with
comparison? http://phpsadness.com/sad/52


> 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.


True, but that's still a lot of code to break. A *lot* of code. Far too
much to consider changing this even at a major level I would think.

PHP if anything, is too pragmatic a language for this change.
Rowan Collins
Re: [PHP-DEV] Unifying logical operators
July 10, 2018 11:30PM
On 10/07/2018 20:38, Michael Morris wrote:
> While having these behave they do is unfortunate, it is hardly the only one
> of PHP's quirks. Ever looked at the ramifications of loose typing with
> comparison?http://phpsadness.com/sad/52


Eugh, I hate that site, and I hate that it's so widely linked as though
it's some kind of well-researched resource rather than the ramblings of
one rather opinionated developer.

That's one of the more reasonable pages, but it's still an awful lot of
words and spurious diagrams to say "coercing values means comparisons
are intransitive in certain situations (most of which you'd never notice
in every day use)".

Regards,

--
Rowan Collins
[IMSoP]


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Ryan
Re: [PHP-DEV] Unifying logical operators
July 11, 2018 04:30AM
On Tue, Jul 10, 2018 at 2:26 AM, Walter Parker <[email protected]> wrote:

>
> 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?.
>

As I said in the OP, out of the top 30 GitHub repositories (the first page
on the API since I couldn't figure out how to get to the second), there was
only one line that would require a change (and it was copy-pasted from the
manual). Obviously there's no way to truly know how many times it's used
in non-public code, but I'll expand my GitHub search and report back some
more solid metrics.

Removing them for style seems like it would be a big BC break. Aliasing
> them might lead to more subtle bugs in legacy code.
>

PHP 7 code should never be blindly upgraded to PHP 8 (which is what this
would target for actual changes, not just deprecation/notices). This would
have to be clearly stated in the upgrade guide.


On Tue, Jul 10, 2018 at 5:01 AM, Rowan Collins <[email protected]>
wrote:
>
>
> As your own next example demonstrates, it does rely on the difference in
> precedence, because without it, you could only use this idiom after
> carefully checking that the left-hand side would be evaluated in one go,
> and probably using an extra set of parentheses.
>

The defined or die idiom does not depend on precedence, because it doesn't
contain an assignment operator. One could theoretically do
$isDefined=defined("X") or die() - however that would be pointless as
$isDefined would always be true.


> > ($gdImage = @imagecreatetruecolor(120, 20)) || die('Cannot Initialize
> new GD image stream');
>
> This is less readable both because of the extra parentheses, and because
> the || operator is not as easily read as the English word "or".
>

The readability issue is why I included the option to alias to or. I
definitely agree that x() or die() looks better than x()||die().


>
> While I've not seen it used much in PHP code, the "do this or die" idiom
> is common in Perl (which also has post-fix "if" and "unless" modifiers, so
> those are a different feature again).
>

Forgive my lack of knowledge with perl, but it looks[1] like they only
support a postfix if and postfix unless operators - which can serve the
same purpose as PHP's and/or (x and y => y if x, x or y => y unless !x)..
However, I'm not aware of any language that uses and/or for this
behaviour. I doubt there will be sufficient cause for confusion with perl
as many languages have slightly different behaviours for and/or (and
whether they use the text or symbolic versions). Lua and python use
and/or, but don't convert the result to boolean and C{,#,++} use symbolic
and convert the result to boolean. I don't know of a language that uses
and/or in this way (unless I'm wrong about Perl) to denote a postfix
operator.


>
> IF there is sufficient harm in having the extra operators, I would say
> removal is the only option - making them behave as aliases for || etc would
> just lead to even more confusion when they *don't* work the same way as in
> Perl, and in earlier versions of PHP. I'm not 100% convinced by the harm,
> though.
>

My thought for aliasing is that it may help with legacy code (if you're not
relying on the return value, which is 99% of cases), as well as there being
no symbolic equivalent for xor (as you state below it's not equivalent to
!= as I thought)


>
>
> Finally, a note on the "xor" operator - your draft says that this is
> equivalent to "!=", but that is not the case, because both can operate on
> non-boolean values. Consider "1 != 2" (true) vs "1 xor 2" (false). I don't
> think I've ever had a use for logical xor in PHP code, but there isn't
> anything to confuse it with, so no reason to remove it.
>

Ah, my mistake. My only experience with xor was one class that I sat in on
in the middle of the semester. It may be worth adding a symbolic
representation of xor regardless.




On Tue, Jul 10, 2018 at 2:37 PM, Kalle Sommer Nielsen <[email protected]> wrote:

>
> I personally wanted to extend this syntax but I never got around to it
> to support: "do() or throw new Exception(...);", tho its just a code
> style over: "if(!do()){ throw new Exception(...); }"
>

do() or throw doesn't actually work because throw is a language construct,
not a function.
$ php -r 'false or throw new Exception();'
PHP Parse error: syntax error, unexpected 'throw' (T_THROW) in Command
line code on line 1

I actually ran into this at work today writing a bootstrap function. I had
a function that would return a class that would either give the path to a
file in a subdirectory, or null if it didn't exist. I was attempting to
call it like $file=self::findFile("subdirectory") and return $file;
(continuing the loop if it didn't return). However, this isn't possible
since return is a language construct.

[1]: http://perl101.org/flow-control.html


On Tue, Jul 10, 2018 at 2:58 PM, Andrey Andreev <[email protected]> wrote:

> isset($foo) OR $foo = 'bar'; (and similar variations using empty()
> and/or &&) is another pattern I use often to set fallback values for
> empty or missing inputs.
>
> An eventual deprecation would make literally all of my code output
> entire screens of warnings.
>

$foo=$foo??"bar"; would work there. I could definitely see this being an
issue if you weren't using isset (although a concrete example of that
doesn't come to mind right away).




On Tue, Jul 10, 2018 at 3:21 PM, Rowan Collins <[email protected]>
wrote:

> On 10/07/2018 20:11, Kalle Sommer Nielsen wrote:
>
>> Den tir. 10. jul. 2018 kl. 21.08 skrev David Rodrigues <
>> [email protected]>:
>>
>>> I think that "or" could be removed if PHP could supports inline
>>> conditionals like:
>>>
>>> die() if !$connected;
>>> throw Exception() if fail();
>>> $x = $y if (z() && w());
>>>
>>> Or "when": die() when !$connected;
>>>
>>> It seems more clear than $connected or die().
>>>
>> I in fact find that more unreadable as you first got to dig through
>> the error handling before you actually get to the logic that triggered
>> it.
>>
>
>
> A more readable syntax, if we were designing from scratch, might be to
> look at SmallTalk, where ifTrue and ifFalse are methods on the boolean
> class, so can appear post-fix after any boolean, giving you something like:
>
> $connected ifFalse: die();
>

I hesitate to propose adding a new syntax to PHP, especially for something
so rarely used it makes me question if it's truly necessary. If anything I
would think we should prefer a syntax that we can point to other languages
as examples (like the if/unless syntax from Ruby). It feels odd to clean
up a rarely used operator by replacing it with fresh syntactical sugar.

On Tue, Jul 10, 2018 at 3:38 PM, Michael Morris <[email protected]> wrote:

> > 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.
>
>
> True, but that's still a lot of code to break. A *lot* of code. Far too
> much to consider changing this even at a major level I would think.
>
> PHP if anything, is too pragmatic a language for this change


I don't understand what you mean by a lot of code to break - this line
would be completely unaffected if the aliasing option was chosen. By the
second line, I meant that PHP supports this behaviour in both the or and ||
operators.
Alice Wonder
Re: [PHP-DEV] Unifying logical operators
July 11, 2018 05:00AM
On 07/10/2018 07:20 PM, Ryan wrote:
> On Tue, Jul 10, 2018 at 2:26 AM, Walter Parker <[email protected]> wrote:
>
>>
>> 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?.
>>
>
> As I said in the OP, out of the top 30 GitHub repositories (the first page
> on the API since I couldn't figure out how to get to the second), there was
> only one line that would require a change (and it was copy-pasted from the
> manual). Obviously there's no way to truly know how many times it's used
> in non-public code, but I'll expand my GitHub search and report back some
> more solid metrics.

Using github may not be the most reliable method.

Look at what is most popularly used in composer dependencies.

For example, I know xor is used in PHP Codesniffer which while likely
not often part of deployed code is very often a devel dependency.

I think phpunit also uses xor and is also very popular.

I use xor myself but my use is purely hobby (I have a pseudo-RNG written
in PHP that can take any source of data, random or not, and pass it
through a filter that makes it pass pRNG tests - showing that passing
tests doesn't mean a random source is necessarily random enough for
cryptography)

Anyway as I believe you have already conceded, nuking xor would require
many projects used a lot to have to change.


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Walter Parker
Re: [PHP-DEV] Unifying logical operators
July 11, 2018 05:40AM
On Tue, Jul 10, 2018 at 7:58 PM, Alice Wonder <[email protected]> wrote:

> On 07/10/2018 07:20 PM, Ryan wrote:
>
>> On Tue, Jul 10, 2018 at 2:26 AM, Walter Parker <[email protected]> wrote:
>>
>>
>>> 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?.
>>>
>>>
>> As I said in the OP, out of the top 30 GitHub repositories (the first page
>> on the API since I couldn't figure out how to get to the second), there
>> was
>> only one line that would require a change (and it was copy-pasted from the
>> manual). Obviously there's no way to truly know how many times it's used
>> in non-public code, but I'll expand my GitHub search and report back some
>> more solid metrics.
>>
>
> Using github may not be the most reliable method.
>
>
There are 67 Million repositories on GitHub, is picking the top 30 PHP
projects a representative sample of PHP use across the Internet?
80% of web servers where the back end language was known had PHP according
to a recent survey.
Picking 30 popular open source projects might bias the results of what you
think is going in PHP usage.


Look at what is most popularly used in composer dependencies.
>
> For example, I know xor is used in PHP Codesniffer which while likely not
> often part of deployed code is very often a devel dependency.
>
> I think phpunit also uses xor and is also very popular.
>
> I use xor myself but my use is purely hobby (I have a pseudo-RNG written
> in PHP that can take any source of data, random or not, and pass it through
> a filter that makes it pass pRNG tests - showing that passing tests doesn't
> mean a random source is necessarily random enough for cryptography)
>
> Anyway as I believe you have already conceded, nuking xor would require
> many projects used a lot to have to change.
>
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
Ryan
Re: [PHP-DEV] Unifying logical operators
July 11, 2018 06:00AM
On Tue, Jul 10, 2018 at 10:58 PM, Alice Wonder <[email protected]> wrote:

> Using github may not be the most reliable method.
>

> Look at what is most popularly used in composer dependencies.


Absolutely - but it's the first one that came to mind when thinking of "how
to get popular repositories really quick". I'm sorting by stars, but I can
definitely also check any dependencies if they aren't already in the list.


>
> For example, I know xor is used in PHP Codesniffer which while likely not
> often part of deployed code is very often a devel dependency.
>
> I think phpunit also uses xor and is also very popular.
>
> I use xor myself but my use is purely hobby (I have a pseudo-RNG written
> in PHP that can take any source of data, random or not, and pass it through
> a filter that makes it pass pRNG tests - showing that passing tests doesn't
> mean a random source is necessarily random enough for cryptography)
>
> Anyway as I believe you have already conceded, nuking xor would require
> many projects used a lot to have to change.


I'm absolutely not trying to take away behaviour with real use cases like
xor. That's why I'm leaning more heavily on the aliasing side so it would
break very little code. If the decision was made to remove the text
operators (or whatever the proper name for and, or, and xor is), there
would need to be a symbolic xor operator.



On Tue, Jul 10, 2018 at 11:37 PM, Walter Parker <[email protected]> wrote:

> There are 67 Million repositories on GitHub, is picking the top 30 PHP
> projects a representative sample of PHP use across the Internet?
> 80% of web servers where the back end language was known had PHP according
> to a recent survey.
> Picking 30 popular open source projects might bias the results of what you
> think is going in PHP usage.


Of course not - I'm working on expanding the search (right now to 300, and
then I'll probably do 3,000 overnight) as we speak and I'll go as far as my
hard drive (and patience, and GitHub API) will allow. I don't really know
of a good way to get usage metrics for a token beyond "get some code using
PHP and check for the token".
Andrey Andreev
Re: [PHP-DEV] Unifying logical operators
July 11, 2018 09:40AM
Hi,

On Wed, Jul 11, 2018 at 5:20 AM, Ryan <[email protected]> wrote:
> On Tue, Jul 10, 2018 at 2:58 PM, Andrey Andreev <[email protected]> wrote:
>
>> isset($foo) OR $foo = 'bar'; (and similar variations using empty()
>> and/or &&) is another pattern I use often to set fallback values for
>> empty or missing inputs.
>>
>> An eventual deprecation would make literally all of my code output
>> entire screens of warnings.
>>
>
> $foo=$foo??"bar"; would work there. I could definitely see this being an
> issue if you weren't using isset (although a concrete example of that
> doesn't come to mind right away).
>

I'm very well aware of the alternatives, that's not the point. I and
although not a majority, many others too would have to go and replace
countless instances of OR usage, for no reason other than "it can be
done another way".

Aside from a few people asking what the difference is, in more than a
decade with PHP, I've never seen a single person who's had a problem
with the operators you want to deprecate. They're not a common cause
for bugs even by a long shot, nor a common annoyance, so I fail to see
the benefits of your proposal.

Cheers,
Andrey.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Rowan Collins
Re: [PHP-DEV] Unifying logical operators
July 11, 2018 11:30AM
On 11 July 2018 at 03:20, Ryan <[email protected]> wrote:

>
> PHP 7 code should never be blindly upgraded to PHP 8 (which is what this
> would target for actual changes, not just deprecation/notices). This would
> have to be clearly stated in the upgrade guide.
>


There's a big difference between "not blindly updating" and "having to run
a static analysis tool and carefully read its results to stop your code
having a subtly different behaviour".

Introducing new errors is nearly always better than silently changing
behaviour (this is the entire principle of run-time type checks, after all).




> On Tue, Jul 10, 2018 at 5:01 AM, Rowan Collins <[email protected]>
> wrote:
> > As your own next example demonstrates, it does rely on the difference in
> > precedence, because without it, you could only use this idiom after
> > carefully checking that the left-hand side would be evaluated in one go,
> > and probably using an extra set of parentheses.
> >
>
> The defined or die idiom does not depend on precedence, because it doesn't
> contain an assignment operator. One could theoretically do
> $isDefined=defined("X") or die() - however that would be pointless as
> $isDefined would always be true.
>


Right, which is why I said your *next* example, which did use assignment.
The point is that *reliably using the idiom* requires a specific
precedence, so that you don't have to carefully vet which other operators
are involved in the expression.




> > While I've not seen it used much in PHP code, the "do this or die" idiom
> > is common in Perl (which also has post-fix "if" and "unless" modifiers,
> so
> > those are a different feature again).
> >
>
> Forgive my lack of knowledge with perl, but it looks[1] like they only
> support a postfix if and postfix unless operators - which can serve the
> same purpose as PHP's and/or (x and y => y if x, x or y => y unless !x).
>

Perhaps I worded that badly. I was saying two things:

- The "do or die" idiom is extremely common in Perl. Just searching the
documentation should be enough to convince you of that:
https://duckduckgo.com/?q=site%3Aperldoc.perl.org+"or+die";
- Perl *also* has post-fix if and unless operators, which you had mentioned
in Ruby (Ruby inherited a lot from Perl). Clearly, people don't see these
as a better replacement for the use of "or".




> My thought for aliasing is that it may help with legacy code (if you're not
> relying on the return value, which is 99% of cases), as well as there being
> no symbolic equivalent for xor (as you state below it's not equivalent to
> != as I thought)
>


Just to reiterate, I strongly feel that aliasing is not an option. If the
aim is to reduce confusion, having the same code give different results in
different PHP versions is a massive own goal.




> On Tue, Jul 10, 2018 at 2:37 PM, Kalle Sommer Nielsen <[email protected]>
> wrote:
>
> >
> > I personally wanted to extend this syntax but I never got around to it
> > to support: "do() or throw new Exception(...);", tho its just a code
> > style over: "if(!do()){ throw new Exception(...); }"
> >
>
> do() or throw doesn't actually work because throw is a language construct,
> not a function.
>


Yes, hence "wanted to extend this syntax" - the suggestion is that this
would be a useful feature to add, not one that already exists.




> > A more readable syntax, if we were designing from scratch, might be to
> > look at SmallTalk, where ifTrue and ifFalse are methods on the boolean
> > class, so can appear post-fix after any boolean, giving you something
> like:
> >
> > $connected ifFalse: die();
> >
>
> I hesitate to propose adding a new syntax to PHP, especially for something
> so rarely used it makes me question if it's truly necessary. If anything I
> would think we should prefer a syntax that we can point to other languages
> as examples (like the if/unless syntax from Ruby). It feels odd to clean
> up a rarely used operator by replacing it with fresh syntactical sugar.
>


I agree that adding new syntax is unnecessary for this, but since you keep
mentioning the postfix if/unless which Ruby inherited from Perl, I thought
I'd point to another language we could borrow syntax from, which is
actually closer to the current idiom ("condition keyword action", not
"action keyword condition").


Regards,
--
Rowan Collins
[IMSoP]
Sorry, only registered users may post in this forum.

Click here to login