Re: [Proposal] Modification to ?: functionality

From: Date: Tue, 26 Nov 2013 18:23:13 +0000
Subject: Re: [Proposal] Modification to ?: functionality
References: 1 2 3 4 5 6  Groups: php.internals 
Request: Send a blank email to internals+get-70424@lists.php.net to get a copy of this message
On Tue, Nov 26, 2013 at 1:08 PM, Etienne Kneuss <colder@php.net> wrote: > > > > On Tue, Nov 26, 2013 at 6:57 PM, Philip Sturgeon <pjsturgeon@gmail.com> > wrote: >> >> On Tue, Nov 26, 2013 at 12:41 PM, Paul Dragoonis <dragoonis@gmail.com> >> wrote: >> > On Tue, Nov 26, 2013 at 4:58 PM, Chris London <me@chrislondon.co> wrote: >> > >> >> On Tue, Nov 26, 2013 at 8:15 AM, Mats Lindh <mats.lindh@gmail.com> >> >> wrote: >> >> >> >> > On Tue, Nov 26, 2013 at 3:43 PM, Chris London <me@chrislondon.co> >> >> > wrote: >> >> > >> >> >> I believe these two statements are functionally equivalent: >> >> >> >> >> >> $foo = $foo ? $foo : 'default'; >> >> >> >> >> >> $foo = $foo ?: 'default'; >> >> >> >> >> > >> >> > They are. >> >> > >> >> > >> >> > I would like to change it so it also checks for isset() so I propose >> >> > the >> >> >> following would be functionally equivalent: >> >> >> >> >> >> $foo = isset($foo) && $foo ? $foo : 'default'; >> >> >> >> >> >> $foo = $foo ?: 'default'; >> >> >> >> >> >> > >> > We can't change the behaviour of ?: that ship has already sailed, we'll >> > just be hurting existing codebases on upgrading and more user education >> > is >> > required to understand non-visual changes in syntax like this, lets try >> > to >> > learn from our mistakes by not changing 'behaviour' anymore. >> > >> > An alternative syntax that is similar and not ugly would be good since >> > the >> > ?: behaviour was broken from the start since you still need to run >> > isset() >> > before running ?: which was the problem we tried to solve in the first >> > place but it just didn't happen. >> > >> > I don't like the @ symbol it's too different from what's already there >> > on >> > the ternary logic. >> > >> > Proposal: $foo = $arr['value'] ?:: ""; >> > >> > Thoughts? >> > >> >> >> >> > The would break the assumption that a reference to an uninitialized >> >> > value >> >> > would generate a notice, unless explicitly handled in the logic. >> >> > >> >> > While I also would like to have something similar to ?: to handle >> >> > default >> >> > values for array keys, etc., this would change a fundamental >> >> > assumption >> >> > that as been in place for many years now. I'm not sure if that's a >> >> > BC >> >> break >> >> > that would be acceptable this late. An alternative operator may be >> >> > more >> >> > suitable. >> >> > >> >> >> >> What do you think about using: >> >> >> >> $foo = $foo @: 'default'; >> >> >> >> and possibly >> >> >> >> $foo @= 'default'; >> >> >> >> >> >> >> >> > >> >> > The change proposed has also been discussed several times since the >> >> > implementation of ?:. See the ifsetor-RFC: >> >> > >> >> > https://wiki.php.net/rfc/ifsetor >> >> > >> >> > It also contains links to the discussion around the feature back >> >> > then. >> >> > >> >> > --mats >> >> > >> >> >> >> This seems like a cracking time to suggest: >> >> $x ||= $y; >> >> The difference? Anything left of the ? SHOULD fail if it is not set, >> because you are using it in a condition which is dangerous and odd for >> other types of condition, but adding in this new syntax (similar to >> Ruby) would essentially evaluate to this: >> >> >> empty($x) ? $y : $x; >> >> This gives keeps the behavior of ternary operators working in the same >> way, but adds what we want: the ability to nicely set defaults for >> variables and array keys that may not be set. > > > To me this reads as $x = $x || $y like all the <OP>= binary operators. So it > would definitely feel weird to use that syntax for something else... > >> >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php >> > > > > -- > Etienne Kneuss > http://www.colder.ch It is not $x = $x || $y but $x || $x = $y. http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html Ternary is being used by us to set defaults, but it is not the only use of ternary, so making it totally quieten potential warnings and errors is a weird use of a ternary. It's one of those "we do it this way because its all we have" options and going further down the road of abusing ternaries for this functionality does not make the situation more simple. Currently: $foo = isset($foo) && $foo ? $foo : 'default'; Proposed change by OP (with BC break): $foo = $foo ?: 'default'; New ternary suggested by others, with "error suppressing": $foo = $foo ??: 'default'; People will try using that with all sorts of other operators involved. What happens when you do $foo = $foo == 'bar' ??: 'default'; It gets complicated. $foo ||= 'default'; Pretty obvious what is happening. If foo is falsey it will use 'default'. We can wrap $foo in isset or empty and make it more durable, which certainly would take care of the OP's concerns without breaking the way ternaries currently work - which is not actually broken just not very handy at setting defaults for non-existent variables.

« previous php.internals (#70424) next »