Hi Ken I totally agree with Andreas especially:
One purpose of the operator should be that you don't have to repeat > the variable. Here you do, e.g. $_SERVER['fname'] But if this operator provide some way not to repeat the variable it will make sense. For example: $_SERVER['fname'] !?? $user->setName($$) But I think this functionality should be of something like pipeline operator: // send tmp variable to the next expression unconditionally $ret = $_SERVER['fname'] |> $user->setName($$); // send tmp variable to the next expression only when $_SERVER['fname'] is set. $ret = $_SERVER['fname'] ?|> $user->setName($$); Also the syntax like above will be consistent with the proposed safe-navigation operators. Cheers On Fri, Oct 25, 2019 at 3:29 AM Andreas Hennings <andr...@dqxtech.net> wrote: > On Thu, 24 Oct 2019 at 20:59, Ken Stanley <doh...@gmail.com> wrote: > > > > On Thu, Oct 24, 2019 at 1:33 PM Dan Ackroyd <dan...@basereality.com> > wrote: > > > > > On Thu, 24 Oct 2019 at 18:21, Ken Stanley <doh...@gmail.com> wrote: > > > > > > > > Since PHP 7.0 brought forward the Null Coalescing Operator (??), > writing > > > > more succinct code for how to handle null values has been a blessing. > > > But, > > > > what about the inverse when you want to do something when a value is > not > > > > null? > > > > > > Hi Ken, > > > > > > It may help to give a real world example, rather than a metasyntactic > > > one, as I can't immediately see how this would be useful. > > > > > > People have been expressing a concern over 'symbol soup' for similar > > > ideas. The null colalesce scenario happens frequently enough, that it > > > seemed to overcome the hurdle needed for acceptance. Again, giving a > > > real world example of what you currently need to do frequently might > > > help other people understand the need. > > > > > > cheers > > > Dan > > > > > > > Hi Dan, > > > > After some thought, and searching through my existing code bases, I > believe > > I've come up with a decent code example to help demonstrate the > usefulness > > of the proposed anti-coalescing-operator: > > > > Without !??: > > <?php > > > > class ExampleController > > { > > /** > > * PATCH a User object. > > */ > > public function saveAction(int $userId) > > { > > $user = $this->getUser($userId); > > > > if (isset($_SERVER['fname']) { > > $user->setName($_SERVER['fname']); > > } > > > > if (isset($_SERVER['lname']) { > > $user->setName($_SERVER['lname']); > > } > > > > if (isset($_SERVER['mname']) { > > $user->setName($_SERVER['mname']); > > } > > > > if (isset($_SERVER['phone']) { > > $user->setName($_SERVER['phone']); > > } > > > > if (isset($_SERVER['email']) { > > $user->setName($_SERVER['email']); > > } > > > > $this-saveUser($user); > > } > > } > > > > With !??: > > <?php > > > > class ExampleController > > { > > /** > > * PATCH a User object. > > */ > > public function saveAction(int $userId) > > { > > $user = $this->getUser($userId); > > > > $_SERVER['fname'] !?? $user->setName($_SERVER['fname']); > > $_SERVER['lname'] !?? $user->setName($_SERVER['lname']); > > $_SERVER['mname'] !?? $user->setName($_SERVER['mname']); > > $_SERVER['phone'] !?? $user->setName($_SERVER['phone']); > > $_SERVER['email'] !?? $user->setName($_SERVER['email']); > > > > $this-saveUser($user); > > } > > } > > Thank you, > > Ken Stanley > > Not convinced. > 1. Most of the perceived brevity is from omitting line breaks and > curly brackets, which is a bit misleading imo. > 2. It is not the intended use of these kinds of operators (ternary or > null coalesce). Normally you would use them to produce a value, here > you use them for control flow only. > 3. One purpose of the operator should be that you don't have to repeat > the variable. Here you do, e.g. $_SERVER['fname'] > > 1. > If you would simply omit the line breaks in the first version, you > would get this: > > if (isset($_SERVER['fname'])) $user->setName($_SERVER['fname']); > if (isset($_SERVER['lname'])) $user->setName($_SERVER['lname']); > if (isset($_SERVER['mname'])) $user->setName($_SERVER['mname']); > if (isset($_SERVER['phone'])) $user->setName($_SERVER['phone']); > if (isset($_SERVER['email'])) $user->setName($_SERVER['email']); > > 2. > Instead of "abusing" your new operator, you could simply "abuse" the > old ternary ?: instead: > > !isset($_SERVER['fname']) ?: $user->setName($_SERVER['fname']); > !isset($_SERVER['lname']) ?: $user->setName($_SERVER['lname']); > !isset($_SERVER['mname']) ?: $user->setName($_SERVER['mname']); > !isset($_SERVER['phone']) ?: $user->setName($_SERVER['phone']); > !isset($_SERVER['email']) ?: $user->setName($_SERVER['email']); > > 3. > One way to not repeat the variable would be to introduce a temporary > local variable, like so: > > if (NULL !== $fname = $_SERVER['fname'] ?? NULL) > $user->setName($fname); > > This gets more useful if the variable expression is something longer. > > A new language feature for this purpose could have an anatomy like this: > https://3v4l.org/TjuuO or > https://3v4l.org/U6arm > > and the short syntax would be like so: > > $product = ($x ??! NULL) * ($y ??! NULL); > > or the NULL can be omitted: > > $product = ($x ??!) * ($y ??!); > > So, the operator would break out of the current expression context, > and produce a value one level up, a bit like a try/throw/catch would, > or like a break in switch. > > This is just a basic idea, it still leaves a lot of questions open. > If the expression context is multiple levels deep, how many of these > levels are we breaking? > > I am not suggesting this is a good idea, but I think it is an > improvement to the original proposal. > > -- Andreas > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >