# Implicit isset/isempty check on short-ternary operator

- Thread: https://externals.io/message/51775
- Original archive: https://news-web.php.net/php.internals/51775
- Started by David Coallier on 2011-03-31T16:29:49+00:00
- Messages: 73
- Page 1 of 3: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/51775.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #51775 — David Coallier — 2011-03-31T16:29:49+00:00

URL: https://externals.io/message/51775#51775

Hey there,

I've been working on a little patch that will allow variables ($1) in
a short-ternary operation to go through an implicit isset
(zend_do_isset_or_isempty) check so that the average use-case for the
short-ternary operator doesn't yield in a notice whenever the first
variable of the expression isn't set.

So the use-case I'm considering is the following:

<?php
    $list = array('name' => 'list');

    echo $list['name'] ?: 'List not set.' . PHP_EOL;
    echo $list['name-notset'] ?: 'List not set.' . PHP_EOL;
?>

This example, which we all know, will result in a notice for the
second echo statement because the requested array-key doesn't actually
exist in the array.

Now, looking at the original implementation thread of ifsetor and ?: I
can see that Marcus' patch had an implicit isset() on the first
variable but I cannot seem to track down why this wasn't implemented
in the final patch.

I'm merely looking for counter-arguments as to why an implicit
isset/isempty should not be performed when the first argument is
indeed a variable and not an expr. The only counter-argument (If this
can even be considered remotely related to an argument) is that having
an implicit isset() would return the boolean value of the check. See
in the common misconceptions of ifsetor on the wiki [1]

I am not trying to revive ifsetor() because I believe this is an
amazingly ugly language construct and I don't think it has an actual
place in PHP however, implicitly performing the ifestor check on
"variable"s and not "expr" could greatly improve it's usability I
believe.

Anyone has notes about the arguments against the implicit check at the
Chicago Round-Table meeting?

Thanks,

[1] Ifsetor cached wiki rfc:
http://webcache.googleusercontent.com/search?q=cache:jKrV2u7jeokJ:wiki.php.net/rfc/ifsetor+php+ifsetor+patch&cd=1&hl=en&ct=clnk&gl=us&client=firefox-a&source=www.google.com

-- 
David Coallier

---

## #51780 — Ben Schmidt — 2011-03-31T22:46:12+00:00

URL: https://externals.io/message/51775#51780 · In reply to: #51775

> Hey there,
>
> I've been working on a little patch that will allow variables ($1) in
> a short-ternary operation to go through an implicit isset
> (zend_do_isset_or_isempty) check so that the average use-case for the
> short-ternary operator doesn't yield in a notice whenever the first
> variable of the expression isn't set.
>
> So the use-case I'm considering is the following:
>
> <?php
>      $list = array('name' =>  'list');
>
>      echo $list['name'] ?: 'List not set.' . PHP_EOL;
>      echo $list['name-notset'] ?: 'List not set.' . PHP_EOL;
> ?>
>
> This example, which we all know, will result in a notice for the
> second echo statement because the requested array-key doesn't actually
> exist in the array.

I'm not familiar with the construct, but to be honest, I fail to see how
it is useful without the suppression of the notice. I mean, it's a
shorthand for isset($var)?$var:$something_else isn't it? That
presupposes that $var may not be set, but that you've accounted for that
fact, so don't want a notice about it. Obviously the isset() can only be
applied if the 'left hand side' is an lval, but I think it makes sense
to apply it whenever it is an lval.

So a big +1 from me.

Ben.

---

## #51825 — Rafael Dohms — 2011-04-07T18:30:03+00:00

URL: https://externals.io/message/51775#51825 · In reply to: #51780

On Thu, Mar 31, 2011 at 7:46 PM, Ben Schmidt
<mail_ben_schmidt@yahoo.com.au> wrote:
> 
> > […]
>
> I'm not familiar with the construct, but to be honest, I fail to see how
> it is useful without the suppression of the notice. I mean, it's a
> shorthand for isset($var)?$var:$something_else isn't it? That
> presupposes that $var may not be set, but that you've accounted for that
> fact, so don't want a notice about it. Obviously the isset() can only be
> applied if the 'left hand side' is an lval, but I think it makes sense
> to apply it whenever it is an lval.
>
> So a big +1 from me.
>
> Ben.
>

Its also a +1 for me, it would make the ternary operator much more
useful to me e remove lots of verbose code for handling arrays.



-- 
Rafael Dohms
PHP Evangelist and Community Leader
http://www.rafaeldohms.com.br
http://www.phpsp.org.br

---

## #51826 — Rasmus Lerdorf — 2011-04-07T18:41:07+00:00

URL: https://externals.io/message/51775#51826 · In reply to: #51825

> On Thu, Mar 31, 2011 at 7:46 PM, Ben Schmidt
> <mail_ben_schmidt@yahoo.com.au>  wrote:
> > […]
>
> Its also a +1 for me, it would make the ternary operator much more
> useful to me e remove lots of verbose code for handling arrays.

Well, it would change the semantics. And Ben, no, it isn't shorthand for 
an isset() it is like writing (boolean)$var?$var:$something

-Rasmus

---

## #51827 — Matthew Weier O'Phinney — 2011-04-07T21:59:43+00:00

URL: https://externals.io/message/51775#51827 · In reply to: #51826

> 
> > […]
>
> Well, it would change the semantics. And Ben, no, it isn't shorthand for 
> an isset() it is like writing (boolean)$var?$var:$something

It may change the semantics as they stand, but I'd argue that the
_expectation_ from the shorthand ternary is to shorten code that
currently uses isset(). As it is, I have almost no use for it at this
point, as I end up needing to do:

    $value = isset($a[$key]) ? $a[$key] : 'Not set';

which is exactly the situation I had before it was introduced.

-- 
Matthew Weier O'Phinney
Project Lead            | matthew@zend.com
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

## #51828 — Rasmus Lerdorf — 2011-04-07T22:03:48+00:00

URL: https://externals.io/message/51775#51828 · In reply to: #51827

> It may change the semantics as they stand, but I'd argue that the
> _expectation_ from the shorthand ternary is to shorten code that
> currently uses isset(). As it is, I have almost no use for it at this
> point, as I end up needing to do:
>
>      $value = isset($a[$key]) ? $a[$key] : 'Not set';
>
> which is exactly the situation I had before it was introduced.

Not sure why you would have that expectation. The long ternary doesn't 
do that, and there is nothing about the short ternary that changes that. 
There was talk of a new ifsetor type of operator to have those semantics 
but never any talk of changing existing semantics.

-Rasmus

---

## #51829 — Chris Stockton — 2011-04-07T22:12:02+00:00

URL: https://externals.io/message/51775#51829 · In reply to: #51828

Hello,


> 
> > […]

I don't think that changing it to do a implicit isset really fixes the
reason developers use it as previously mentioned. My code is littered
with isset checks, I would rather see a syntax or operator
specifically for this purpose, like ?? since ?: has already been
implemented in a different (and in my opinion in all to many cases not
a useful) way. Syntax doesn't matter to me though long as it serves my
purpose.

  $var = Array('foo' => 'I am set');
  $value = $var['foo'] ?? 'Foo was not set'; // value = "I am set"
  $value = $var['bar'] ?? 'Bar was not set'; // value ="Bar was not
set"; !!no warning!!

---

## #51830 — Etienne Kneuss — 2011-04-07T22:35:26+00:00

URL: https://externals.io/message/51775#51830 · In reply to: #51828

> 
> > […]
> 
> Not sure why you would have that expectation. The long ternary doesn't 
> do that, and there is nothing about the short ternary that changes that. 
> There was talk of a new ifsetor type of operator to have those semantics 
> but never any talk of changing existing semantics.

Well it could (and I believe that was the intention) call !empty instead
of isset, that way the semantics would not be changed, appart from the
lack of error for undefined variables.

Best,

> 
> -Rasmus

---

## #51831 — Stas Malyshev — 2011-04-07T23:02:51+00:00

URL: https://externals.io/message/51775#51831 · In reply to: #51828

Hi!

> > […]
>
> Not sure why you would have that expectation. The long ternary doesn't
> do that, and there is nothing about the short ternary that changes that.

It is true, however I think the amount of boilerplate code produces by 
this paradigm is staggering, and it's about time we fixed that. We had a 
chance of doing it with ?: but for one reason or another it was passed, 
but the need is still there. I think actually the idea of "expr ?? 
expr2", meaning (isset($expr)?$expr:$expr2) is not bad. Anybody sees any 
holes in it?
And yes, I wouldn't be disappointed too much if ?: didn't generate 
notices either. With modern IDEs times when it helped catch typos are 
mostly gone, and now these warnings are just a very annoying reason to 
write boilerplate code.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #51832 — Ben Schmidt — 2011-04-08T02:49:09+00:00

URL: https://externals.io/message/51775#51832 · In reply to: #51826

> 
> > […]
>
> Well, it would change the semantics. And Ben, no, it isn't shorthand for an
> isset() it is like writing (boolean)$var?$var:$something

Thanks for the clarification, Rasmus. That makes sense.

I still think the patch would be very useful, though I can also see how an 
argument could be made for keeping the warning. In my opinion, the case for 
removing the warning is stronger than for keeping it.

Ben.

---

## #51833 — Rasmus Lerdorf — 2011-04-08T05:01:42+00:00

URL: https://externals.io/message/51775#51833 · In reply to: #51831

> Hi!
>
> > […]
>
> It is true, however I think the amount of boilerplate code produces by
> this paradigm is staggering, and it's about time we fixed that. We had a
> chance of doing it with ?: but for one reason or another it was passed,
> but the need is still there. I think actually the idea of "expr ??
> expr2", meaning (isset($expr)?$expr:$expr2) is not bad. Anybody sees any
> holes in it?
> And yes, I wouldn't be disappointed too much if ?: didn't generate
> notices either. With modern IDEs times when it helped catch typos are
> mostly gone, and now these warnings are just a very annoying reason to
> write boilerplate code.

I'm not against coming up with a cleaner no-warning mechanism for this. 
I was just responding to the idea that the intent of ?: was to solve 
this. It never was. We need to be careful about changing the beahviour 
of existing operators.

-Rasmus

---

## #51834 — Adam Richardson — 2011-04-08T07:02:07+00:00

URL: https://externals.io/message/51775#51834 · In reply to: #51833

>
>
> > […]
> operators.
>

Indeed.

The '?' character already is special, so using '??' seems like a safe,
practical approach. However, I'd prefer maintaining the form of the standard
ternary operator with the colon ($value = $var['bar'] ?? : 'Bar was not
set'; // value ="Bar was not) so the '??' operator could be applied in any
situation that one would normally use the standard ternary operator.

// standard
$value = isset($a[$key]) ? $a[$key] : 'Not set';

// new ?? double ternary that performs isset check and omits second
expression
$value = $a[$key] ?? : 'Not set';

// new ?? double ternary that performs isset check and uses second
expression
$value = $a[$key] ?? strtoupper($a[$key]) : 'Not set';

Granted, the last example might be infrequent, but I think there's also a
value in keeping the form of the double ternary (if used at all) the same as
the standard ternary operator for consistency sake.

Adam

-- 
Nephtali:  A simple, flexible, fast, and security-focused PHP framework
http://nephtaliproject.com

---

## #51835 — dukeofgaming — 2011-04-08T07:32:09+00:00

URL: https://externals.io/message/51775#51835 · In reply to: #51834

Hi, just to drop an opinion on something I felt natural when reading this:
how about a word instead?:

$value = 'Not set' unless $a['key'];

I think it would be way more readable.

Regards,

David

On Fri, Apr 8, 2011 at 2:02 AM, Adam Richardson <simpleshot@gmail.com>wrote:

> > […]
>
> Indeed.
>
> The '?' character already is special, so using '??' seems like a safe,
> practical approach. However, I'd prefer maintaining the form of the
> standard
> ternary operator with the colon ($value = $var['bar'] ?? : 'Bar was not
> set'; // value ="Bar was not) so the '??' operator could be applied in any
> situation that one would normally use the standard ternary operator.
>
> // standard
> $value = isset($a[$key]) ? $a[$key] : 'Not set';
>
> // new ?? double ternary that performs isset check and omits second
> expression
> $value = $a[$key] ?? : 'Not set';
>
> // new ?? double ternary that performs isset check and uses second
> expression
> $value = $a[$key] ?? strtoupper($a[$key]) : 'Not set';
>
> Granted, the last example might be infrequent, but I think there's also a
> value in keeping the form of the double ternary (if used at all) the same
> as
> the standard ternary operator for consistency sake.
>
> Adam
>
> --
> Nephtali:  A simple, flexible, fast, and security-focused PHP framework
> http://nephtaliproject.com

---

## #51836 — Ford — 2011-04-08T09:06:52+00:00

URL: https://externals.io/message/51775#51836 · In reply to: #51834

> -----Original Message-----
> From: Adam Richardson [mailto:simpleshot@gmail.com]
> Sent: 08 April 2011 08:02


> 
> Indeed.
> 
> The '?' character already is special, so using '??' seems like a
> safe,
> practical approach. However, I'd prefer maintaining the form of the
> standard
> ternary operator with the colon ($value = $var['bar'] ?? : 'Bar was
> not
> set'; // value ="Bar was not) so the '??' operator could be applied
> in any
> situation that one would normally use the standard ternary operator.
> 
> // standard
> $value = isset($a[$key]) ? $a[$key] : 'Not set';
> 
> // new ?? double ternary that performs isset check and omits second
> expression
> $value = $a[$key] ?? : 'Not set';
> 
> // new ?? double ternary that performs isset check and uses second
> expression
> $value = $a[$key] ?? strtoupper($a[$key]) : 'Not set';
> 

Like it! I would have proposed ??: for the isset() variant of ?:,
and I think decomposing it into a full ternary operator in this way,
with ??: as a degenerate variant, is brilliant.

(Only downside is, people would have to stop referring to *the*
ternary operator!)


Cheers!

Mike

 -- 
Mike Ford,
Electronic Information Developer, Libraries and Learning Innovation,  
Leeds Metropolitan University, C507 City Campus, 
Woodhouse Lane, LEEDS,  LS1 3HE,  United Kingdom 
Email: m.ford@leedsmet.ac.uk 
Tel: +44 113 812 4730



To view the terms under which this email is distributed, please go to http://disclaimer.leedsmet.ac.uk/email.htm

---

## #51837 — Hannes Landeholm — 2011-04-08T09:12:10+00:00

URL: https://externals.io/message/51775#51837 · In reply to: #51834

Hi. I like Adam's suggestion _a lot_ however I'd also find a third
case very useful.

In addition to:
*********
// standard
$value = isset($a[$key]) ? $a[$key] : 'Not set';

// new ?? double ternary that performs isset check and omits second
expression
$value = $a[$key] ?? : 'Not set';

// new ?? double ternary that performs isset check and uses second
expression
$value = $a[$key] ?? strtoupper($a[$key]) : 'Not set';
*********

I would also like a case where you could:

// new ?? double ternary that performs isset check and uses null
$value = $a[$key]??;

This would replace a lot of ugly code I have where: (the @ operator is ugly)

$value = @$a[$key];

When I want to treat all non existing indexes as containing the null value.

~Hannes



>
> > […]
>
> Indeed.
>
> The '?' character already is special, so using '??' seems like a safe,
> practical approach. However, I'd prefer maintaining the form of the standard
> ternary operator with the colon ($value = $var['bar'] ?? : 'Bar was not
> set'; // value ="Bar was not) so the '??' operator could be applied in any
> situation that one would normally use the standard ternary operator.
>
> // standard
> $value = isset($a[$key]) ? $a[$key] : 'Not set';
>
> // new ?? double ternary that performs isset check and omits second
> expression
> $value = $a[$key] ?? : 'Not set';
>
> // new ?? double ternary that performs isset check and uses second
> expression
> $value = $a[$key] ?? strtoupper($a[$key]) : 'Not set';
>
> Granted, the last example might be infrequent, but I think there's also a
> value in keeping the form of the double ternary (if used at all) the same as
> the standard ternary operator for consistency sake.
>
> Adam
>
> --
> Nephtali:  A simple, flexible, fast, and security-focused PHP framework
> http://nephtaliproject.com

---

## #51838 — Rune Kaagaard — 2011-04-08T13:19:37+00:00

URL: https://externals.io/message/51775#51838 · In reply to: #51837

Dear Internals

I'm very happy that this is getting some attention again. Please allow
me to give my 2 cents too. The text below can also be seen nicely
formatted at https://gist.github.com/909711.

## Intro ##

Isset and IsNotEmpty operators have for sure been a hot topic for several years
now and in my opinion rightly so. The non-DRY style of:

    $my_array['my_long_boring_key'] = !empty($my_array['my_long_boring_key'])
                  ? $my_array['my_long_boring_key'] : 'Default value';
    $my_array['my_long_boring_key'] = isset($my_array['my_long_boring_key'])
                  ? $my_array['my_long_boring_key'] : 'Default value';

is a true day-to-day hassle and addressing this annoyance would be a
big win for
the PHP community as a whole. As PHP has two keywords `isset` and `empty` that
can check for a non existing variable without throwing errors I think there
should exist two assignment/ternary operators who mirror those.

I have been thinking [1] about the same problem for my meta language Snow and
also ended up using `??` as an isset operator.

## Proposal ##
I propose that two new operators `??` (IssetOperator) and `?!`
(NotEmptyOperator) are added. `??` mirrors `isset` and `?!` mirrors `!empty`.
They are chainable ad nauseum but not with each other.

They would work like this:

### Example 1 : Ternary shortcut ###
Old syntax:
    $a = isset($b) ? $b : 42;
    $a = !empty($b) ? $b : 42;

New syntax:
    $a = $b ?? 42;
    $a = $b ?! 42;

### Example 2 : Direct assignment ###
Old syntax:
    $arr['key'] = isset($arr['key']) ? $arr['key'] : 42;
    $arr['key'] = !empty($arr['key']) ? $arr['key'] : 42;

New syntax:
    $arr['key'] ??= 42;
    $arr['key'] ?!= 42;

### Example 3 : Works with statements too ###
Old syntax:
    // a)
    $tmp = get_stuff('foo');
    $a = isset($tmp) ? $tmp : 42;

    // b)
    $tmp = get_stuff('foo');
    $a = !empty($tmp) ? $tmp : 42;

New syntax:
    // a)
    $a = get_stuff('foo') ?? 42;

    // b)
    $a = get_stuff('foo') ?! 42;

### Example 4 : Chaining ###
Old syntax [2]:
    $a = false;
    if (!empty($c) {
        $a = $c;
    } else {
        $tmp = get_stuff();
        $a = !empty($tmp) ? $tmp : false;
    }
    if ($a === false) {
        $a = !empty($c) ? $c : 42;
    }

New syntax:
    $a = $c ?! get_stuff() ?! $b ?! 42;

### Example 5 : Illegal syntax ###
    $a = $d ?? $c ?! $b ?? 42; // `??` and `?!` cannot be mixed.

## References ##
     * [1]: http://code.google.com/p/php-snow/wiki/EmptyIssetOperators
     * [2]: This could also be done by nesting ternary operators, but that gets
            even more unreadable I think.

---

## #51839 — Jordi Boggiano — 2011-04-08T13:57:30+00:00

URL: https://externals.io/message/51775#51839 · In reply to: #51838

> New syntax:
>     // a)
>     $a = get_stuff('foo') ?? 42;
> 
>     // b)
>     $a = get_stuff('foo') ?! 42;

This is wrong. The "new syntax" is already available since 5.3.0 and is

$a = get_stuff('foo') ?: 42;

Now I agree with you, it sounds great and all, but we have to be clear:

$a ?: $b  =>  $a ? $a : $b

And ?? should equal to !empty($a), or otherwise said isset($a) && $a
So:

$a ?? $b  =>  (isset($a) && $a) ? $a : $b

Again, your example1 was unclear. !empty is not the equivalent of
isset(). They only are equal if the value is null, but not for false or
"" or array().

Seeing how everyone says confusing stuff here, I'm starting to think
those shortcuts may actually be more harmful than anything.

I'd just favor switching ?: to be equivalent to !empty() instead of just
a cast to boolean, because it means we can drop the isset checks, and
the semantics wouldn't change - only BC "break" would be warnings going
away. The rest, adding new operators, is dangerous imo.

Cheers

-- 
Jordi Boggiano
@seldaek :: http://seld.be/

---

## #51840 — Hannes Landeholm — 2011-04-08T14:27:05+00:00

URL: https://externals.io/message/51775#51840 · In reply to: #51838

I think "?!" wouldn't work as an operator as it would conflict with ternary
comparision + not operator. Also I don't see the point of adding an operator
for "empty" as the function/construct itself is pretty confusing and
non-useful as you have to memorize all the things that happen to be
considered "empty" by it and those things has too align up with the things
you want to check for by chance. (I never use it.)

Empty-ness is just one of a billion things you might want to write a
comparison for (and it's not even well defined). Having an operator for that
would be crazy. Dealing with possibly undefined indexes/properties is a very
common use case though which is why I think it deserves an operator. The
"empty comparison" thing is a _separate issue_ and it can simply be dealt
with by separating the assignment and comparison into two expressions...

~Hannes



> Dear Internals
>
> I'm very happy that this is getting some attention again. Please allow
> me to give my 2 cents too. The text below can also be seen nicely
> formatted at https://gist.github.com/909711.
>
> ## Intro ##
>
> Isset and IsNotEmpty operators have for sure been a hot topic for several
> years
> now and in my opinion rightly so. The non-DRY style of:
>
>    $my_array['my_long_boring_key'] =
> !empty($my_array['my_long_boring_key'])
>                  ? $my_array['my_long_boring_key'] : 'Default value';
>    $my_array['my_long_boring_key'] = isset($my_array['my_long_boring_key'])
>                  ? $my_array['my_long_boring_key'] : 'Default value';
>
> is a true day-to-day hassle and addressing this annoyance would be a
> big win for
> the PHP community as a whole. As PHP has two keywords `isset` and `empty`
> that
> can check for a non existing variable without throwing errors I think there
> should exist two assignment/ternary operators who mirror those.
>
> I have been thinking [1] about the same problem for my meta language Snow
> and
> also ended up using `??` as an isset operator.
>
> ## Proposal ##
> I propose that two new operators `??` (IssetOperator) and `?!`
> (NotEmptyOperator) are added. `??` mirrors `isset` and `?!` mirrors
> `!empty`.
> They are chainable ad nauseum but not with each other.
>
> They would work like this:
>
> ### Example 1 : Ternary shortcut ###
> Old syntax:
>    $a = isset($b) ? $b : 42;
>    $a = !empty($b) ? $b : 42;
>
> New syntax:
>    $a = $b ?? 42;
>    $a = $b ?! 42;
>
> ### Example 2 : Direct assignment ###
> Old syntax:
>    $arr['key'] = isset($arr['key']) ? $arr['key'] : 42;
>    $arr['key'] = !empty($arr['key']) ? $arr['key'] : 42;
>
> New syntax:
>    $arr['key'] ??= 42;
>    $arr['key'] ?!= 42;
>
> ### Example 3 : Works with statements too ###
> Old syntax:
>    // a)
>    $tmp = get_stuff('foo');
>    $a = isset($tmp) ? $tmp : 42;
>
>    // b)
>    $tmp = get_stuff('foo');
>    $a = !empty($tmp) ? $tmp : 42;
>
> New syntax:
>    // a)
>    $a = get_stuff('foo') ?? 42;
>
>    // b)
>    $a = get_stuff('foo') ?! 42;
>
> ### Example 4 : Chaining ###
> Old syntax [2]:
>    $a = false;
>    if (!empty($c) {
>        $a = $c;
>    } else {
>        $tmp = get_stuff();
>        $a = !empty($tmp) ? $tmp : false;
>    }
>    if ($a === false) {
>        $a = !empty($c) ? $c : 42;
>    }
>
> New syntax:
>    $a = $c ?! get_stuff() ?! $b ?! 42;
>
> ### Example 5 : Illegal syntax ###
>    $a = $d ?? $c ?! $b ?? 42; // `??` and `?!` cannot be mixed.
>
> ## References ##
>     * [1]: http://code.google.com/p/php-snow/wiki/EmptyIssetOperators
>     * [2]: This could also be done by nesting ternary operators, but that
> gets
>            even more unreadable I think.

---

## #51841 — Martin Scotta — 2011-04-08T14:45:14+00:00

URL: https://externals.io/message/51775#51841 · In reply to: #51840

I just feels that !empty($arr['key']) or isset($arr['key']) do not express
the real meaning, instead I would choose to write array_key_exists('key',
$arr). It may be slower but it clearly express what I meant.

Regarding the operators, I believe they will do more harm than good.
To check if a variable was already defined is a bad programing habit, these
operators will encourage that kind of things

In the other hand, the isset check inside the condition ?: would silently
improve not-so-well written code, and could be a good feature for the lang.

 Martin Scotta


On Fri, Apr 8, 2011 at 11:27 AM, Hannes Landeholm <landeholm@gmail.com>wrote:

> I think "?!" wouldn't work as an operator as it would conflict with ternary
> comparision + not operator. Also I don't see the point of adding an
> operator
> for "empty" as the function/construct itself is pretty confusing and
> non-useful as you have to memorize all the things that happen to be
> considered "empty" by it and those things has too align up with the things
> you want to check for by chance. (I never use it.)
>
> Empty-ness is just one of a billion things you might want to write a
> comparison for (and it's not even well defined). Having an operator for
> that
> would be crazy. Dealing with possibly undefined indexes/properties is a
> very
> common use case though which is why I think it deserves an operator. The
> "empty comparison" thing is a _separate issue_ and it can simply be dealt
> with by separating the assignment and comparison into two expressions...
>
> ~Hannes
>
> 
>
> > […]
> isset($my_array['my_long_boring_key'])
> > […]
> there
> > […]

---

## #51842 — Hannes Landeholm — 2011-04-08T15:47:46+00:00

URL: https://externals.io/message/51775#51842 · In reply to: #51841

Operators should have very specific purpose and function... a ternary if
statement should just be another way to express a normal if statement.
Making the ? operator suppress the not defined error would be a poor
compromise, making PHP inconsistent. Then I'd rather have access of
non-defined array indexes return null instead (simply removing the
not-defined notice for arrays - where array_key_exists and isset would still
work like normal if you want to check for undefined).

~Hannes



> I just feels that !empty($arr['key']) or isset($arr['key']) do not express
> the real meaning, instead I would choose to write array_key_exists('key',
> $arr). It may be slower but it clearly express what I meant.
>
> Regarding the operators, I believe they will do more harm than good.
> To check if a variable was already defined is a bad programing habit, these
> operators will encourage that kind of things
>
> In the other hand, the isset check inside the condition ?: would silently
> improve not-so-well written code, and could be a good feature for the lang.
>
>  Martin Scotta
>
>
>
> On Fri, Apr 8, 2011 at 11:27 AM, Hannes Landeholm <landeholm@gmail.com>wrote:
>
> > […]

---

## #51843 — Matt Pelmear — 2011-04-08T15:54:33+00:00

URL: https://externals.io/message/51775#51843 · In reply to: #51841

Hello all,
First post here; been watching for a while though.

IMHO:
1) Implicit isset() checks in ?: would be bad. This would not
"silently improve not-so-well written code"; In fact it would make
not-so-well written code more difficult to debug. I can't count the
number of times I've run across components that are acting oddly
because somebody wrote them to ignore the fact that they're not
receiving some required parameter. At least with the current
functionality of ?: we get a warning. If the collective decision were
to implement this, could it at least have a setting to force it to
function how it does currently?

2) A shorthand assignment operator would be handy. I like the suggestion of ??=
where:
$var ??= $default;
is shorthand for
if( !isset($var) ) $var = $default;
Or, maybe similar to C#
$var = $var ?? $default;
(Correct me if I'm using this syntax incorrectly)

This would provide a clean way to set defaults for unset vars but
would make it easy to find blocks of code that are using unset vars
with the ternary operator.


-Matt


> I just feels that !empty($arr['key']) or isset($arr['key']) do not express
> the real meaning, instead I would choose to write array_key_exists('key',
> $arr). It may be slower but it clearly express what I meant.
>
> Regarding the operators, I believe they will do more harm than good.
> To check if a variable was already defined is a bad programing habit, these
> operators will encourage that kind of things
>
> In the other hand, the isset check inside the condition ?: would silently
> improve not-so-well written code, and could be a good feature for the lang.
>
>  Martin Scotta

---

## #51844 — Ben Schmidt — 2011-04-08T16:05:42+00:00

URL: https://externals.io/message/51775#51844 · In reply to: #51841

> I just feels that !empty($arr['key']) or isset($arr['key']) do not express
> the real meaning, instead I would choose to write array_key_exists('key',
> $arr). It may be slower but it clearly express what I meant.

I don't like this. array_key_exists will return true for an array key
that exists but is set to null, which is rarely what is wanted (though
it sometimes is).

I agree that the variants with empty() aren't very good.

Just a single isset() variant seems like a good idea. I favour the ??:
syntax.

I liked the well-thought-out examples with assignment and chaining and
so on. For chaining, does associativity matter? (Too tired to figure it
out for myself right now!)

Ben.

---

## #51846 — Sanford Whiteman — 2011-04-08T18:34:41+00:00

URL: https://externals.io/message/51775#51846 · In reply to: #51843

> First post here; been watching for a while though.

Same here.

Here's my take:

[1]  I  don't like ?? / ? because it is disjunctive with === / ==.. The
extra  equals  sign  strengthens  equality comparison, while the extra
question  mark  essentially  _weakens_ the ternary operator (making it
more forgiving). (Sure, a case could be made that an "extra" duplicate
operator has no inherent meaning overall, but these two operators seem
to be in a similar domain.)

[2]  I  would prefer @?. This makes the error-suppression obvious. But
this leads to...

[3]  ...  are we saying that [a] we are still suppressing a deep error
or  [b]  or that an error state does not exist anywhere when you use a
special  operator?  In  other  words,  is  it  now  going  to be fully
supported  to  use  undefined  variables,  as  long  as  we always use
operators  that  take  them  into  account?  This seems to be inviting
criticism  from other language fanboys (if we care) since they already
hold the non-fatal use of undefined variables in contempt.

[4]  Strange  idea:  what about treating the variable as defined after
you  test it with the special operator, even if you don't specifically
assign it a value?

So:

$varor2  =  $var1  @?:  2  //  $varor2==2,  no warning because special
ternary is used

$varor3  =  $var1  ?: 3 // $varor3=3, but no warning because $var1 has
been implicitly defined in special expression

[5]  Sort  of  the opposite of [4] and continuing the question of [3],
what  about  only letting a variable be special-op-checked once before
throwing  a  warning. So you can suppress (or not throw) the undefined
warning  once,  but it is assumed that you will define the variable in
that  statement.  So  this  would discourage the continuous use of the
same  undef var throughout code (which seems like a code smell), while
allowing  for the real case that you're using the special-op to filter
$_REQUEST or whatever -- one time.

I  haven't  really  thought about the edges, but thought I'd put those
out there.

Cheers,

Sandy

---

## #51848 — Rune Kaagaard — 2011-04-09T12:16:52+00:00

URL: https://externals.io/message/51775#51848 · In reply to: #51846

Hi guys

Below is a discussion about some of the issues being raised. Again a
nicely formatted version of the whole thing is here:
https://gist.github.com/909711.

## Discussion ##

### About changing the beviour of the ternary shortcut ###

@Jordi, others

Some suggest adding an implicit `isset` around the value being tested in the
ternary shortcut. This I think is less than optimal because:

1. It would be a huge BC break, because a boolean test and a isset test differs
   greatly. [3]
2. It would be a major WTF, because it would work different than the normal
   ternary operator that it is a shortcut of.

Jordi suggests adding an implicit `!empty` around the value being tested in the
ternary shortcut. This would not break BC but it still wouldn't improve usecases
where the value tested for is allowed to be falsy ('', 0, "0", false, etc.):

    function render_articles($rows, $settings) {
        // Shows the last page per default. Zero based.
        $settings['page_num'] = $settings['page_num'] ?: count($rows) - 1;
        // ...
    }

    // Lets render_articles showing the first page.
    echo render_articles ($rows, array('page_num' => 0));

The obvious bug here is that since 0 is considered falsy, render_articles
will show the last page instead of the first. The correct version is back in
non-dry mode:

    $settings['page_num'] = isset($settings['page_num'])
        ? $settings['page_num']
        : count($rows) - 1;

Im writing the same stuff three times. With the `??` operator it would be:

    $settings['page_num'] ??= count($rows) - 1;

### Why we need both an Isset and IsNotEmpty operator ###

@Hannes, Ben

What's considered falsy in PHP is _very_ dynamic. Depending on context the
following can easily be considered falsy:

    '', null, undefined, array(), false, 0

Therefore we need to be very precise when we are making decisions based on a
variable or statements value. This is where `isset` and `!empty` compliments
each other very well. Sometimes i want to use a default value when falsy means
"this variable is not defined". Other times I want to assign a default value
when falsy means "this variable is not an empty string".

Sometimes the behaviour we want will change while we are working on the code.
Therefore I strongly believe that not having both operators would severely break
the symmetry and force the end user to make tedious and non-dry refactorings
just because he needs a function to - under certain conditions -
return false or
vice versa.

## References ##
    * [3]: http://php.net/manual/en/types.comparisons.php

---

## #51852 — D. Dante Lorenso — 2011-04-09T19:20:03+00:00

URL: https://externals.io/message/51775#51852 · In reply to: #51830

> 
> > […]
>
> Well it could (and I believe that was the intention) call !empty instead
> of isset, that way the semantics would not be changed, appart from the
> lack of error for undefined variables.


Since I see the beast has risen from the dead, I'd like to chime in 
again for my proposal to have a "function" called "filled".  It is the 
opposite of empty() and takes variable number of arguments.  The first 
non-empty value is returned.  example:

$x = filled($myarray['badkey'], $varundef, $obj->nosuch, $default);

This *must* be created in the Zend engine because userland can not catch 
the unset keys and variables.

Again, "filled()" would be the opposite of empty() and we'd need some 
other function similar to be the opposite of isset() if you wanted that 
type of check.  The proposed `filled()` will suit all my needs with great 
satisfaction :-)

-- Dante

----------
D. Dante Lorenso
dante@lorenso.com
972-333-4139

---

Next page: https://externals.io/message/51775.md?page=2
