ColdFusion 10 and Closures: The Sesame Library

Writing my presentation for cf.Objective(), Getting closure on Closures, I found I was writing a few common utility functions for use with Closures to use and show in my talk, and as general utilities for coding.

I wanted to bundle these functions into a project, and put it on Github so that we could all share various utility functions that would be useful now that ColdFusion has got Closures available to us. I went looking for an existing project that was already doing this, but since I couldn't find one, I figured I would start one, and see what happens from there!

The project's name is Sesame (much thanks to Ben Koshy for the name), and currently only has a few functions which can be cfincluded into your code, but they were the ones I found most useful when doing some recent work with Groovy, and wanted to have them on hand when doing similar things in ColdFusion.

Here are a few examples:

From the collections include, the _collect functions allows you collect values from one array or struct, by iterating a closure over the passed in collection, and collecting the results returned from that closure.

For example, if I wanted to get all the names from an array of Employees, I could do the following:


var employees = listEmployees();
var names = _collect(employees, function(employee) { return employee.getName(); } );

This would then give me an array of all the employees name in the list.

My other favourite, is _groupBy(), which gives you an easy way to group an array or struct of items into a structure of items that have been grouped by a value returned from a closure.

For example, I could easily group an array of employees by their salary, like so:


var employees = listEmployees();
var grouped = _groupBy(employees, function(employee)
              {
                 if(employee.getSalary() < 100)
                 { return "Less Than 100"; }
                 else if(employee.getSalary() > 100 && employee.getSalary() < 200)
                 { return "Greater than 100, Less than 200"; }
                 else
                 { return "Greater than 200"; }
              });

From there, I can now get at all the employees that earn less than 100, by referenceing them as grouped["Less Than 100"], and so on.

From the numbers include, I really like the _times() function. Simply put, it executes a closure a certain number of times!

_times(6, function() { writeOutput("Write me 6 times!"); });

Nothing too complicated there, but it can be quite useful.

From the concurrency include, there is a function that was directly inspired by the GPars Groovy library (and awesome concurrency library for Groovy). _eachParrallel() will execute the closure for each item in an array or struct, but execute the closure in its own cfthread implementation, allowing for an easy way to parallel process data. When it is done, it joins all the threads back up again, so there is no need for you to do deal with managing the threads yourself.

For example, summing up each item in an array, each in it's own thread:


var values = [1, 2, 3, 4, 5];
var total = 0;
_eachParallel(values, function(it) { total += it; });

Gives us a total of 15.

If you find this interesting, please feel free to download, use and also contribute. I know there are a million more functions that could yet be implemented, and I've already implemented the automatic documentation generator – so as long as your functions have appropriate hinting, it becomes super easy to regenerate the README.md file! So no hard work there.

I'll also be showing this library off as part of my cf.Objective() talk on Closures – so please pop by if you want to see more about closures in ColdFusion 10, or just about closures in general.

Leave a Comment

Comments

  • Sam Farmer | March 27, 2012

    These look really cool and I think functional programming might start to be making sense for me.

  • Dan Vega | March 27, 2012

    Great stuff Mark, can’t wait to see your presentation at cfObjective!

  • John Allen | March 28, 2012

    Thanks Mark. Not only are these helpful, but inspiring.

  • Salvatore Fusto | September 4, 2012

    Hi Mark,
    i’m trying to understand functional programming, but i’ve some doubts: imho in functional programming fn must be fisrst class ones, so their results will depend only on arguments, and never on external variables, but in your example on _eachparallell() result dependes on an array passed as argument, but even on a variable, total, external to the function.
    what do you think about? what am i missing?
    regards

  • Mark | September 5, 2012

    @Salvatore What I’m showing above is not functional programming.

    It’s just using closures. Closures and functions are used in functional programming, but closures exist also in many object oriented programming languages as well.

  • Salvatore Fusto | September 5, 2012

    Mark, is it possible to subsribe your blog?
    thank you