tracker issue : CF-4198933

select a category, or use search below
(searches all categories and all time range)
Title:

Elvis Operator incorrectly treating false values as undefined

| View in Tracker

Status/Resolution/Reason: Needs Review//Investigate

Reporter/Name(from Bugbase): Bryan Henderson / Bryan Henderson ()

Created: 06/21/2017

Components: Language

Versions: 2016

Failure Type: Incorrectly functioning

Found In Build/Fixed In Build: 2016,0,03,301771 /

Priority/Frequency: Normal / All users will encounter

Locale/System: / Win 2012 Server x64

Vote Count: 8

Problem Description:
When a variable is defined, but contains a value that equates to boolean false, the Elvis operator (?:) incorrectly resolves to the expression on the right.

Steps to Reproduce:
{code:java}
local.vals = [0, false, "no", JavaCast("null", "")];
writeDump(local.vals.map(function(val){return arguments.val ?: true;}));
{code}


Actual Result:
array 
1: true 
2: true 
3: true 
4: true 

Expected Result:
array 
1: 0 
2: false 
3: no 
4: true 

Any Workarounds:
none while still using the elvis operator.

Attachments:

Comments:

Hi Bryan, The behavior of Elvis operator was changed as a part of the fix for bug: https://tracker.adobe.com/#/view/CF-4028653 Hence, Elvis operator has been modified to consider binary equivalent and null coalescing both.
Comment by Suchika S.
551 | June 27, 2017 08:12:44 AM GMT
WOW! OK... This is great... you guys have really confused the issue here... The functionality of the Elvis operator, as defined for ColdFusion (and still stated in your docs) at https://helpx.adobe.com/coldfusion/developing-applications/the-cfml-programming-language/elements-of-cfml/elvis-operator.html is no longer available: "The support has been provided in ColdFusion for the Elvis operator (?:). The Elvis operator is primarily used to assign the ‘right default’ for a variable or an expression. In an expression, if the resultant value is ***not defined***, then the object will be assigned to the left most part of the expression otherwise a default value (define at the right most part) will be assigned." This is NOT the same as a binary version of the ternary ?: operator! I see that you have been swayed by public opinion to change the functionality in ColdFusion to be the same as in other languages, HOWEVER; The original functionality of "null coalescing" is still sorely needed, and REQUIRED to maintain functionality available in CF10. If you want to leave the Elvis operator as is to appease the masses (or just the extremely vocal few) that is fine, but you need to restore the null coalescing functionality lost by this change. The new Safe navigation operator (?.) is practically useless without a null coalescing operator to consume its result... the primary objective here is to restore the in-line exception handling that was available in CF 10 with the Elvis operator. Might I suggest implementing the null coalescing operator '??' to restore the functionality that is currently described in your documentation for the Elvis operator. Also, since you have completely change it, you MUST update your documentation for the Elvis Operator.
Comment by Bryan H.
552 | June 27, 2017 03:08:39 PM GMT
sorry... the Elvis operator was not available until CF11... so please set CF10 = CF11 in the previous comment.
Comment by Bryan H.
553 | June 27, 2017 05:08:52 PM GMT
Let me add one more thing... ticket https://tracker.adobe.com/#/view/CF-4028653 explains that the Elvis operator (in other languages, NOT ColdFusion) has nothing to do with nulls/undefined values, so that would still leave the current implementation incorrect as the statement "local.val ?: true" should cause an error if local.val is not defined. As it is currently implemented, the ColdFusion Elvis operator is inconsistent... The statement "local.val ?: true" returns true if local.val is not defined... it returns the contents of local.val if it is defined, but only if its value is not falsey!... if the value is falsey (0, false, "no"), then it returns the "default", not the value of local.val. This inconsistency is what makes the current fix from CF-4028653 unacceptable. Proponents of CF-4028653 were primarily concerned with how CFML relates to other languages that define their "Elvis" operator differently (as can be seen by the blog at http://blog.adamcameron.me/2015/07/cfml-elvis-operator-and-null-coalescing.html mentioned in that ticket). I don't believe that a shortcut binary operator for the shortcut ternary operator (?:) for the if-then-else construct was the intent behind including the Elvis operator in ColdFusion... rather the in-line exception handling/undefined detection originally implemented was what was intended... So the wrong symbol was used (one that developers are used to functioning differently in OTHER languages) for this feature... the answer is not to change the feature, but to rename it so that it is not inconsistent with other languages... but this makes it inconsistent with itself (not backwards compatible with CF11). So this leaves you with a choice... you can be hard nosed about it and tell the proponents of CF-4028653 to get over themselves and that the Elvis operator, as defined in ColdFusion, IS NOT a binary equivalent of the (?:) ternary operator, but is a null coalescing operator and their desire for a binary if-else operator is a new feature request. (Are they, the proponents of CF-4028653, even satisfied with your solution?) OR, you can limp along from now and for who knows how many future versions of ColdFusion with an operator that is inconsistent and still different from all other languages that you seem to be trying to imitate and still not have a true binary equivalent to the if-then-else ternary operator, NOR a null coalescing operator in ColdFusion, because the current Elvis operator implementation is neither ('null/undefined' is not and should not be made equivalent to false.)
Comment by Bryan H.
554 | June 27, 2017 06:00:02 PM GMT
Does it make any difference that CF-4028653 was a CF11 fix and this is a CF2016 problem?
Comment by Bryan H.
555 | June 27, 2017 06:12:59 PM GMT
My ticket (CF-4199440) was closed as my example seems to demonstrate the same problem. Bryan Henderson's comments are spot on. Ultimately, it comes down to not thinking through the original implementation of the Elvis operator in CF 11 and know you have a pissing fight between developers.
Vote by Stephen J.
557 | August 09, 2017 08:47:44 PM GMT
Oh .... and I also suggest ?? as a null coalescing operator.
Comment by Stephen J.
556 | August 09, 2017 09:58:47 PM GMT
The elvis operator is basically useless still in ColdFusion. We tried to start using it in the ColdBox framework in ColdBox 5 but had to give up due to too many bugs and issues like this. The elvis operator was originally widely thought of as a shortened ternary which was not the case and led to some very bad things being requested Elvis in ColdFusion is a null coalescing operator and needs to consistently behave that way. That means it behaves on the existence, or null-ness of variables and doe NOT operate on booleans or boolean conditions.
Comment by Bradley W.
29274 | July 11, 2018 05:02:39 AM GMT