Edit on February 19, 2016: This blog post came up on a StackOverflow post today. The code I used in my sort was based on a beta of ColdFusion and will not work in the release or more recent versions. Specifically, my comparator must return 1, 0, or -1, instead of just true and false. See this answer which talks more about it and shows an example of how you can now do sorting on query objects directly.
Back in May I wrote a blog entry talking about how impressed I was with closures in ColdFusion 10. This was thanks to Mark Mandel introducing me to the awesome Sesame project. For the RIACon keynote I decided to share this and other examples.
I began with a simple example of how arraySort was updated to include closure support. Consider the following example.
I've got a simple static array of data I want to sort. I pass it to arraySort and dump the results.
Notice something? The bands that begin with "The" are sorted correctly, but not optimally. Instead, most folks would probably prefer them sorted by the letter after the word The. Using a closure, this becomes simple to fix.
I supplied a new function to arraySort that handles the comparison manually. If it finds that the string begins with "The", it just removes it. This could be a bit more intelligent, but you get the idea. Here's the result:
At the keynote, I talked about Mark's Sesame library, but also UnderScore.cfc by Ross Spivey. As you can probably guess, this is a port of the ultra-cool UnderScore.js library.
It has got quite a few features, but one that I thought was really cool was memoize. Memoize takes a function and creates a cacheable version of it. So given some method X, you can pass it to memoize to get some new function Y, that given input A will automatically cache all future calls with A as an attribute. Perhaps an example will make more sense.
You can see I've got a function that can be a bit slow. Essentially it gets slower as you pass it higher and higher numbers. But when I pass it to memoize, the result, in this case slowX, has automatic caching enabled. The first time I call slowX(4) it will be, well, slow. But the second time I run it will return instantly. My result from this script was:
Time diff after first call: 1602, diff after second call: 0
Finally - another person doing cool stuff with closures is Ben Nadel. He's written a few blog posts on it, but one in particular caught my attention. He wrote a UDF called reReplaceAll. It allows you to take a string, run a regex against it, and then fire a closure against every result. Normally you can't do much with replacements. You can do a bit of logic like upper or lowercasing results, but if you want to do something very complex with a match, you have to manually step through each result and update the string. With his UDF, you can simply do your complex stuff in a simple closure. Check out the example below:
I've taken input text, used a simple regex, and then written a closure that wraps each result in HTML while also reversing the actual match. Very simple and direct to use!