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 operators1. The
page on logical operators2 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 page2 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 astonishment3. 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").
This4 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" operator5:
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 one6 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
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 theT_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 operators1. The
page on logical operators2 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 page2 gives an example of this
difference:
$e = false || true; // true
$f = false or true; // falseBecause 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 astonishment3. 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").This4 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[5]:
https://www.tutorialspoint.com/ruby/ruby_if_else.htm#Ruby%20unless%20modifier
[6]:
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
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]
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
“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]
“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
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
Den tir. 10. jul. 2018 kl. 20.22 skrev Larry Garfield larry@garfieldtech.com:
"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
Hi,
Den tir. 10. jul. 2018 kl. 20.22 skrev Larry Garfield larry@garfieldtech.com:
"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.
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 narf@devilix.net
escreveu:
Hi,
On Tue, Jul 10, 2018 at 9:37 PM, Kalle Sommer Nielsen kalle@php.net
wrote:Den tir. 10. jul. 2018 kl. 20.22 skrev Larry Garfield <
larry@garfieldtech.com>:"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.--
--
David Rodrigues
Den tir. 10. jul. 2018 kl. 21.08 skrev David Rodrigues david.proweb@gmail.com:
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
Den tir. 10. jul. 2018 kl. 21.08 skrev David Rodrigues david.proweb@gmail.com:
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]
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 theT_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.
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]
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 rowan.collins@gmail.com
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 looks1 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.
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.
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 rowan.collins@gmail.com
wrote:
Den tir. 10. jul. 2018 kl. 21.08 skrev David Rodrigues <
david.proweb@gmail.com>: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.
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.
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.
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.--
--
The greatest dangers to liberty lurk in insidious encroachment by men of
zeal, well-meaning but without understanding. -- Justice Louis D. Brandeis
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.
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".
Hi,
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 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 rowan.collins@gmail.com
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 kalle@php.net
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]