# Implicit isset in ternary operator

- Thread: https://externals.io/message/61394
- Original archive: https://news-web.php.net/php.internals/61394
- Started by Rafael Dohms on 2012-07-18T14:15:44+00:00
- Messages: 29
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/61394.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

---

## #61394 — Rafael Dohms — 2012-07-18T14:15:44+00:00

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

Hey Everyone,

With the syntax improvements for 5.4 and some of the de-referencing work,
code looks so much sleeker then before, but there is still one use case
that really bugs me.

Given this code:

$width = (isset($config['width']))? $config['width'] : 300;

The code is pretty straight forward, if width is set in the array, use it
otherwise use 300.

This code would look much better if it could make use of the ternary
operator

$width = $config['width'] ?: 300;

The only reason for this to not work is: it throws a notice if the array
key is not there (which is the case we are covering anyway)

This is basically because the ternary operator does not do a internal
implicit isset, only an empty.

Does this seem like a possible improvement we can work on? Anyone
interested in championing the change?

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

---

## #61395 — Anthony Ferrara — 2012-07-18T14:20:43+00:00

URL: https://externals.io/message/61394#61395 · In reply to: #61394

Rafael,

One point of clarity:

On Wed, Jul 18, 2012 at 10:15 AM, Rafael Dohms <listas@rafaeldohms.com.br>wrote:

> Hey Everyone,
>
> With the syntax improvements for 5.4 and some of the de-referencing work,
> code looks so much sleeker then before, but there is still one use case
> that really bugs me.
>
> Given this code:
>
> $width = (isset($config['width']))? $config['width'] : 300;
>
> The code is pretty straight forward, if width is set in the array, use it
> otherwise use 300.
>
> This code would look much better if it could make use of the ternary
> operator
>
> $width = $config['width'] ?: 300;
>
> The only reason for this to not work is: it throws a notice if the array
> key is not there (which is the case we are covering anyway)
>
> This is basically because the ternary operator does not do a internal
> implicit isset, only an empty.
>

It does not do an empty. Empty would avoid notices as well. All it does is
an implicit bool cast...


> Does this seem like a possible improvement we can work on? Anyone
> interested in championing the change?
>

I like it in principle. My only concern is *why* wasn't it done this way in
the first place... Is there a reason?

Anthony

---

## #61396 — Rafael Dohms — 2012-07-18T14:23:59+00:00

URL: https://externals.io/message/61394#61396 · In reply to: #61395

On Wed, Jul 18, 2012 at 4:20 PM, Anthony Ferrara <ircmaxell@gmail.com>wrote:

>
> Does this seem like a possible improvement we can work on? Anyone
> > […]
>
> I like it in principle. My only concern is *why* wasn't it done this way
> in the first place... Is there a reason?
>
>
I don't recall correctly, there was a thread on this by David Coalier some
time ago, but it went completely off course and i remember BC breaks were
part of the reason. I think we have a good plan for BC breaks now, so why
not rethink this.


> Anthony
>
>


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

---

## #61400 — Gustavo Lopes — 2012-07-18T14:33:23+00:00

URL: https://externals.io/message/61394#61400 · In reply to: #61394

> With the syntax improvements for 5.4 and some of the de-referencing 
> work,
> code looks so much sleeker then before, but there is still one use 
> case
> that really bugs me.
>
> Given this code:
>
> $width = (isset($config['width']))? $config['width'] : 300;
>

Do we have to do this again?... We had this discussion an year ago.

See
http://grokbase.com/t/php/php-internals/113zbx5y77/implicit-isset-isempty-check-on-short-ternary-operator
http://grokbase.com/t/php/php-internals/114br1w6gs/proposed-access-modifier-silent-was-re-php-dev-implicit-isset-isempty-check-on-short-ternary-operator

-- 
Gustavo Lopes

---

## #61401 — Andrew Faulds — 2012-07-18T14:37:17+00:00

URL: https://externals.io/message/61394#61401 · In reply to: #61396

Sounds good. CoffeeScript (a lightweight language with JS semantics that
compiles to JS) has a existential operator, "?", and this looks similar and
would be very nice. It's not the same thing, of course. It also reminds me
of JavaScript's || behaviour.


> On Wed, Jul 18, 2012 at 4:20 PM, Anthony Ferrara <ircmaxell@gmail.com
> > […]
>
> > […]
> I don't recall correctly, there was a thread on this by David Coalier some
> time ago, but it went completely off course and i remember BC breaks were
> part of the reason. I think we have a good plan for BC breaks now, so why
> not rethink this.
>
>
> > […]
>
>
> --
> Rafael Dohms
> PHP Evangelist and Community Leader
> http://www.rafaeldohms.com.br
> http://www.phpsp.org.br

---

## #61430 — Galen Wright-Watson — 2012-07-18T19:21:01+00:00

URL: https://externals.io/message/61394#61430 · In reply to: #61395

On Wed, Jul 18, 2012 at 7:20 AM, Anthony Ferrara <ircmaxell@gmail.com>wrote:

>
> On Wed, Jul 18, 2012 at 10:15 AM, Rafael Dohms <listas@rafaeldohms.com.br
> > […]
>
> > […]
>
> It does not do an empty. Empty would avoid notices as well. All it does is
> an implicit bool cast...
>
>
> > […]
>
> I like it in principle. My only concern is *why* wasn't it done this way in
> the first place... Is there a reason?
>

It changes the semantics. If the variable is set to a falsey value and ?:
uses an implicit isset, the value of the expression will be the falsey
value.

    $config['width'] = ''
    $width = $config['width'] ?: 300
    # $width == ''

If !empty were used instead of isset, you could preserve semantics ($a ?:
dflt = !empty($a) ? $a : dflt).

---

## #61442 — Stan Vass — 2012-07-18T21:39:41+00:00

URL: https://externals.io/message/61394#61442 · In reply to: #61430

> It changes the semantics. If the variable is set to a falsey value and ?:
> uses an implicit isset, the value of the expression will be the falsey
> value.
>
>    $config['width'] = ''
>    $width = $config['width'] ?: 300
>    # $width == ''
>
> If !empty were used instead of isset, you could preserve semantics ($a ?:
> dflt = !empty($a) ? $a : dflt).
>

Since this has been discussed before, here's a previous solution with zero 
of those problems:

// A new operator.
$width = $config['width'] ?? 300;

// Actual behavior of the operator in pseudo code:
$width = isset($config['width']) ? $config['width'] : 300;

Why wasn't it implemented? No reason, it just wasn't. But people keep asking 
about it, so it's only a matter of time.

Stan

---

## #61443 — Galen Wright-Watson — 2012-07-18T21:40:05+00:00

URL: https://externals.io/message/61394#61443 · In reply to: #61430

On Wed, Jul 18, 2012 at 12:21 PM, Galen Wright-Watson <ww.galen@gmail.com>wrote:

>
>
> On Wed, Jul 18, 2012 at 7:20 AM, Anthony Ferrara <ircmaxell@gmail.com>wrote:
>
> > […]
>
> It changes the semantics. If the variable is set to a falsey value and ?:
> uses an implicit isset, the value of the expression will be the falsey
> value.
>
>     $config['width'] = ''
>     $width = $config['width'] ?: 300
>     # $width == ''
>
> If !empty were used instead of isset, you could preserve semantics ($a ?:
> dflt = !empty($a) ? $a : dflt).
>

However, this would break if someone were to use an explicit isset, so ?:
could only use an implicit !empty if the expression isn't an isset
expression (which starts to get messy, grammar-wise).

Looking over the previous discussion, people objected to altering the
behavior of ?: precisely because it currently generates notices, which they
desire.

The following use-cases were put forward as commonly occurring and verbose
enough to desire syntactic sugar:

   1. isset($arr['key']) ? $arr['key'] : dflt
   2. ! empty($arr['key']) ? $arr['key'] : dflt
   3. ! is_null($arr['key']) ? $arr['key'] : dflt (used instead of isset
   version; both wouldn't appear in same code base)
   4. $arr['key'] = isset($arr['key']) ? $arr['key'] : dflt
   5. isset($arr['key']) ? strtoupper($arr['key']) : dflt

The following new operators were suggested:

   1. new ternary based on isset (e.g. "$a ?? strtoupper($a) : 'DFLT'" with
   implicit isset)
   2. new shortcut ternary based on isset
   3. new shortcut ternary based on !empty (objection: not as useful as
   isset, since !empty is equivalent to !! but with notice suppression)
   4. new shortcut ternary based on !== null or ! is_null
   5. new shortcut ternary that only works on arrays and is based
   on array_key_exists
   6. indexing operator that suppress undefined index notices
   7. variable access that suppresses undefined variable notices
   8. assign-if-not-set operator  (like ||= in Javascript)

Some objections to the above:

   1. (new ternary) ?
   2. (isset) Some developers always set variables and never want undefined
   notice suppression (the "never-unset" style), which isset will do. However,
   this isn't as common a style.
   3. (!empty) Not as useful as isset, since !empty is equivalent to !! but
   with notice suppression. Also, !empty($a)?$a:dflt isn't used as much as
   isset($a)?$a:dflt.
   4. (!== null / ! is_null) Not as useful as isset, since it doesn't
   suppress notices, so isn't a replacement for the isset($a)?$a:dflt pattern.
   However, it can be used in combination with 6 for the isset-based ternary
   for arrays (e.g. "$arr?['key'] ?: 'dflt'").
   5. (array_key_exists) Conceptually, anything unset has a null value, and
   should thus be equivalent in value to something set to NULL.
   array_key_exists distinguishes between unset and set to NULL, which
   won't always match how some want to use the shortcut ternary. Thus, not as
   useful as is_null.
   6. (indexing w/o notices) ?
   7. (variable access) Probably do more harm than good. It's easy to
   ensure a variable is set.
   8. (assign-if-not-set) For arrays, there's the alternative:

       $arr += Array('key' => 'value');

   This can also be used for a "never-unset" style to set defaults for an
   array, which goes with the "! is_null($a) ? $a : dflt" pattern.

Various syntax proposals:

   1. "$a ?? $b : dflt"  as a ternary, with shortcutting behavior.
   2. "$a ?? dflt" as a shortcut ternary
   3. "$a ?! dflt" as a shortcut ternary based on !empty (could be added
   along with "??"; objection is that it could ambiguate PHP's syntax,
   conflicting with the not operator)
   4. "$a $: dflt"  as a shortcut ternary
   5. "$arr?['key']" to suppress undefined index notices
   6. "$arr@['key']" to suppress undefined index notices
   7. "$?var" to suppress undefined variable notices
   8. "$a ??= dflt" as an assign-if-not-set operator (goes along with "??")
   9. "$a !?= dflt" as an assign-if-not-set operator ("!" suggests not-set)
   10. "$a $:= dflt" as an assign-if-not-set operator (goes along with "$:")


  ?? / isset vs ?? / is_null

Of the various proposals, "??" (with semantics of "isset($a) ? $a : dflt")
already has a precedence: in C# as the null-coalescing operator. While PHP
doesn't have non-nullable types (hence "??" isn't a necessity), using ?? is
perhaps the least surprising option, and (including "??=") would cover
use-cases 1 and 4. On the other hand, PHP's "??" wouldn't be the same as
C#, since C# requires that variables be declared. Arguably, having "??"
equivalent to "!is_null($a) ? $a : dflt" is closer to C# semantics. Also,
use-cases 2 and 3 would be left out, whereas operator proposals 4 (?? /
is_null), 6 (?[]) and 8 (??= / is_null) together cover use-cases 1, 3 and
4. Back on the first hand, use-cases 2 and 3 are less common and this is
(after all) merely syntactic sugar, which should be targeting the common
cases.

  ??: vs ??

The ternary "??:" (whether based on isset or is_null) can also cover
use-case 5, but isn't so good for case 4 ("??:=" would be ugly). One one
hand, the short-cut "??:" may be surprising to developers familiar with
C#'s "??:". On the other, PHP ain't C#, and documentation can cover "??:".
Besides, "??" isn't the only null-coalescing operator out there, so why
should C# be given special consideration? Less rhetorically, would
supporting both "??" and "??:", with "$a ??: dflt" equivalent to "$a ?? dflt",
be undesirable?

Personally, I support syntaxes 8. ??= with either 1. ??: / isset or
(1. ??:/ is_null and 5.
?[]).

---

## #61585 — Matthew Weier O'Phinney — 2012-07-20T22:27:40+00:00

URL: https://externals.io/message/61394#61585 · In reply to: #61443

Top-posting, as not sure where to snip. :)

I think either "??" "??:" as an operator makes sense, and would be
readable and easy to learn, and resolve any BC concerns people have. I'd
love to see this in, as the current behavior is basically useless for me
I don't think I've once had code where I could successfully use it
without worrying about the E_NOTICE, which then forces me to use the
longhand form. Having a version that does an implicit "isset" would be
tremendously useful.


> --0016e6d64661f7e32504c521836f
> Content-Type: text/plain; charset=ISO-8859-1
>
> On Wed, Jul 18, 2012 at 12:21 PM, Galen Wright-Watson <ww.galen@gmail.com>wrote:
>
> > […]
>
> However, this would break if someone were to use an explicit isset, so ?:
> could only use an implicit !empty if the expression isn't an isset
> expression (which starts to get messy, grammar-wise).
>
> Looking over the previous discussion, people objected to altering the
> behavior of ?: precisely because it currently generates notices, which they
> desire.
>
> The following use-cases were put forward as commonly occurring and verbose
> enough to desire syntactic sugar:
>
>    1. isset($arr['key']) ? $arr['key'] : dflt
>    2. ! empty($arr['key']) ? $arr['key'] : dflt
>    3. ! is_null($arr['key']) ? $arr['key'] : dflt (used instead of isset
>    version; both wouldn't appear in same code base)
>    4. $arr['key'] = isset($arr['key']) ? $arr['key'] : dflt
>    5. isset($arr['key']) ? strtoupper($arr['key']) : dflt
>
> The following new operators were suggested:
>
>    1. new ternary based on isset (e.g. "$a ?? strtoupper($a) : 'DFLT'" with
>    implicit isset)
>    2. new shortcut ternary based on isset
>    3. new shortcut ternary based on !empty (objection: not as useful as
>    isset, since !empty is equivalent to !! but with notice suppression)
>    4. new shortcut ternary based on !== null or ! is_null
>    5. new shortcut ternary that only works on arrays and is based
>    on array_key_exists
>    6. indexing operator that suppress undefined index notices
>    7. variable access that suppresses undefined variable notices
>    8. assign-if-not-set operator  (like ||= in Javascript)
>
> Some objections to the above:
>
>    1. (new ternary) ?
>    2. (isset) Some developers always set variables and never want undefined
>    notice suppression (the "never-unset" style), which isset will do. However,
>    this isn't as common a style.
>    3. (!empty) Not as useful as isset, since !empty is equivalent to !! but
>    with notice suppression. Also, !empty($a)?$a:dflt isn't used as much as
>    isset($a)?$a:dflt.
>    4. (!== null / ! is_null) Not as useful as isset, since it doesn't
>    suppress notices, so isn't a replacement for the isset($a)?$a:dflt pattern.
>    However, it can be used in combination with 6 for the isset-based ternary
>    for arrays (e.g. "$arr?['key'] ?: 'dflt'").
>    5. (array_key_exists) Conceptually, anything unset has a null value, and
>    should thus be equivalent in value to something set to NULL.
>    array_key_exists distinguishes between unset and set to NULL, which
>    won't always match how some want to use the shortcut ternary. Thus, not as
>    useful as is_null.
>    6. (indexing w/o notices) ?
>    7. (variable access) Probably do more harm than good. It's easy to
>    ensure a variable is set.
>    8. (assign-if-not-set) For arrays, there's the alternative:
>
>        $arr += Array('key' => 'value');
>
>    This can also be used for a "never-unset" style to set defaults for an
>    array, which goes with the "! is_null($a) ? $a : dflt" pattern.
>
> Various syntax proposals:
>
>    1. "$a ?? $b : dflt"  as a ternary, with shortcutting behavior.
>    2. "$a ?? dflt" as a shortcut ternary
>    3. "$a ?! dflt" as a shortcut ternary based on !empty (could be added
>    along with "??"; objection is that it could ambiguate PHP's syntax,
>    conflicting with the not operator)
>    4. "$a $: dflt"  as a shortcut ternary
>    5. "$arr?['key']" to suppress undefined index notices
>    6. "$arr@['key']" to suppress undefined index notices
>    7. "$?var" to suppress undefined variable notices
>    8. "$a ??= dflt" as an assign-if-not-set operator (goes along with "??")
>    9. "$a !?= dflt" as an assign-if-not-set operator ("!" suggests not-set)
>    10. "$a $:= dflt" as an assign-if-not-set operator (goes along with "$:")
>
>
>   ?? / isset vs ?? / is_null
>
> Of the various proposals, "??" (with semantics of "isset($a) ? $a : dflt")
> already has a precedence: in C# as the null-coalescing operator. While PHP
> doesn't have non-nullable types (hence "??" isn't a necessity), using ?? is
> perhaps the least surprising option, and (including "??=") would cover
> use-cases 1 and 4. On the other hand, PHP's "??" wouldn't be the same as
> C#, since C# requires that variables be declared. Arguably, having "??"
> equivalent to "!is_null($a) ? $a : dflt" is closer to C# semantics. Also,
> use-cases 2 and 3 would be left out, whereas operator proposals 4 (?? /
> is_null), 6 (?[]) and 8 (??= / is_null) together cover use-cases 1, 3 and
> 4. Back on the first hand, use-cases 2 and 3 are less common and this is
> (after all) merely syntactic sugar, which should be targeting the common
> cases.
>
>   ??: vs ??
>
> The ternary "??:" (whether based on isset or is_null) can also cover
> use-case 5, but isn't so good for case 4 ("??:=" would be ugly). One one
> hand, the short-cut "??:" may be surprising to developers familiar with
> C#'s "??:". On the other, PHP ain't C#, and documentation can cover "??:".
> Besides, "??" isn't the only null-coalescing operator out there, so why
> should C# be given special consideration? Less rhetorically, would
> supporting both "??" and "??:", with "$a ??: dflt" equivalent to "$a ?? dflt",
> be undesirable?
>
> Personally, I support syntaxes 8. ??= with either 1. ??: / isset or
> (1. ??:/ is_null and 5.
> ?[]).
>
> --0016e6d64661f7e32504c521836f--


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

---

## #61593 — Stas Malyshev — 2012-07-20T23:10:15+00:00

URL: https://externals.io/message/61394#61593 · In reply to: #61585

Hi!

> Top-posting, as not sure where to snip. :)
> 
> I think either "??" "??:" as an operator makes sense, and would be
> readable and easy to learn, and resolve any BC concerns people have. I'd
> love to see this in, as the current behavior is basically useless for me
> I don't think I've once had code where I could successfully use it
> without worrying about the E_NOTICE, which then forces me to use the
> longhand form. Having a version that does an implicit "isset" would be
> tremendously useful.

I think we've painted ourselves into a corner somewhat here, because we
have the following things clashing:
1. Producing an error when accessing non-existing var/element.
2. Unability to temporarily disable 1 since @ both is regarded as
"unclean" and does not actually disable the error generation, only makes
it not printed out.
3. Obvious need to express common pattern "take it if it exists, assume
null if it does not".

Note that the case in 3 is not limited to ?: in any way, you as
frequently encounter it in any context where you can encounter a
variable. We can get back to ?: if we extend 3 with "take it if it
exists, assume this other value if it does not" - but we don't have to,
as the use case is completely dominated by "null" pattern, it is very
rare that you need any other default than null and type conversions of
null like ''/false/0.

I'd be very happy if we could have something like @$var['foo'] just work
by not generating any errors, but if not then probably having some
syntax saying "this variable or null, no notices" will be good - if say
it's $?foo then we could easily add defaults by doing $?foo ?: 'bar'.
Making @$var magically work though would have an advantage of being
instantly backwards compatible.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #61635 — Alex Aulbach — 2012-07-23T03:12:19+00:00

URL: https://externals.io/message/61394#61635 · In reply to: #61394

Do we really need that as operator? Why not using new functions for
special cases.
Don't see much difference between

$a = $b ?: $c;

and (for example I used "i" for "if")

$a = _i($b, $c);

Just a manner of getting accustomed to it.

A little bit more thinking: This could be implemented directly into
any program/project, so it is a manner of how to use PHP and not of
why it isn't added to the language.

PS: Would it be possible to implement functions like ":?()" or "!?()"
? Currently this is not allowed by syntax.


2012/7/18 Rafael Dohms <listas@rafaeldohms.com.br>:
> $width = $config['width'] ?: 300;
>
> The only reason for this to not work is: it throws a notice if the array
> key is not there (which is the case we are covering anyway)
>
> This is basically because the ternary operator does not do a internal
> implicit isset, only an empty.
>
> Does this seem like a possible improvement we can work on? Anyone
> interested in championing the change?

-- 
Alex Aulbach

---

## #61636 — Yahav Gindi Bar — 2012-07-23T03:23:52+00:00

URL: https://externals.io/message/61394#61636 · In reply to: #61635

On Mon, Jul 23, 2012 at 6:12 AM, Alex Aulbach <alex.aulbach@gmail.com>wrote:

> Do we really need that as operator? Why not using new functions for
> special cases.
> Don't see much difference between
>
> $a = $b ?: $c;
>
> and (for example I used "i" for "if")
>
> $a = _i($b, $c);
>
> Just a manner of getting accustomed to it.
>
> A little bit more thinking: This could be implemented directly into
> any program/project, so it is a manner of how to use PHP and not of
> why it isn't added to the language.
>
> PS: Would it be possible to implement functions like ":?()" or "!?()"
> ? Currently this is not allowed by syntax.
>
>
> 2012/7/18 Rafael Dohms <listas@rafaeldohms.com.br>:
> > […]
>
> --
> Alex Aulbach
>
> --
> 
> 
>
> I do think that such operator will be great.
I think that you can compare the situation to the short if syntax ($a > $b
? $c : $d) - you could use a function too that'll do the same thing, but
the syntax is very useful, readable and great.

---

## #61638 — Sanford Whiteman — 2012-07-23T04:08:01+00:00

URL: https://externals.io/message/61394#61638 · In reply to: #61636

> I think that you can compare the situation to the short if syntax ($a > $b
> ? $c : $d) 

Not sure I understand... that *is* the situation under discussion,
no?

$a > $b ? ...

and

$a ? ...

both use the ternary operator.

You do raise (maybe on purpose, not totally clear what you were
getting at) the question of whether a more complex (expr1) in one of
these theoretical ternarys w/implicit isset, however it is
implemented, would apply the isset to _any_ variable in (expr1)? That
is, if $a or $b do not exist, does

$a > $b ?? ...

return an error? What if both do not exist?

I think the conclusion (as reached by other people) is that the
operator needs to apply to each individual variable, not to a
multi-step deal like the ternary where there are more cases to
consider.

-- S.

---

## #61639 — Alex Aulbach — 2012-07-23T04:19:48+00:00

URL: https://externals.io/message/61394#61639 · In reply to: #61638

2012/7/23 Sanford Whiteman <swhitemanlistens-software@cypressintegrated.com>:
> > […]
>
> Not sure I understand... that *is* the situation under discussion,
> no?

Use functions. Above case for example:

_greater($a, $b, $c, $d)

where

function _greater($a, $b, $c, $d)
{
    if ($a > $b) {
        return $c;
    }
    return $d;
}

My suggestion just is: At any point everybody needs one more operator
for "his stuff". But that's why functions exists.


-- 
Alex Aulbach

---

## #61640 — Sanford Whiteman — 2012-07-23T05:31:24+00:00

URL: https://externals.io/message/61394#61640 · In reply to: #61639

> Use functions. 

I understood your post; I was replying to Yahav.

Anyway, I don't agree with you that (built-in) functions are all we
can add because there'll be too much debate. Other languages still
consider adding operators over time and/or allow overloading. Getting
functions added to the language is far from easy anyway. And IMO there
are waaaaaay too many places where something bound closely to the
variable like $?a would be instantly useful and portable; adding
functions for each of these would be impossible.

-- S.

---

## #61641 — Rafael Dohms — 2012-07-23T07:43:36+00:00

URL: https://externals.io/message/61394#61641 · In reply to: #61639

On Mon, Jul 23, 2012 at 6:19 AM, Alex Aulbach <alex.aulbach@gmail.com>wrote:

> 2012/7/23 Sanford Whiteman <
> swhitemanlistens-software@cypressintegrated.com>:
> > […]
> $b
> > […]
>
> Use functions. Above case for example:
>
> ...
> My suggestion just is: At any point everybody needs one more operator
> for "his stuff". But that's why functions exists.
>
>
This is not about "his stuff", this is about the general userland
expectation of what a ternary operator will do with a $array[key]  where it
is not set.
This is a valid use case in every app and as we saw in lots of frameworks.

As for functions, i do not like the idea of having functions around for
this kind of operation, it will bring about the return of "utils.php" and i
don't think that's worth.
So while i agree not everything needs a core implementation, this does not
fall under that case.


>
> --
> Alex Aulbach
>
> --
> 
> 
>
>


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

---

## #61667 — Galen Wright-Watson — 2012-07-24T10:24:03+00:00

URL: https://externals.io/message/61394#61667 · In reply to: #61638

On Sun, Jul 22, 2012 at 9:08 PM, Sanford Whiteman <
swhitemanlistens-software@cypressintegrated.com> wrote:

> [...]
> You do raise (maybe on purpose, not totally clear what you were
> getting at) the question of whether a more complex (expr1) in one of
> these theoretical ternarys w/implicit isset, however it is
> implemented, would apply the isset to _any_ variable in (expr1)? That
> is, if $a or $b do not exist, does
>
> $a > $b ?? ...
>
> return an error? What if both do not exist?


My feeling is that either more complex expressions for operators with an
implicit "isset" or "!empty" shouldn't work, or that they should cause
notices. It's a moot point for null-coalescing operators. Since the
proposal is to deal with specific, common usage patterns, it should stay
focused on those patterns unless during development it's revealed that a
more general case is as easy or easier to implement.

---

## #61668 — Galen Wright-Watson — 2012-07-24T10:24:24+00:00

URL: https://externals.io/message/61394#61668

On Sun, Jul 22, 2012 at 8:12 PM, Alex Aulbach <alex.aulbach@gmail.com>wrote:

> Do we really need that as operator? Why not using new functions for
> special cases.
>

There isn't a need in the sense that such an operator makes things possible
that otherwise aren't possible. There is a need in that there are common
use cases for the ternary operator that are more verbose than they need to
be, and such operators would reduce the cases to their shortest expression.

Rafael's suggestion follows from the principle (which, for lack of a name,
I'd call the Huffman Principle) that (1) common expressions should be
succinct, even at (2) the expense of increasing verbosity for less common
expressions. The suggestion also betrays the BC principle that new versions
of the language should be backwards compatible with others that have the
same major version. Later suggestions are both BC compatible and aim to
improve expressiveness without sacrificing uncommon cases (part 1 of
Huffman without 2, which you could call the Idiom Principle).

One other applicable principle is that common usages appearing across the
breadth of programs in the language should have language or official
library support (core extensions, as opposed to PECL). (Hopefully, my
rendition of this principle is accurate, precise and makes sense.) Note
that common usages that appear only in programs targeting some narrow
subdomain (such as stock trading or medical billing) are excluded from the
principle. Since PHP's domain is web development, anything that commonly
crops up in same is a candidate.

I've yet to identify other competing principles behind some of the
alternative suggestions, but would love to hear some that might help settle
which approach should be implemented (if any).

Don't see much difference between
>
> $a = $b ?: $c;
>
> and (for example I used "i" for "if")
>
> $a = _i($b, $c);


When $b is defined, there isn't much appreciable difference. However, this
behavior already exists, so there isn't much to debate. In the cases under
discussion, a userland function can't suppress undefined variable & index
notices, so it isn't a viable substitution.

PS: Would it be possible to implement functions like ":?()" or "!?()"
> ? Currently this is not allowed by syntax.


This could lead to ambiguity in the grammar:

    /* call function ~-, , or "~ ( - 1)"?*/
    ~-(1);

---

## #61694 — Alex Aulbach — 2012-07-24T16:18:06+00:00

URL: https://externals.io/message/61394#61694

2012/7/24 Galen Wright-Watson <ww.galen@gmail.com>:
> > […]
>
>
> When $b is defined, there isn't much appreciable difference. However, this
> behavior already exists, so there isn't much to debate. In the cases under
> discussion, a userland function can't suppress undefined variable & index
> notices, so it isn't a viable substitution.

Hm, you're right. I normaly don't do such ugly things. :)

Hum. This behaviour is needed in very special contexts. In my eyes
only when printing out/filling up the templates etc. Under normal
circumstances I think, you should program without too much operators,
because a deflation of operators leads to - hm - deflation of the
language. Thats the same, as if everybody can create new words: after
a short time, nobody can understand anybody.

Hmmmm. But we can make this to a principle in this very, very closed context.

So: What about if we can create new operators inside PHP with PHP? I
think not more than 36 operators are needed at any time in a project.
So we can do this:

set_operator_handler('i', function ($b, $c) {
        if (empty($b)) return $b;
        return $b;
}, OPERATOR_HANDLE_UNSET_WITHOUT_WARNINGS)

then we can do this:

$a = $a ?i: $b;

This should help for this case and could be a great things for those
very special cases, when you need the same operation over and over.

Comments
----------------

Context: I think those operators should be global.

Security: Hm. Could operators be overwritten? How to test, if an
operator already exists? I think it should work like including a file.
E. g. set_operator_handler_once() should be possible, so that a second
call isn't executed.

Other things: I don't like the first operator (the operator-name). Any
goof idea?


-- 
Alex Aulbach

---

## #61695 — Yahav Gindi Bar — 2012-07-24T16:25:56+00:00

URL: https://externals.io/message/61394#61695 · In reply to: #61694

> 2012/7/24 Galen Wright-Watson <ww.galen@gmail.com>:
> > […]
> 
> Hm, you're right. I normaly don't do such ugly things. :)
> 
> Hum. This behaviour is needed in very special contexts. In my eyes
> only when printing out/filling up the templates etc. Under normal
> circumstances I think, you should program without too much operators,
> because a deflation of operators leads to - hm - deflation of the
> language. Thats the same, as if everybody can create new words: after
> a short time, nobody can understand anybody.
> 
> Hmmmm. But we can make this to a principle in this very, very closed context.
> 
> So: What about if we can create new operators inside PHP with PHP? I
> think not more than 36 operators are needed at any time in a project.
> So we can do this:
> 
> set_operator_handler('i', function ($b, $c) {
>        if (empty($b)) return $b;
>        return $b;
> }, OPERATOR_HANDLE_UNSET_WITHOUT_WARNINGS)
> 
> then we can do this:
> 
> $a = $a ?i: $b;
> 
> This should help for this case and could be a great things for those
> very special cases, when you need the same operation over and over.
> 
> Comments
> ----------------
> 
> Context: I think those operators should be global.
> 
> Security: Hm. Could operators be overwritten? How to test, if an
> operator already exists? I think it should work like including a file.
> E. g. set_operator_handler_once() should be possible, so that a second
> call isn't executed.
> 
> Other things: I don't like the first operator (the operator-name). Any
> goof idea?
> 
> 
> -- 
> Alex Aulbach
> 
> -- 
> 
> 
> 

I don't think global operators is good idea since it can make a script very complex and you'll have to learn many operators in case the one who wrote it decided to make it "operator driven"
However, if we're talking about operators, I do think that adding operator override option (for the regular operators, such as +, -, * etc.) will be great for OOP - but that's a different topic.

---

## #61698 — Alex Aulbach — 2012-07-24T17:15:35+00:00

URL: https://externals.io/message/61394#61698 · In reply to: #61695

2012/7/24 Yahav Gindi Bar <g.b.yahav@gmail.com>:
> I don't think global operators is good idea since it can make a script very complex and you'll have to learn many operators in case the one who wrote it decided to make it "operator driven"

On the other hand: If those operators aren't global, then they are
local. I wouldn't like that much more, because inside "your project"
you will then never know, if and how an operator is currently working.
Much more confusion.

But I wouldn't like to see this operator-stuff using in a "normal"
context, in "normal" PHP-scripts. (What's normal?)

I see those operators in a very limited context, e.g. when you create
output (use PHP as template-engine), then they could be extremly
helpful. Always and alyways repeating things, which can't be made
shorter. For example checking the rights of a user:

set_operator_handler('r', function ($user, $current) {
    ....
    if (!$userrRights->userHasRights($username, $current)) {
         throw userRightsException(....)
    }
}

and in the code:

try {
     $user ?r: $current;
} catch
....

Ugly? Yes!!! Very! But that's wanted, because - as said - in very
special context. [But really? You can read the code as: "Has the user
the rights for current?"]

In the end this is a design-decision. I wouldn't recomend this for the
normal work (as shown above) and I think the said should be part of
the documentation - if it is really implemented. But I think in some
very special contexts this could be really helpful.


> However, if we're talking about operators, I do think that adding operator override option (for the regular operators, such as +, -, * etc.) will be great for OOP - but that's a different topic.

Existing operators shouldn't be changeable. My suggestion is the
"PHP-way" of operator driven development for a very special problem,
which is making very repeating but complex things very short, nothing
else. :)

Or in other words: In detail it's great, but in general it's a very
bad idea. :) That's just wanted and if you think you must use it, then
you should have a good reason.

-- 
Alex Aulbach

---

## #61710 — Yahav Gindi Bar — 2012-07-24T17:50:09+00:00

URL: https://externals.io/message/61394#61710 · In reply to: #61698

> 2012/7/24 Yahav Gindi Bar <g.b.yahav@gmail.com>:
> > […]
> 
> On the other hand: If those operators aren't global, then they are
> local. I wouldn't like that much more, because inside "your project"
> you will then never know, if and how an operator is currently working.
> Much more confusion.
> 
> But I wouldn't like to see this operator-stuff using in a "normal"
> context, in "normal" PHP-scripts. (What's normal?)
> 
> I see those operators in a very limited context, e.g. when you create
> output (use PHP as template-engine), then they could be extremly
> helpful. Always and alyways repeating things, which can't be made
> shorter. For example checking the rights of a user:
> 
> set_operator_handler('r', function ($user, $current) {
>    ....
>    if (!$userrRights->userHasRights($username, $current)) {
>         throw userRightsException(....)
>    }
> }
> 
> and in the code:
> 
> try {
>     $user ?r: $current;
> } catch
> ....
> 
> Ugly? Yes!!! Very! But that's wanted, because - as said - in very
> special context. [But really? You can read the code as: "Has the user
> the rights for current?"]
> 
> In the end this is a design-decision. I wouldn't recomend this for the
> normal work (as shown above) and I think the said should be part of
> the documentation - if it is really implemented. But I think in some
> very special contexts this could be really helpful.
> 


Yeah, that's a design decision, but its important because that's one of the PHP greatest things - the code is very nice and readable, and it's kind of sad to ruin it...

I didn't thought about template engines - I agree, it'll be great there, but does a language syntax need to be defined only for a specific cases like template engine?

> 
> > […]
> 
> Existing operators shouldn't be changeable. My suggestion is the
> "PHP-way" of operator driven development for a very special problem,
> which is making very repeating but complex things very short, nothing
> else. :)
> 
> Or in other words: In detail it's great, but in general it's a very
> bad idea. :) That's just wanted and if you think you must use it, then
> you should have a good reason.
> 
> -- 
> Alex Aulbach


If the programmers will follow your guidelines and use this operators only for some unique and rare cases - I strongly support that idea, but I'm afraid from programmers who'll make their program full of operators which makes it unreadable by other programers...

I think that operators overriding should be implemented in a class scope (only for object with object interaction, such as (merge operation): $mergedMember = $member1 + $member2; or for roles permission concat - $memberRule = $adminRule - $editorRule)
But that's a different topic from the suggested feature...

---

## #61711 — Sanford Whiteman — 2012-07-24T17:54:32+00:00

URL: https://externals.io/message/61394#61711 · In reply to: #61667

> My feeling is that either more complex expressions for operators with an
> implicit "isset" or "!empty" shouldn't work, or that they should cause
> notices. 

That's exactly why I think we're going in the wrong direction by
speaking of an "alternate ternary" operator.

You're saying the basic ternary is (expr1) ? (expr2) : (expr3)

But the only notice-free alternate is (var) ?? (expr2) : (expr3)

This alternate is just going to cause confusion as it has a different,
more limited signature.

-- S.

---

## #61716 — Alex Aulbach — 2012-07-24T18:09:13+00:00

URL: https://externals.io/message/61394#61716 · In reply to: #61710

2012/7/24 Yahav Gindi Bar <g.b.yahav@gmail.com>:
> Yeah, that's a design decision, but its important because that's one of the PHP greatest things - the code is very nice and readable, and it's kind of sad to ruin it...
>
> I didn't thought about template engines - I agree, it'll be great there, but does a language syntax need to be defined only for a specific cases like template engine?

It's one of the best things of PHP and the reason, why it was invented.

> If the programmers will follow your guidelines and use this operators only for some unique and rare cases - I strongly support that idea, but I'm afraid from programmers who'll make their program full of operators which makes it unreadable by other programers...

Hhummm, every programming language could be written unreadable. Even
PHP. I can say that per sure. :)

> I think that operators overriding should be implemented in a class scope (only for object with object interaction, such as (merge operation): $mergedMember = $member1 + $member2; or for roles permission concat - $memberRule = $adminRule - $editorRule)
> But that's a different topic from the suggested feature...

Which is a much better idea in general. My suggestion was only for a
very special context and should be easier to implement.

I currently think, this discussion needs more time, because I begin to
forget, for what this is really needed. :)

I suggest to (re)think about the real usage-cases...


-- 
Alex Aulbach

---

## #61929 — Christoph Hochstrasser — 2012-08-01T17:50:14+00:00

URL: https://externals.io/message/61394#61929 · In reply to: #61593

Hi, 
> I'd be very happy if we could have something like @$var['foo'] just work
> by not generating any errors, but if not then probably having some
> syntax saying "this variable or null, no notices" will be good - if say
> it's $?foo then we could easily add defaults by doing $?foo ?: 'bar'.
> Making @$var magically work though would have an advantage of being
> instantly backwards compatible.



I'm lately using @$var["key"] a lot (despite it's slowness) and I like it a lot. It makes
most code a lot more readable. I would be +1 for it, if we can make it fast.

I think most people (me included) want only to avoid the notice for accessing undefined array offsets. What if we just remove the notice for accessing undefined array offsets, because it's the most common use case?

I've looked a bit into other languages (Ruby, Python, Go) and
all of them do not generate an error when an undefined dict/hash/map key is accessed.
-- 
Christoph Hochstrasser
http://twitter.com/hochchristoph | http://christophh.net | https://github.com/CHH



Am Samstag, 21. Juli 2012 um 01:10 schrieb Stas Malyshev:

> Hi!
> 
> > […]
> 
> 
> 
> I think we've painted ourselves into a corner somewhat here, because we
> have the following things clashing:
> 1. Producing an error when accessing non-existing var/element.
> 2. Unability to temporarily disable 1 since @ both is regarded as
> "unclean" and does not actually disable the error generation, only makes
> it not printed out.
> 3. Obvious need to express common pattern "take it if it exists, assume
> null if it does not".
> 
> Note that the case in 3 is not limited to ?: in any way, you as
> frequently encounter it in any context where you can encounter a
> variable. We can get back to ?: if we extend 3 with "take it if it
> exists, assume this other value if it does not" - but we don't have to,
> as the use case is completely dominated by "null" pattern, it is very
> rare that you need any other default than null and type conversions of
> null like ''/false/0.
> 
> 
> -- 
> Stanislav Malyshev, Software Architect
> SugarCRM: http://www.sugarcrm.com/
> (408)454-6900 ext. 227

---

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