Yes, if you ever read my twitter profile, I am a bit old fashioned. I started writing CFML when it was still called DBML loooooong ago. Javascript was still simple, and javascript frameworks were eh… nonexisting? So don’t expect me to explain you everything about closures and lambda expressions. But they are not the same in CFML, that’s what I found out today. The hard way.

Nowadays I try to be more ‘modern’, so I am only writing tag cfml syntax if there is no escape. Cfscript is a lot shorter, and easier to read and write, except for some views in my favorite framework. And the last few years I was writing more and more closures. If we can do that in Javascript it shouldn’t be too hard in CFML. So to demonstrate my closure/lambda expression clash a few words on both, more or less stolen from the Modern CFML book (thank you Ortus!)

A closure is the combination of a function and the lexical environment within which that function was declared.
Remember that functions (UDFs) in CFML are objects, closures are objects as well. So are closures and functions the same? The answer is yes and no. The main difference between a UDF and a closure is that closures have access to their lexical environment in which they are declared. Both functions and closures can be manipulated at runtime and can be passed around to other functions and closures or can be returned from other functions and closures.
A closure can be used in any of the following ways:
– Defined inline without giving a name.
– They can be assigned to a variable, array item, struct, and variable scope.
– It can be returned directly from a function.

So closures can be very handy. I just needed them to try out some fancy new scheduling stuf in Coldbox 6.4 ( more on this in my next post ). Let’s just assume I had to write this

task( "Do Something in MyService" )
  .call( () => getInstance( "MyService").someCall() )
   .every( 1, "minutes" )
   .when( function() {
     return  ( hour(now() < 21 ));

So, the highlighted lines are the closures. In Lucee 5 and ACF 2018 lambda expressions were introduced. Stealing again from the Modern CFML book

Lambda expressions reduce much of the syntax around creating closures. In its simplest form, you can eliminate the function keyword, curly braces and return statement. Lambda expressions implicitly return the results of the expression body.

So how does this look like?

// Using a traditional closure
makeSix = function(){ return 5 + 1; }

// Using a lambda expression
makeSix = () => 5 + 1;

// returns 6
systemOutput( makeSix() );

So using lambda’s you can save a few bytes. Not very interesting but it is shorter and it doesn’t harm. At least that’s what I thought. So I rewrote my task as

task( "Do Something in MyService" )
  .call( () => getInstance( "MyService").someCall() )
   .every( 1, "minutes" )
   .when( ()=>{
     return  ( hour(now() < 21 ));

I could even make is shorter by removing the curly brackets but it’s all just about the arrow syntax here.

So is there any difference? Let’s have a look at

So we tried to find differences between closures and arrow syntax. Boring. At least in ACF >=2018.

So the same results in Lucee. But hey, here a lambda is NOT a closure!

So what was my problem now? I assumed my closure was exactly the same as the arrow syntax I used. I should have known better. I read the documentation for scheduling and saw some closure examples. I decided to create my own arrow functions, but while doing it I was asking myself if I should not just use closures instead of this funky lambda stuff. When testing my code I was realizing the code was not executed. Why? It took a few hours, reading and debugging al this new scheduling code in ColdBox, just to realize my when() closure was only executed when it was indeed a closure. So no execution on Lucee, only on ACF2018. I searched all coldbox code for the IsClosure() function, and there was only one place where it was not OR’ed with the isCustomFunction check.

The bug will be fixed soon, and until then I think my CFML will be a bit less ‘Modern’ .