Fat Arrow Function Support in Lucee 5 and Adobe ColdFusion 2018

Arrow functions have been around in CFML since Lucee 5 and Adobe ColdFusion 2018 (Update 5), respectively. Despite this, I only recently began trying to get comfortable with the syntax. I was surprised to find that, while Lucee added fat arrow support much earlier, Adobe ColdFusion provides more complete support for the syntax.

On the Arrow Function Syntax

Whether you like its succint nature, or find it off-putting, the arrow function syntax is here to stay. I believe it’s worth learning, even if you don’t intend to use it; otherwise, the arrow functions you stumble upon in someone else’s code will be an indecipherable mess of parenthesis and greater than signs.

I don’t intend this post to be a primer on (fat) arrow functions. For that, I’d recommend:

Engine Differences (Lucee 5 vs. Adobe ColdFusion 2018)

As I mentioned at the top, Lucee introduced support for arrow functions in Lucee 5, which was released in November of 2016. It wasn’t until September 2019, with update 5 to ColdFusion 2018, that Adobe also supported the syntax.

Fat Arrow Syntax Supported by Both Engines

The following basic examples, some of which were cribbed and slightly modified from Ben’s blog post above, are supported by both Lucee 5 and ACF 2018.

Basic

greet = ( name ) => {
  return( "Hello, #name#." );
};

writeOutput( greet( "Matthew" ) ); // Hello, Matthew.

Dropping return and curly brackets

// When the only statement is `return`
// we can remove `return` and the surrounding curly brackets
depart = (name) => "Goodbye, #name#.";

writeOutput( depart( "Marcy" ) ); // Goodbye, Marcy.

Without parameters

shrug = () => "¯\_(ツ)_/¯";

writeOutput( shrug() ); // ¯\_(ツ)_/¯

Within iterators

Examples of iterators include the array .map() member function, arrayMap(), and similar.

cuts = [ "julienne", "chiffonade", "dice" ];
upperCuts = cuts.map( 
  ( item, index ) => {
    return item.ucase();
  }
);

writeDump( var='#upperCuts#', abort='true' );
// ["JULIENNE","CHIFFONADE","DICE"]

Syntax Supported only by Adobe ColdFusion 2018

The final three examples work in Adobe ColdFusion 2018, but result in a syntax error in Lucee. I found this a bit disappointing; hopefully this incompatibility/shortcoming is addressed soon.


Update - 06/04/2020: Within a few minutes of my publishing this, John Berquist provided a very insightful comment below, pointing out that the primary root of the incompatibilities I encountered is explained the Lucee issue LDEV-2417 - namely, that fat arrow functions shouldn’t require parentheses around a single parameter.


Without parentheses

// Parentheses are optional when there's only one parameter name
greet = name => "Hello, #name#.";

writeOutput( greet( "Matthew" ) ); // Hello, Matthew.

Without return and curly brackets, within iterators

// Oops. In the comments, John pointed out that this incompatibility doesn't have to do with the arrow function, but rather with how Lucee/ACF differ in their parsing of the semicolon in the function.
cuts = [ "julienne", "chiffonade", "dice" ];
upperCuts = cuts.map( 
  ( item, index ) => item.ucase(); 
);

writeDump( var='#upperCuts#', abort='true' );
// ["JULIENNE","CHIFFONADE","DICE"]

Shorthand, within iterators

cuts = [ "julienne", "chiffonade", "dice" ];
lengths = cuts.map(cut => cut.len());

writeDump( var='#lengths#', abort='true' ); // [8,10,4]

Obviously, there are likely variations and edge cases that I haven’t covered. If you find one, let me know in the comments.

Lucee Issues

There are a number of Lucee tickets related to this. Here’s one, for example: LDEV-2417. Brad Wood also put together a Github repo demonstrating the incompatibilities. So, if this is something that interests you, make it known on those tickets!