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.
On 2012-07-18, Galen Wright-Watson <ww.ga...@gmail.com> wrote: > --0016e6d64661f7e32504c521836f > Content-Type: text/plain; charset=ISO-8859-1 > > On Wed, Jul 18, 2012 at 12:21 PM, Galen Wright-Watson > <ww.ga...@gmail.com>wrote: > >> >> >> On Wed, Jul 18, 2012 at 7:20 AM, Anthony Ferrara <ircmax...@gmail.com>wrote: >> >>> >>> On Wed, Jul 18, 2012 at 10:15 AM, Rafael Dohms <lis...@rafaeldohms.com.br >>> >wrote: >>> >>> > [...] >>> >>> > >>> > 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? >>> >> >> 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. > ?[]). > > --0016e6d64661f7e32504c521836f-- -- Matthew Weier O'Phinney Project Lead | matt...@zend.com Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php