tracker issue : CF-4204512

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

CF Elvis Operator does not function as defined.

| View in Tracker

Status/Resolution/Reason: Needs Review//BugVerified

Reporter/Name(from Bugbase): Joe G. / ()

Created: 06/13/2019

Components: Language

Versions: 2018

Failure Type: Incorrectly functioning

Found In Build/Fixed In Build: 2016 hf 11 through 2018 current, trycf /

Priority/Frequency: Normal / All users will encounter

Locale/System: English / Linux All

Vote Count: 1

Problem Description:
Definition of Elvis from Adobe documentation
"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"

Steps to Reproduce:
var a = false;

Actual Result:

Expected Result:

Any Workarounds:

See CF-4028563

This was never a bug and never should have been changed.

While I agree with Adam that "null coalesce" and "binary ternary" are not the same thing, that's where the agreement ends.

The problem was not with CF.  The problem is that Adam assumed that CF's implementation of ?: was binary ternary. It wasn't.  It never was.  It never should have been.

Groovy: ?: = binary ternary, but NULL and FALSEY both replace the value
Javascript binary ternary: || because short circuit replaces the values
Kotlin: ?: = NULL coalesce.  As CF was.

You cannot use other languages to drive this decision, because first of all, if you look for the "Elvis" operator online, few people can agree on whether that operator is ?. or ?:

When the language defines an operator it should be for the use of THAT language.  I can see great benefits to a null coalescing operator in Coldfusion, because it removes the need for <cfparam> while ALSO dealing with Nulls, which can be introduced by safe-nav ?.  I can see little to no benefit for a binary ternary... Plain ternary is good enough, and if you actually want a binary ternary mechanism, implement || (which can also be used for logic reasons.

To wit, it is absolutely unacceptable that the documentation says:
"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"

(Note it says ABSOLUTELY NOTHING about whether the value is true or valse)

var a = false;

Returns false, but


Returns "default"

Which means your "bugfix" has violated the specification of the feature and never should have been done.


Comments: has a much better handle on what the operator should do. And to be clear this is NOT a problem with documentation. This is a problem where the documentation AND implementation was correct, never should have been changed... But then was, which means it no longer matches the requirements and the documentation matches the REQUIREMENTS not the implementation.
Comment by Joe G.
30913 | June 13, 2019 03:05:34 PM GMT
Proper old bug reference (without transposed digits)
Comment by Joe G.
30914 | June 13, 2019 03:06:40 PM GMT
Further note that Adam contradicted HIMSELF in the old bug and you still changed the behavior. He calls ?: a null Coalescing Operator (which is how CF defined it) Later He calls ?: a binary ternary. Hence, he's posted two bugs that contradict each other and you chose to implement one that never should have been implemented. (Bugs 3710381 and 4028653)
Comment by Joe G.
30915 | June 13, 2019 03:14:24 PM GMT
-1. Adam correctly corrected himself. CF-4028653 was fixed correctly. Null coalescing needs moved from ?: to ??
Vote by Aaron N.
31156 | August 23, 2019 03:46:03 AM GMT
Hi all, `booleanExpression ?: valueIfFalse` should be the binary equivalent of `booleanExpression ? valueIfTrue : valueIfFalse`. It makes sense that `? valueIfTrue :` can shorten to `?:`. ?? should be introduced for null coalescing. Thanks!, -Aaron
Comment by Aaron N.
31155 | August 23, 2019 03:57:00 AM GMT