Bluemini.comBluemini.com

Sean Corfield

The Blog Is Dead. Long Live The Blog.

posted: 20 Jun 2014

I've become increasingly frustrated with blogging software. I use MangoBlog here. I used BlogCFC before that. I used WordPress before that (a long time ago - but I've worked with it for a few friends more recently). I just don't enjoy using any of it. Back in January, I toyed with the idea of using my Google+ account for blogging but that hasn't really worked out - because I don't much like Google+, even with all its improvements since I last tried using it. So I'm starting a new blog that doesn't need software to publish anything!

I'll keep this site running since there's a lot of legacy material here that is heavily linked but I won't be posting here any more. I'll probably add redirects to the new blog (with a link back here for Google-friendliness). The new blog probably won't have any CFML stuff on it since, well, I don't really do that any more. I'm still committed to maintaining and enhancing FW/1 - Framework One so don't worry about that but my blog is not really the best place for announcements about that: I'll continue to post to the mailing list and Twitter, and I'll probably set up a framework-one.github.io documentation site now that I've seen how seancorfield.github.io is going to work.

Some thoughts on Java 8

posted: 14 Jun 2014

Since I try to keep this blog mostly related to either Clojure or CFML, I've posted my thoughts on Java 8 over on Google Plus. I'm using Google Plus for my more philosophical musings on technology.

Where did they go? A look at (former) CFML blogger

posted: 07 Jun 2014

Back in March 2013, Adam Cameron posted a list of CFML blogs that he follows, asking the community to comment with additional blogs they followed. The comment thread kinda went off in a different direction but it is an interesting discussion nonetheless that would be grist for several blog posts on other topics. A month later, he posted about a new CFML blog and it made me wonder what had happened to a lot of the "old guard" of CFML bloggers. I thought it might make an interesting blog post to take a look at the blogs of a number of formerly very active members of the CFML community and see what they are up to these days.

I started doing the process manually, based on the list of feeds on coldfusionbloggers.org and after a while I just ran out of steam so I put the project aside. Back in January 2014, a conversation with Mark Mandel on IRC spurred me to at least put that ages-old draft into Mango Blog so that I'd see it every time I logged in, thinking it might spur me to go through some more blogs and categorize them. For a while it did, but it was a tedious process, visiting each blog (if it still existed), and figuring out whether they mostly blogged about CFML or something else these days and writing up some notes. There are nearly 700 blogs listed on coldfusionbloggers.org and about half of them had ceased to exist in their original form (some were still blogs, some were even still about CFML, but the old RSS feed had gone away so they weren't contributing to the aggregator). I got tired again.

Then this week I decided to write a little code to automate the review process. Due to vagaries in the format of various RSS and Atom feeds, it took me a while to get a viable "parser" working that could segregate blogs into missing, present but no longer parsable, and valid feeds. In deciding to automate the process, I'd decided to give up on the manual review and annotation: I figured that whatever I write will become outdated and having a blog post full of links to outdated material wouldn't be much value. So instead I created a separate HTML page, auto-generated by code, listing the most recent blog post I could determine on every (former) CFML blog that still exists. Of the 250 or so that weren't directly parsable, some have genuinely gone away, replaced by an HTML placeholder for the domain, some have updated their sites and still have an RSS feed but never updated coldfusionbloggers.org (if you're on that list, head over and let Ray Camden know your updated RSS feed!). And then there's nearly 90 that my code couldn't get a response from. I decided to leave links present to all 680 entries so folks can take a look for themselves, and add comments here about changes (but see my note about letting Ray know about updated RSS URLs!). Note that some of the RSS feeds that were unreachable belong to blogs that clearly do still exist! (e.g., Open BlueDragon's blog still exists, but the RSS feed on coldfusionbloggers.org is for openbd.blog-city.com which is offline).

I can run the code and update that page whenever there are significant changes.

Getting Started

posted: 04 Jun 2014

I've been involved with World Singles for about five years now, about three and a half years as a full-time engineer. The project was a green field rewrite of a dating system the company had evolved over about a decade that, back in 2009, was running on ColdFusion 8 on Windows, and using SQL Server. The new platform soft-launched in late 2011 as we migrated a few small sites across and our full launch - migrating millions of members in the process - was May 2012. At that point we switched from "build" mode to "operations" mode, and today we maintain a large codebase that is a combination of CFML and Clojure, running on Railo 4.2 on Linux, and using MySQL and MongoDB, running partly in our East Coast data center and partly on Amazon.

Like all projects, it's had some ups and downs, but overall it's been great: I love my team, we love working with Clojure, and we have a steady stream of interesting problems to solve, working with a large user base, on a multi-tenant, multi-lingual platform that generates millions of records of data every day. It's a lot of fun. And we all get to work from home.

Sometimes it's very enlightening to look back at the beginning of a project to see how things got set up and how we started down the path that led to where we are today. In this post, I'm going to talk about the first ten tickets we created as we kicked the project off. Eleven if you include ticket "zero".

  • #0 - Choose a bug tracking / ticketing system. We chose Unfuddle. It's clean and simple. It's easy to use. It provides Git (and SVN) hosting. It provides notebooks (wikis), ticketing, time management, customizable "agile" task boards, collaboration with external users, and it's pleasing to the eye. I've never regreted our choice of Unfuddle (even when they did a massive overhaul of the UI and it took us a week or so to get used to the radically new ticket editing workflow!).
  • #1 - Version control. Yes, really, this was our first ticket in Unfuddle. The resolution to this ticket says:
    Selected vcs system (git), created repository in Unfuddle, and provided detailed documentation on why git, how to set it up, how to connect to the repo and how to work with git.
    And the documentation was all there in an Unfuddle notebook for the whole team. A good first step.
  • #2 - Developer image. Once we had version control setup and documented, we needed an easy way for every developer to have a full, self-contained local development environment. We had some developers on Windows, some on OS X, some on Linux, so we created a VMWare image with all the basic development tools, a database, a standardized ColdFusion installation, with Apache properly configured etc. This established a basic working practice for everyone on the team: develop and test everything locally, commit to Git, push to Unfuddle. We could then pull the latest code down to a showcase / QA server for the business team to review, whenever we or they wanted.
  • #3 - Project management system. Although we had bug tracking and wikis, we wanted to nail down how communication would work in practice. We created a project management mailing list for discussion threads. We created a notebook section in Unfuddle for documenting decisions and requirements. We decided to use Basecamp for more free-form evolution of business ideas. We agreed to use tickets in Unfuddle for all actionable work, and we settled on a Scrum-like process for day-to-day development, with short, regular sprints so we could get fast feedback from the business team, and they could easily see what progress we were making.
  • #4 - General project management. Since we had agreed to use Unfuddle for time tracking, we created a ticket against which to track project management hours that didn't fit into any actual work tickets. We used this for the first six months of the project (and logged about 300 hours against it).
  • #5 - Performance planning/tuning. This was mostly a placeholder (and initially focused on how to make a Reactor-based application perform better!). It was superceded by several more specific tickets, six months into the project. But it's one of those things we wanted on the radar early for tracking purposes.
  • #6 - Architectural planning. Like ticket #4, this was a time tracking bucket that we used for the first six months of the project.
  • #7 - Set up Continuous Integration. Yup, even before we got to our first actual coding ticket, as part of the early project setup, we wanted a Continuous Integration server. Whilst we were using ColdFusion for local development (prerelease builds of ACF9, at the time), we chose to use Railo 3.2 for the CI server so that we could ensure our code was cross-platform - we were still evaluating which engine to ultimately go to production with. The resolution of this ticket says:
    Apache / Tomcat / Railo / MySQL / Transparensee / Hudson in place. Automated test run restarts Railo, reloads the DB, reloads Transparensee, cleans the Reactor project, runs all test suites and generates test results.
    We developed an Ant script that stopped and started Railo, tore down and rebuilt the test database, using a canned dataset we created (with 1,000 random users), repopulated the search engine we use and cleaned up generated files, then ran our fledgling MXUnit test suite (and later our fledgling Selenium test suite).
  • #8 - Display About us/trust. This was our first actual code ticket. The company had selected ColdBox, ColdSpring, and Reactor as our basic frameworks (yeah, no ticket for that, it was a choice that essentially predated the project "getting started"). This ticket was to produce a first working skeleton of the application that could actually display dynamically generated pages of content from the database. We created the skeleton of the site navigation and handlers for each section as part of this ticket. The "trust" in the ticket title was about showing that we really could produce basic multilingual content dynamically and show an application architecture that worked for the business.
  • #9 - Implement resource bundles for templates. And this was also an early key requirement: so that we could support Internationalization from day one and perform Localization of each site's content easily.
  • #10 - Display appropriate template for each site. This was our other key requirement: the ability to easily skin each site differently. Like #9, this was an important proof of concept to show we could support multiple sites, in multiple languages, on a single codebase, with easy customization of page layouts, content, and even forms / questions we asked.

So that's how we got started. Bug tracking, version control, local development environment, continuous integration and the key concepts tackled first!

A reasonable question is to ask what has changed in our approach over the five years since. We're still using Unfuddle (in case you're wondering, we're up to ticket 6537 as I write this!), we're still using Git (and still loving it). Our development stack has changed, as has some of our technology.

Over time we all migrated to Macs for development so maintaining the VM image stopped being important: everyone could have the entire development stack locally. We eventually settled on Railo instead of ColdFusion (we're on Railo 4.2 now), and we added MongoDB to MySQL a couple of years ago. We added some Scala code in 2010 to tackle a problematic long-running process (that did a lot of XML transformation and publishing). We added Clojure code in 2011 for a few key processes and then replaced Scala with Clojure and today Clojure is our primary language for all new development, often running inside Railo. We stopped using Reactor (we wrote a data mapper in Clojure that is very close to the "metal" of JDBC). Recently we stopped using MXUnit and replaced it with TestBox. We're slowing changing over from Selenium RC tests to WebDriver (powered by Clojure). We have about 20,000 lines of Clojure now and our CFML code base is holding steady at around 39,000 lines of Model and Controller CFCs and 45,000 lines of View cfm files.

BlogCFC is a TeamCFAdvance project

posted: 28 May 2014

I don't think I've actually blogged about TeamCFAdvance yet. That's very lax of me. TeamCFAdvance is an initiative started by Denard Springle last year to help foster the development of Free Open Source Software (FOSS) in the CFML community. Yes, there's been several attempts at this in the past. I've been involved with a few of them myself. The Open CFML Foundation is one example, focused on promoting awareness of open source solutions that are written in CFML - reaching out beyond our community. But TeamCFAdvance is very pragmatic: it's aimed directly at our developers, to educate and encourage, to ensure that great projects continue to be maintained, even when their maintainers move on.

If you look at the TeamCFAdvance Github repo you'll see a bunch of projects and there is one you will definitely recognize: BlogCFC! Originally created by Ray Camden, and later stewarded by Scott Stroz, BlogCFC is now a TeamCFAdvance project. One of the things you'll note on that page is the (hopefully!) green "build: passing" icon as we now have BlogCFC hooked into Travis-CI - a Continuous Integration system that automatically runs your test suite after every change, testing the project against Railo (4.0, 4.1, 4.2 beta - soon to be "gold") and Adobe ColdFusion (9.0.2 and 10 on Linux - soon to add 11), using TestBox. There's only a placeholder there right now but expect tests to blossom soon...

To see what's possible once we have everything wired up, take a look at what happens with FW/1's Travis-CI setup with automated tests - 115 of them - that are run on five platform combinations. Almost 120 builds have been tested. FW/1, DI/1, and AOP/1 are all automatically tested.

If you're not already involved with TeamCFAdvance but you're interested in FOSS, sign up! Everyone is welcome!

FW/1 2.5 is released!

posted: 26 May 2014

This is a migration release to pave the way for breaking changes in Release 3.0. All examples have been updated to latest best practices and now use cfcscript exclusively. Examples use DI/1 0.5.0 to manage all beans and services (as framework.ioc), and no longer rely on start/end actions or the service() method.

As always, FW/1 can be downloaded from the FW/1 page on RIAForge. Release 2.5 is now the latest stable release of this framework, as it approaches its fifth birthday!

For a full list of all tickets closed in Release 2.5: https://github.com/framework-one/fw1/issues?milestone=14&page=1&state=closed

Migration from 2.2.1

The service() call has been deprecated, as have start/end action items. Global access to rc in Application.cfc has also been deprecated. If you just drop 2.5 into your setup and you rely on these features, you'll get exceptions explaining how to enable these features for backward compatibility, namely add the following to your framework configuration:

enableGlobalRC = true,
suppressServiceQueue = false

The ability to enable the implicit service calls is still present via:

suppressImplicitService = false

but, like the other two options, defaults to disallowing the deprecated feature.

If you enable these deprecated features, you will no longer get exceptions using them, but you will see deprecation warnings in your application server's console log. This is to remind you to update your code in preparation for 3.0 later this year!

Please note that Release 3.0 will completely remove these backward compatibility options - and the associated deprecated features. In addition, org.corfield.framework will move to framework.one in Release 3.0, alongside framework.ioc.

Conferences & Me

posted: 21 May 2014

cf.Objective() is over for another year and the reactions I've seen were all very positive. As a long-time member of the Steering Committee, that makes me very happy. This is the first time I've ever missed cf.Objective(). Yes, I've attended eight of the nine, and I've been a speaker at six of them (I think?). I've also attended as a sponsor (2012, as Railo's "booth babe").

This year also saw Into The Box the day before - a one day conference dedicated to all things *Box, not just ColdBox. That conference also seemed to go well, from what I saw on Twitter, and I'm very interested to learn more about CommandBox, the CLI and package manager they previewed!

Eagle-eyed readers may have noticed posts from me back in November and December indicating that I'd submitted talks to cf.Objective() and Scotch on the Rocks, which had been accepted... and then those posts disappeared. I took the posts down to reduce linkage to them and, to some extent, to head off any questions. I try really hard not to back out of commitments: I had to cancel Scotch on the Rocks back in 2009 because my wife broke her ankle just before the conference and she was laid up in bed for a couple of months and then in a wheelchair for another couple of months.

Over the last few years, I've attended a lot of conferences and most of them have been out of my own pocket and out of my vacation allowance. Over the last few years, my technology focus has shifted. When I joined World Singles full-time in 2010, I came in primarily as a CFML developer, with experience in a number of other languages. At BroadChoice we'd gone to production with Groovy and Flex alongside CFML. At World Singles, we went to production with Scala alongside CFML and then we introduced Clojure. Now we're primarily a Clojure shop: it's our go-to language for all new work and we're slowly replacing CFML code with Clojure code as we touch that CFML code to make enhancements. The benefits of immutable data, pure functions, and composable data transformations - and the ease with which we can operate concurrently - are huge.

That shift has meant that CFML conferences, once core to my work, are now a personal luxury. The once bleeding edge, new technology events that I could justify as an investment in my personal growth have instead become core to my work: MongoDB Days, Clojure/West, The Strange Loop, Lambda Jam, Clojure/conj. Even with an employer as generous as World Singles, I can't get to all of those on the company dime and company time.

I've been very lucky to be able to attend and speak at so many conferences over the last decade, and I've loved attending all those CFML conferences: MXDU, Fusebox, Frameworks, CFUnited, CFinNC, cf.Objective(), Scotch on the Rocks. I have a huge number of friends in the CFML community and that's a big part of what I love about the conferences. The desire to see my friends is a large part of why I've continued to submit talks to CFML conferences.

Unfortunately, as Jay & I reviewed our commitments back in January, both financial and timewise, as we started to prepare our 2013 tax return, it became clear that there was no way I was going to be able to attend Into The Box, cf.Objective(), and Scotch on the Rocks. It led to some very uncomfortable discussions with those conference organizers. I'd already overreached in 2013 and, realistically, I shouldn't have even submitted talks.

In the end, of course, Into The Box and cf.Objective() were both great successes - they are so much more than the sum of their speakers - and Scotch on the Rocks looks absolutely amazing. I wish I could attend! I miss my friends in the CFML community and without the conferences I don't get to hang out with them.

I'm sorry that I caused the conference organizers hassle by submitting talks and then pulling out. As a long-time member of the cf.Objective() Steering Committee I know that flaky speakers are a pain in the ass!

Realistically, all this means that unless you attend The Strange Loop (or a Clojure conference), I'm probably not going to get to hang out with you in the future. That makes me sad for the friends I won't get to see but I hope we all grow...

FW/1 2.5 Release Candidate 2

posted: 17 May 2014

Later than planned, FW/1 2.5 RC2 is finally available for testing! You can download FW/1 2.5 RC2 from Github and it is also the default download from FW/1's page on RIAForge.

You can read the complete list of closed tickets for Release 2.5 for more details on features added (or removed) in this release.

Changes since RC1: trace now has delta column showing time taken (thank Ryan Guill); environment control is now able to affect many more basic configuration items, including tracing; ColdFusion 11 / Railo 4.2 compatibility (string member function workaround); bean factories are fully cleared on a reload (Brian Fitzgerald); all examples updated to remove deprecated features.

DI/1 0.5.0 is included (as framework.ioc), along with the WireBoxAdapter.cfc (also in the framework/ folder), and all the examples that used any sort of bean factory have been updated to use DI/1 instead.

All the examples have been updated to use script-only CFCs, with the exception of userManagerAccessControl which I just couldn't summon up the energy to tackle this morning. It will get converted before 2.5 goes "Gold" since it will dramatically simplify the code (especially the beans!).

Migration from 2.2.1

The service() call has been deprecated, as have start/end action items. Global access to rc in Application.cfc has also been deprecated. If you just drop 2.5 into your setup and you rely on these features, you'll get exceptions explaining how to enable these features for backward compatibility, namely add the following to your framework configuration:

enableGlobalRC = true, suppressServiceQueue = false

The ability to enable the implicit service calls is still present via:

suppressImplicitService = false

but, like the other two options, defaults to disallowing the deprecated feature.

If you enable these deprecated features, you will no longer get exceptions using them, but you will see deprecation warnings in your application server's console log. This is to remind you to update your code in preparation for 3.0 later this year!

Please note that Release 3.0 will completely remove these backward compatibility options - and the associated deprecated features. In addition, org.corfield.framework will move to framework.one in Release 3.0, alongside framework.ioc.

Packt Publishing Buy One, Get One Free Offer Ends

posted: 22 Mar 2014

Those wonderful folks over at Packt Publishing are celebrating their 2000th title release and they are offering all their customers a "Buy One, Get One Free" offer on all e-books right now. The offer runs until March 26th and will be applied automatically at check out - and it is unlimited! Great time to stock up on their titles!

Check out Packt Publishing's Buy One, Get One Free e-book offer!

Insanely Useful Leiningen Plugins

posted: 14 Feb 2014

A very short post, partly as a reminder for my future self. Check out the following Leiningen plugins:

  • lein-ancient - analyzes your project.clj and lets you know which dependencies are out of date.
  • lein-exec - directly execute Clojure code snippets, or write shell scripts in Clojure!
  • lein-try - start a REPL with various dependencies without needing a project. Great for exploring new libraries!
  • Eastwood - a lint tool for Clojure.

FW/1 2.5 Release Candidate 1

posted: 01 Feb 2014

You can download it from the FW/1 Releases page.

This has some minor functionality additions to clean up some RC (request context) access that was identified by a user. Given the compatibility changes being setup by Release 2.5, this was a good opportunity to deprecate direct access to variables.rc inside the framework (possibly inside buildURL(), setupView(), and setupResponse()).

Check the release notes for a link to the closed issues in this release.

The documentation wiki has been updated to match the latest functionality. The UserManager example has been updated to "best practice" for 2.5. The other examples will be updated before 2.5 goes "gold".

Me and Gmail (revisited)

posted: 31 Jan 2014

Six years ago I blogged that I only use my Gmail account for mailing lists and asked people not to sent direct / personal email to my @gmail.com account.

Recently I decided to give Google Plus a second chance. I had stopped using it completely because it seemed to be "Facebook for geeks" and I try really hard to keep my tech life and my "real" life partitioned on the web: Facebook for IRL friends that I share interests with and have at least had dinner with; Twitter for tech chatter and news. Nowadays, many of my Facebook friends are also on G+ (or have migrated from Facebook to G+), and along the way Google enabled G+ for Google Accounts, which is where I've managed my corfield.org email for several years. And, yes, G+ has gotten better. It's still primarily "Facebook for geeks" but there's more interesting content from people I know in real life and I figured it might be a nice avenue for "musings on technology" that don't really belong on my blog (and are too long for Twitter anyway). And as Facebook gets more and more annoying with its filtering, its ads, its auto-play videos, and its somewhat weird privacy settings, maybe G+ will see more and more non-geek users, which in turn will make it more appealing to me...

Now, having two G+ accounts - both corfield.org and gmail.com - is a royal pain in the bejeesus because you get circle notifications on two addresses and you end up having to keep two different browsers open, each logged in via a different account. Google doesn't let you merge accounts. Boo! So I decided to strip G+ from my gmail.com account, and just use my corfield.org Google Account for all my Google needs. That had been working out pretty well so about three weeks ago I decided to effectively shut down my gmail.com account: I started switching all my mailing list subscriptions over to corfield.org and set up rules in Google Mail to push mailing list content to folders so I didn't have to see it in my desktop client (I really like Google Mail on the web for reading mailing lists!).

In that three weeks, according to Google's "Account Activity Report", I've received 5,200 emails from almost 900 contacts, and I've sent just over 300 emails to just over 100 contacts. I'll be interested to see what a full month looks like on corfield.org now that I have disconnected everything from my gmail.com account.

So, six years ago I warned not to send personal / direct email to gmail.com because it might get lost in the flood of mailing lists. Today, if you send any email there, it might as well be /dev/null - I no longer use gmail.com. corfield.org, on the other hand, still remains the best way to contact me!

ClojureBridge - Workshops Coming Soon!

posted: 31 Jan 2014

I've been an advocate of diversity in IT for a long time. I'm very pleased to work in a company that has an above average ratio of female to male employees, as well as very diverse cultural backgrounds amongst our staff. In most tech communities, diversity is pretty low. It's why organizations like RailsBridge and Women Who Code and numerous others exist. The lack of diversity hurts us all because a homogeneous community doesn't have diversity of thought either: diverse teams outperform homogeneous teams.

Back in 2012, I became very bothered by the lack of diversity in the Clojure community - it's a lot less diverse than several other communities I've experienced - and after talking to a few people, I reached out to a former colleague from Macromedia, Sarah Allen - president of RailsBridge, to see what it would take to get something started to address it. I continued talking to people about the idea of ClojureBridge and was thrilled when Bridget Hillyer, Lynn Grogan, Maggie Litton and others took up the torch to make it happen!

I'm even more thrilled to announce that ClojureBridge is a reality: you can sign up on the web site to get involved, you can join the ClojureBridge Workshops mailing list. The first workshop will be in Durham, NC the first weekend of April and the second workshop will be in San Francisco, CA the first weekend of May!

As it says on the ClojureBridge web site:

ClojureBridge aims to increase diversity within the Clojure community by offering free, beginner-friendly workshops for women.

Our students range from those completely new to programming to professional developers who want to learn more about Clojure.

ClojureBridge is inspired by RailsBridge, and closely models the RailsBridge philosophy.

clojure.java.jdbc 0.3.3 released

posted: 31 Jan 2014

clojure.java.jdbc 0.3.3 is a minor bug fix release:

  • JDBC-89 - calling query with a bare SQL string no longer causes an exception (or a crash with some drivers!).
  • JDBC-87 - metadata-result is no longer lazy by default, and accepts :row-fn and :result-set-fn arguments, like query, to manipulate the result set.
  • Key/value pairs in connection string URI are now passed through to the driver as part of the connection parameters - thanks to Phil Hagelberg for that.

CFUI Tags - Just Say No!

posted: 26 Jan 2014

Back in June 2007, I gave a talk at CFUnited about the very exciting, soon-to-be-released "AJAX Integration with ColdFusion 8" features. I am an unabashed server-side guy who is hopeless at front end development so I was very enamored of the (then) new cflayout, cfdiv, cfajaxproxy, data binding, and - I'm now ashamed to admit it - cfpod!

Yes, it's right there on slide 31 of my CFUnited 2007 presentation about the CFUI tags. I even had downloadable demo code that included cfpod!

CFML makes hard stuff easy and for me, back then, UI was hard. But that was nearly seven years ago and much has changed!

I'm still not great at front end stuff, but I can write some JavaScript (even tho' I hate the language) and I can wrestle jQuery into submission when I have to. Heck, only the other day I created a table-based view that dynamically filled in each row asynchronously using raw jQuery and simple server requests!

The truth is, those CFUI tags, they're a terrible thing. They're tied to the product, they don't get upgraded very often, and when they do, they break your existing, working web site! And, really, it's not that hard to do it yourself with any number of relatively easy-to-use JavaScript libraries out there!

Don't take my word for it! Ray Camden wants you to do your user interface the right way and Adam Cameron thinks you're a bloody wanker if you use the CFUI tags! I agree! I was that bloody wanker. I got better! You should get better too!

By the way, if you use Railo, this doesn't apply to you because Railo very sensibly decided not to implement the silly UI tags that appeared in ColdFusion 8. We complained at the time, but they were right. It was for our own good!

Into The Box - spread the love!

posted: 26 Jan 2014

Want to support Into The Box? You can get your Into The Box badges to add to your blog or email!

It's not just about ColdBox...

Into The Box

posted: 16 Jan 2014

The Into The Box conference web site is up and running now: May 13th, 2014, the day before cf.Objective().

Into The Box brings together ten speakers, in two tracks, covering all aspects of the ColdBox-family of products for just $199. If you're using any of those frameworks - or you're just curious about them, this is going to be a great opportunity to really get to know them in depth!

Back in 2009, I gave a talk at cf.Objective() about Behavior-Driven Development - a way to describe the expected behavior of software as executable tests. It's an approach I've always believed in but we've lacked the tools in the CFML world until recently: TestBox provides traditional "xUnit" testing, MXUnit compatibility, and Behavior-Driven Development testing.

I'm very pleased to be speaking at Into The Box about Behavior-Driven Development!

FW/1 2.5 Release Candidate 0

posted: 12 Jan 2014

You can download it from the FW/1 Releases page on Github.

I want to get this out there for folks to experiment with since it contains a fundamental change (regarding services).

FW/1 2.5 is a "release candidate" insofar as it is feature complete, but it is not yet documented, and the changes to the examples are not yet complete.

#151 Tracing changes:

  • frameworkTrace() is now a public method and takes a message and an optional value that will be added to the trace output.
  • disableFrameworkTrace() and enableFrameworkTrace() do what they say on a per-request basis.
  • setupTraceRender() is called at the start of the rendering process so you can intercept rendering.
  • getFrameworkTrace() returns the raw trace data array at the point where it is called: if you want to manage trace rendering or recording yourself, call this method in setupTraceRender() and then call disableFrameworkTrace() to suppress the default rendering.

#207 Service Queue Deprecation - the big one!

  • new setting suppressServiceQueue which defaults to true: when this is true, you can no longer call service() and attempts to use startItem()/endItem() will also fail - see below; if this setting is changed to false, the behavior of FW/1 2.2 is restored, but you will see deprecated messages appearing in the console every time service(), startItem(), or endItem() is called.

#208 WireBoxAdapter:

  • you can now use WireBox as the bean factory with FW/1 and it will autowire services, by name, into controllers: see the new examples/wirebox app for an example of how to do this.

#213 populate() now accepts properties:

  • previously populate() could only inject elements of the request context into a bean; now you can specify a new properties struct argument that will be used instead of the RC struct.

#216 buildCustomURL():

  • this makes it easier to build route-based URLs instead of regular action-based URLs: buildCustomURL( "/product/123" ) will construct a URL with the same sort of prefix that buildURL() would create, followed by the URI argument.

#221 recognition of XSS in default error page:

  • the code now does a minimal bit of URL encoding but admonishes developers to either do better encoding (which may be CFML engine specific!) or simply provide a real error page!

#229 isCurrentAction():

  • let's you test if a given action is equal to the currently executing action - as you might need in navigation elements to highlight the currently active tab.

The UserManager example has been overhauled to use DI/1 and no longer rely on the service queue. All the other examples will be overhauled before I release 2.5. The documentation will also get updates (of course) and the Getting Started page will probably be rewritten from scratch to lead new users down the right path as they encounter services (i.e., using a bean factory).

So what's the deal with the service queue? This was something introduced back in 2009 and was intended to provide a simple-to-use convention-based way to ensure the appropriate service methods are called with the appropriate arguments automatically. This was supposed to encourage FW/1 users to keep controllers simple and to put their business logic in service CFCs, since it was so easy to do that. For anything more complex, you could queue up additional service calls and they'd be called automatically between the start and end controller methods for a given action, or after the primary controller method. In other words, it was intended to make it easy for you to "do the right thing". In reality, users quickly outgrew the convention and started to manage services directly. It's arguable whether it really worked well even for the simple cases. FW/1 2.5 is the first step to moving users in that direction!

Feedback and suggestions welcome, as always!

LightTable comes of age!

posted: 11 Jan 2014

Early in 2012, Chris Granger - former Program Manager for Microsoft's Visual Studio product, Bay Area resident, and Clojure enthusiast - released a proof of concept video for something he called "LightTable", a radical rethinking of our traditional programming environments. Over the next few months, new videos appeared, followed by a KickStarter project...

...and gradually the vision of LightTable turned into a series of working software sketches that drew an ever-increasing number of users, taking advantage of LightTable's live code evaluation for Clojure, ClojureScript, JavaScript, and Python - despite its rough edges - until just the other day when LightTable reached a stage where Chris, and his new team, felt it was ready to be released to the public: LightTable became open source and it also sprouted an ecosystem of plugins.

LightTable is still young but it is already a usable editor with some very unique features. Over the last year I've kept dipping into LightTable to see how it is evolving but it's been too rough around the edges, and too feature poor, to use for anything more than small projects for short periods. It's always shown tremendous promise though so I knew it was only a matter of time...

...and with the new release, and the plugins available, today I was able to use LightTable for all of my editing needs (and I'm writing this blog post in it as well!). Today I've been exploring the Monger library for MongoDB. We've been a CongoMongo shop for a couple of years but there are all sorts of reasons why we're concerned about continuing to rely on that library (and I'm pretty much the de facto lead on the project!). LightTable's live evaluation and inline documentation make it really easy to explore and play with new libraries and to evaluate how a particular library will work with your code.

What's missing?

As I said, LightTable is still young. The plugins available so far are pretty basic. I'm an Emacs user so I'm used to full keyboard control, integrated Git, and a whole bunch of powerful packages. That said, LightTable is already doing well: the Emacs key bindings are usable (but still quirky), there's a great REPL experience, rainbow delimiters and the Claire plugin provides a good first step toward the ido-mode C-x C-f experience. Git integration is the biggest missing piece for me right now. Global find and replace. An integrated shell. And an IRC client would be icing on the cake.

So I can't leave Emacs behind yet. I doubt I'll be able to leave it behind for a while. But I expect I'll be able to use LightTable for more and more serious work going forward.

cf.Objective() 2014 - now you can spread the love!

posted: 07 Jan 2014

Promotional badges:

If you're a ColdBox fan, don't forget Into The Box the day before cf.Objective()!

clojure.java.jdbc 0.3.2 released

posted: 30 Dec 2013

This release contains minor bug fixes compared to 0.3.0, with the main focus being an overhaul of docstrings etc to improve the auto-gen'd documentation.

The community documentation for java.jdbc on clojure-doc has also had a major overhaul.

Details of this release:

  • Add nil protocol implementation to ISQLParameter.
  • Improve docstrings and add :arglists for better auto-generated documentation.
  • Make insert-sql private - technically a breaking change but it should never have been public: sorry folks!
  • Provide better protocol for setting parameters in prepared statements JDBC-86.
  • Fix parens in two deprecated tests JDBC-85.
  • Made create-table-ddl less aggressive about applying as-sql-name so only first name in a column spec is affected.

Please note that the 0.3.1 release is broken and should not be used.

TestBox - replacing MXUnit and providing BDD

posted: 24 Dec 2013

If you've seen my tweets over the last couple of days, you'll know that I've been taking a look at TestBox, the new testing framework from the ColdBox team.

You might be thinking "Do we really need a new testing framework?" and it's a reasonable question. CFML has had a number of testing frameworks over the years but mostly we've seen each one come and go as maintainers have moved onto other things: cfUnit, then cfcUnit, then a brief resurrection of cfUnit, then MXUnit. Does anyone remember cfSpec? I liked that a lot - I like the Behavior-Driven Development style of writing tests. That's why, at World Singles, we use the Expectations library for almost all of our Clojure-based tests.

So why the interest in TestBox? My initial interest was spurred by the inclusion of the BDD style of tests which I find both more natural to read and a better fit for expressing requirements for software that is yet to be written. Then I read that TestBox has MXUnit compatibility which intrigued me - we have been using MXUnit for several years at World Singles and I don't relish having to rewrite all those tests. If TestBox could allow us to run our existing "xUnit" tests as-is while we write new tests in the BDD style, I'd be very happy.

Adam Cameron has been blogging about Test-Driven Development recently and has also picked up on TestBox. He just blogged about trying TestBox on his extensive MXUnit test suite and you can see he ran into a number of issues, all of which he has reported, and which I expect we'll see fixes for. My experience was more fruitful than his - as I mentioned in my comment on his blog post: just two small changes got the whole of our suite running flawlessly!

My next challenge was integrating TestBox into our automated build / test script, which uses Ant. TestBox provides a runner-template that shows how to do basic Ant integration. I followed that recipe but discovered there was no way for Ant to see that any tests failed and so I couldn't "fail the build" if TestBox found errors or failures. After studying the source code briefly, I realized I could extend the TestBox CFC and provide a way for the runner CFM template to access the details of the TestResult object, and write a property file that Ant could read and fail if a certain property was set. Time to fork the ColdBox Platform Github repo and send a Pull Request to add build failing functionality which Luis merged in within a few hours! Nice!

With that in place, I was able to delete MXUnit from the World Singles repo and rely entirely on TestBox for all our testing needs!

Whether you prefer the "xUnit" style of tests, with assertions, or the "BDD" style with expectations, TestBox can support you, and even if you have a lot invested in MXUnit, migration to TestBox should be straightforward (especially once they address the issues Adam has raised). I think we can be sure of ongoing support and maintenance - based on the well-established track record of the ColdBox Team. I think TestBox is a safe bet. Now you just need to start actually doing some automated testing :)

FW/1 2.2 Released!

posted: 18 Dec 2013

Framework One version 2.2 is now available for production use! You can download it from the Framework One page on RIAForge. This includes one bug fix over RC2 (interaction between renderData() and trace output).

The main focus of the 2.2 release is improved support for REST APIs, through the addition of renderData() to simplify returning JSON, XML and plain text results to the caller, as well as more sophisticated route handling via "resource packs" which let you define a family of related routes for a given resource type, using a shorthand notation. For more information, see this blog post about the latest FW/1 release and the roadmap.

As noted previously, the master branch is the current stable release (2.2), and the develop branch has become the next release (2.5). 2.5 will be released next month and will be a stepping stone toward some substantial changes coming in 3.0. For more detail, read this blog post explaining the changes coming in 2.5 and 3.0.

Speaking at cf.Objective() and Scotch on the Rocks

posted: 17 Dec 2013

I'm very pleased to be able to say that I will be giving a talk on Functional Programming for the Web at both cf.Objective() in May 2014 and Scotch on the Rocks in June 2014!

For a little background on the talk, you can read my earlier blog post about Functional Programming for the Web but I wanted to provide a bit more detail about the contents of the talk in this post.

If you write web applications in a typical imperative and/or object-oriented language, the logic for each request will generally be a mix of side effects as well as data transformations. In many simple data processing web applications, the focus will actually be on those side effects: updating the database. Such side effect laden code can be difficult to test as well as difficult to scale, since you cannot leverage multicore servers easily when your logic is interspersed with database calls. In a functional programming language, you are encouraged (and sometimes even forced) to separate out side effecting code from your data transformation code which makes it much easier to write tests for your purely functional code, as well as better leveraging the performance of multicore servers for any work that is CPU-intensive.

We'll walk through an interactive web application, written in a functional style, looking at how to isolate side effects so that testing is easier, as well as exploring concurrency to improve performance. You'll learn a little Clojure - enough to follow along with the examples - and some functional programming concepts that can be applied to other languages. I'm hoping to show four versions of the application, written in very different styles, to how functional programming techniques can apply in various ways:

  • MVC on the server (FW/1 for Clojure)
  • MVC on the client (AngularJS, with ClojureScript on the client and REST-based Clojure on the server)
  • Asynchronous channel-based communication (ClojureScript on the client, Clojure on the server)
  • FRP - Functional Reactive Programming - on the client (Elm on the client and REST-based Clojure on the server)

Even if I don't have time to show all four versions during the talk, I'll make the code available on Github after Scotch on the Rocks. My goal is that you'll be able to apply at least some of these techniques to whatever language you use today, to leverage some of the same benefits I'll show in the talk - and hopefully make you curious about Clojure, ClojureScript, and Elm!

clojure.java.jdbc 0.3.0 Released!

posted: 17 Dec 2013

The "gold" release of the Clojure contrib library that wraps JDBC is now available on Maven Central. This release has been in the works for most of this year, as it introduces large changes from the previous "gold" release (0.2.3) that aim to make the library more idiomatic and easier to use in a multi-threaded functional environment. In order to provide a smooth migration path, the old API from the 0.2.3 release has been moved wholesale to the clojure.java.jdbc.deprecated namespace, and the new API in 0.3.0 uses new naming for almost all of the (new) functionality.

The main API change is the removal of the dynamic global variable *db* and the with-connection macro. Instead you now pass the database spec as an explicit argument in all calls, and you can share connections across multiple SQL operations either by using connection pooling (recommended) or the new with-db-connection macro that takes an explicit binding for (a connected version of) the database spec.

A common problem with the old API when performing queries was that with-query-results required care because the result set was lazily constructed and it was easy to let that lazy sequence escape and have the connection closed before you had finished working on the results. The new API provides a query function that, by default, fully realizes the result set to avoid that problem. You can still process very large result sets lazily by passing :row-fn and/or :result-set-fn arguments to query.

For more details of the new API, you can read the reference documentation for clojure.java.jdbc. For a summary of all the changes made since the 0.2.3 release, read the clojure.java.jdbc change log on Github. To use the library in your project, see the clojure.java.jdbc dependency information on Github.

Detailed documentation on using clojure.java.jdbc is being developed for the Clojure Documentation Site and will be found in the java.jdbc section of the Clojure ecosystems area, once the site has been refreshed from the markdown sources on Github.

clojure.java.jdbc 0.3.0 RC1

posted: 13 Dec 2013

Clojure's low-level JDBC wrapper inches closer to a gold 0.3.0 release with the first release candidate. Read more on clojure.java.jdbc's Github repo. The changes in this release are:

  • Deprecate db-transaction (new in 0.3.0) in favor of with-db-transaction JDBC-81.
  • Add with-db-metadata macro and metadata-result function to make it easier to work with SQL metadata JDBC-80.
  • Add with-db-connection macro to make it easier to run groups of operations against a single open connection JDBC-79.
  • Add ISQLValue protocol to make it easier to support custom SQL types for parameters in SQL statements JDBC-77.
  • Add support for :isolation in with-db-transaction JDBC-75.
  • Add :user as an alias for :username for DataSource connections JDBC-74.

The reference documentation for clojure.java.jdbc has already been updated. The Clojure Documentation Site java.jdbc section has been updated in Github, pending a regeneration of the site.

FW/1 2.2 Release Candidate 2

posted: 02 Dec 2013

Framework One version 2.2 release candidate 2 is now available for testing (download from the Framework One page on RIAForge). This includes a couple of bug fixes, compared to release candidate 1. See the FW/1 2.2 RC2 release notes on Github for more details. Unless any showstopping bugs are found this week, the final 2.2 release will be made early next week, merged to master, and then develop will become the 2.5 branch.

See FW/1 Releases and Roadmap and FW/1 - The Year Ahead for more information about the upcoming 2.2, 2.5 and 3.0 releases, as well as plans for DI/1.

A Year With Windows 8

posted: 01 Dec 2013

About a year ago, I bought a Dell XPS 12 "convertible" with Windows 8, and I've been meaning to write up the experience for a long time. My Microsoft acquaintance, Matt Harrington, asked me back in June how I was getting on with it and, in particular, how I was liking it for Clojure development.

As I said at the time, my initial impressions were very positive, especially for someone who has been an Apple customer for two decades. How has it held up over the twelve months since purchase?

Overall, I'm still very impressed with this machine / O/S combination. Shocking! The flip-screen still makes people stop in their tracks, and it gets a lot of attention at conferences, which amuses me no end, given how prevalent Macs are in the tech community these days!

It hasn't all been good news tho'... The reliability of the wifi has been appalling, to be honest, right up until the recent Windows 8.1 update. I'm so used to Apple's rock solid wifi behavior on every machine / device I've owned that this was a real pain point - and it was one of the major issues I had with my Ubuntu netbook too in the time I had that. The Windows 8.1 update seems to have resolved the problems: I've had no problems at all with wifi since that update. Thank you Microsoft!

The touch screen stops responding to touch. This was pretty common before the 8.1 update but all sorts of things made it come back to life and, at worst, I'd just put it to sleep and wake it up, so it wasn't as annoying as the wifi issue. That said, I've only had it happen a couple of times since the 8.1 update so maybe that's been partially addressed too (although I'd point the finger at Dell here, rather than Microsoft).

I use this machine almost every day. I use it for casual content consumption most evenings while watching the TV and when I'm on public transit, or flying. I read books, I play games. When I'm online, I do email and surf the 'net. The keyboard is comfortable, with decent travel. The touch pad is large and responsive, but I still can't get used to it not working well with a combination of left and right thumbs which works flawlessly on Apple touch pads. I've used it for presenting at conferences and user groups and, compared to Apple laptops, it's definitely not as "plug'n'play" and the experience is still a bit quirky and unreliable, with poor screen alignment and weird resolution selection. As an e-reader, it's a bit big and heavy but the high resolution screen and the built-in PDF reader make for a very nice ebook reading experience in portrait mode. I wish the battery life were better tho' - four hours tops is not enough to cross the country on a plane!

As a development machine, I struggle with the lack of full *nix command line support: GOW (Gnu On Windows) is a reasonable substitute, and using Emacs as my primary editor really helps (since it has "shell" and "eshell" packages). I also have "Git Bash" and I use Console2 as a basic command line replacement, and those both help too. A year ago, I mentioned I had a problem with Ant doing variable substitution differently on Windows. I never got to the bottom of that but I rewrote that part of the Ant script in Clojure which side-stepped the problem. I have a ton of different language systems installed now: Clojure (obviously), Scala, Groovy, Racket, Node.js, Haskell, Python, Ruby, Erlang and, yes, CFML via Railo on Tomcat. And of course Java (but who uses that?). Once I'm inside Emacs, it pretty much doesn't matter what O/S I'm running so the answer to Matt's question is "Emacs".

The Windows 8.1 update was a major improvement all round. I can do without the stupid "start" button (why did Windows users get so upset about this going away?), but the ability to run multiple "metro" apps side-by-side is awesome. The new "metro" mail app is great (although I'd really appreciate an obvious way to do the equivalent of Gmail's "archive"). The overall feel of the operating system is much improved.

On the hardware side, Dell have done a great job with this machine: it's light yet solid, reasonably ergonomic, and the screen is great. It also stays fairly cool on my lap which is more than I can say for any of the Apple laptops I've owned. My only criticism of the hardware would be the very "sticky outy" power cable which, compared to Apple's magnetic adapter, is very old school and has already gotten bent a little.

A year in, for $1,600, I'm still happy.

clojure.java.jdbc 0.3.0 beta2

posted: 25 Nov 2013

Based on feedback from the community, I have released clojure.java.jdbc 0.3.0-beta2 to Maven Central.

This includes two very important changes:

  • The clojure.java.jdbc.sql and clojure.java.jdbc.ddl namespaces have been removed.
  • The API functions that were already marked as deprecated have moved to the clojure.java.jdbc.deprecated namespace

This means that if you depend on the clojure.java.jdbc.sql or clojure.java.jdbc.ddl namespaces, which were introduced in 0.3.0-alpha1, you will need to switch to the java-jdbc/dsl project (release 0.1.0 is on Clojars). The new namespaces in that project are java-jdbc.sql and java-jdbc.ddl. If you depend on these namespaces, I strongly recommend you migrate to a more sophisticated DSL, such as:

  • HoneySQL - https://github.com/jkk/honeysql
  • SQLingvo - https://github.com/r0man/sqlingvo
  • Korma - http://www.sqlkorma.com

More importantly, if you depend on the older (0.2.3) API in clojure.java.jdbc, you'll need to switch to the clojure.java.jdbc.deprecated namespace in your code, until you can migrate to new API in clojure.java.jdbc instead.

These steps are more radical than I would have liked but they simplify the library and streamline the API - and the auto-generated documentation - which should reduce all the confusion expressed about the library right now. This will allow the library to move forward in a more focused manner, with an API that no longer depends on dynamic variables.

Clojure/conj 2013 - a quick recap

posted: 19 Nov 2013

This was my third Clojure/conj and the first year it's been outside of Raleigh, NC - with the actual event at the George Washington Masonic Memorial, in a beautiful theater, and lodging at the (expensive) Embassy Suites, just a few minutes away. As usual, the caliber of the talks was (mostly) excellent - which is important in a single track conference - and the hallway / bar conversations were also very educational / entertaining!

I'm not going to go over the talks one by one - I think Logan Linn has a great post about the Clojure/conj 2013 talks - so I'm just going to mention some highlights:

Russ Olsen's "To The Moon!" was an inspirational closer for the conference: go home and do something hard! Tim Ewald's "Clojure: Programming with Hand Tools" was a brilliantly illustrated metaphor for the benefits of simplicity, as enshrined in Clojure's approach to both language design and problem solving. Aria Haghighi's "Prismatic's Schema..." covered a practical tool for both data validation and documentation that really caught my fancy - more below. Mike Anderson's "Enter the Matrix" really showed the power of protocols and clean, simple design, allowing for a high-performance matrix manipulation library (core.matrix) with swappable implementations. Timothy Baldridge's "core.async" cut straight to the chase with an entirely code-based presentation illuminating many of this cool library's features.

Honorable mentions also go to: Jennifer Smith for her "Internet of Strings" talk which showed how a contract DSL evolved that helped her specify and test interactions with third party systems; and Doug Selph's "Personalized Medicine, Powered by Clojure" which told the story of Clojure creeping into the corners of an organization and ultimately replacing Ruby on Rails for a core system!

Prismatic's Schema caught my attention so strongly that I actually skipped several day two talks in order to experiment with it in a real world code setting. I'd previously experimented with core.typed (a.k.a. Typed Clojure) as a way of adding type-based testing to our current automated tests at World Singles. I really like the premise of Typed Clojure but, right now, it's a little rough to use: you have to annotate everything in a namespace, or else add code to explicitly only warn for the unannotated Vars (and then ignore all the warnings in the output), you have to add annotations for called functions that core.typed doesn't know about, there's no type inference yet, the actual types are a little unforgiving sometimes (especially around number handling). It's an amazing project - even in my short time trying it out on production code it found a logical error very quickly - and I like that it can be applied entirely externally to the code. Right now tho', Schema provides a more optional approach: you can annotate just what you want, you can add explicit validations in your test suite, and overall it feels less formal and more pragmatic. That said, Schema isn't Typed Clojure - it doesn't analyze your code and it only provides runtime checks so your tests have to exercise enough paths to allow Schema to actually do its job. For now, for us, Schema provides enough additional checks in our test suite, without a huge amount of work - and it allows us to add type-checking where we feel we need it most. If Typed Clojure gets type inference and can be a little more optional, I can see us switching entirely to that. It all just shows what an exciting community we have with Clojure.

clojure.java.jdbc 0.3.0 beta 1

posted: 04 Nov 2013

The clojure.java.jdbc library has finally hit "feature complete" for the upcoming 0.3.0 release and so the first beta release has been made available. For full details, see the clojure.java.jdbc README on Github but here's a quick list of changes in this release:

  • query as-arrays? true now allows you to leverage lazy result fetching - JDBC-72
  • "h2" is now recognized as a protocol shorthand for org.h2.Driver
  • Tests no longer use :1 literal - JDBC-71 - (this was due to a change made in Clojure 1.6 that has since been reverted, but may be revisited in future)
  • Conditional use of javax.naming.InitialContext so the library can be compiled on Android - JDBC-69
  • New db-query-with-resultset function replaces private db-with-query-results* and processes a raw ResultSet object - JDBC-63
  • Allow :set-parameters in db-spec to override set-parameters internal function to allow per-DB special handling of SQL parameters values (such as null for Teradata) - JDBC-40

JDBC-65 (a bug affecting SQLite) will be fixed before the 0.3.0 final release. JDBC-70 (an enhancement to DDL) may also be included.

FW/1: The Year Ahead

posted: 03 Nov 2013

With FW/1 Version 2.2 just around the corner - after a long time in incubation - and FW/1 itself being almost four and a half years old, it's a good time to look ahead at what's in store.

When FW/1 was first conceived, it was intended to be drop-dead simple and help on-board developers who were new to MVC and new to frameworks and also new to OOP. It leveraged conventions very heavily to encourage simple controller logic and delegation to a service layer for heavy lifting. That was the conceptual justification for the implicit service calls in the 1.x version and the ability to split controller methods in two - start/end-item - to wrap the automatic call to the service layer.

While that conceptual framework served its purpose admirably, users very quickly grew out of it and needed to start managing service calls more directly. That's why implicit service calls were no longer the default in 2.0 (although you could turn them back on). Even with that change, many users find the queuing of service calls confusing, even tho' controller calls are also queued (although that's mostly invisible to users).

In version 2.5, scheduled for early January 2014, FW/1 will begin the move away from queuing services by deprecating the service() call and requiring a configuration setting to enable its use in your application. In version 3.0, scheduled for release just after cf.Objective() 2014, the service() call will be removed. Along with that, the start/end-item calls will be deprecated in 2.5 and removed in 3.0, since they were only introduced in the first place to create the queued services workflow!

This means that users will need to manage services themselves and of course I recommend using a Dependency Injection framework for that (or at least using some sort of object factory as a bare minimum). Accordingly, DI/1 will have a higher profile in FW/1 2.5 and the two frameworks will be officially bundled together in 3.0. FW/1 will continue to support any bean factory that provides the containsBean() and getBean() API such as ColdSpring (WireBox uses a slightly different API but I plan to provide an adapter for it in 2.5).

Also as part of 3.0, the framework CFC itself will be renamed and the /org/corfield structure removed. The default path will be /framework/one.cfc so your Application.cfc will have extends="framework.one" by default. In 2.5, DI/1 will have adopted this pattern as /framework/ioc.cfc, but since 2.5 will still be backward compatible with 2.2 (after you've added the compatibility setting in Application.cfc), I don't want to force renaming or reorganizing on users until 3.0.

Finally, as part of 3.0, the entire repository will be restructured to better reflect what is considered "best practices" in terms of where you install things and what lives in your webroot (only web-accessible assets!). This will make it easier to get started with the FW/1 skeleton application as a "best practice" out-of-the-box experience.

Note that the DI/1 and AOP/1 repositories will remain active but DI/1 versions will be in lockstep with FW/1 from 3.0 onward, and development will be conducted as part of the FW/1 repository, with releases being merged to the DI/1 repository. Once AOP/1 reaches a similar level of maturity, it will likely follow the same trajectory.

FW/1 Releases and Roadmap

posted: 02 Nov 2013

Today I released the first FW/1 Version 2.2 Release Candidate for testing. See below for the list of changes in this release, compared to Version 2.1. I also released a maintenance update for the old compatibility branch: FW/1 Version 1.3 (the "Latest Release" label is due to Github's view of the world, but it is the latest 1.x release). This is the version to use if you're on CFMX 7, CF 8, CF 9.0.0, Railo versions prior to 3.2, or OpenBD.

In addition to these two releases, I also added milestones (and dates!) for the next two FW/1 releases: 2.5 and 3.0. There are some fairly big changes coming, including some important breaking changes. I'll post a follow-up with more details on why these changes are coming, but you should read the FW/1 Roadmap and start thinking about how these changes will affect you (as well as reading the next blog post, of course!).

As always, FW/1 wouldn't be possible without all the contributions from the community. This version includes contributions from John Berquist (regex caching in routes, resource packs in routes), Marco Betschart, Chris Blackwell, Peter Boughton, Will Coleda, Billy Cravens, Mark Drew, and all those who have provided feedback via the mailing list and Twitter and IM and... Thank you!

Here's a fairly complete change list for Version 2.2:

  • #198 renderData() added for easier REST APIs
  • #197 resource pack support added to routes for easier REST APIs
  • #195 override processRoutes() to customize them (addRoute() is deprecated)
  • #192 regex in routes are now cached for improved performance
  • #181 improve null value support (Railo compatibility)
  • #179 can use onMissingMethod() for injectFramework()
  • #176 buildURL() now correctly supports ? at end of action
  • #175 subsystems automatically enabled if you specify subsystem configuration
  • #170 layout suppression is now correctly reset on an exception
  • #169 ensure framework.home is consistent with subsystem settings
  • #168 don't strip additional characters from start of path
  • #165 onMissingView() correctly called when view is missing
  • #163 trace code no longer fails if session scope is disabled
  • #160 buildURL() sanity checks queryString as struct

Additional changes:

  • fixed error message for service() missing action
  • framework initialization logic is more robust
  • improve example that uses DI/1 to avoid confusion over what to manage
  • improve consistency of framework injection (of itself)
  • layout trace shows correct path

cf.Objective() & Scotch on the Rocks 2014 - Yeah,

posted: 01 Nov 2013

I've said several times in several venues that I plan to attend Scotch on the Rocks 2014 - as part of my annual visit to see my folks in the UK (my wife judged a cat show there this year and has one scheduled for 2015 so SotR is a great "excuse" to visit in 2014) - so it should be no surprise that I've submitted a talk there. I go back and forth on submitting talks to cf.Objective(). This year I submitted three talks and ending up giving all three talks and, whilst they were well-received, it was a lot of work and really a bit much in terms of truly enjoying the conference (although I had a great time). Last year I didn't even expect to go, until the last minute when I attended as a "booth babe" for Railo since they had some big announcements to make and needed extra cover while they were talking with the community. I didn't speak in 2008 either, when I was the entirety of the "Content Advisory Board". But for 2014, since I was going to be developing a talk for SotR, I figured I might as well throw my hat in the ring for cf.Objective() 2014 as well...

Below is the full description of the talk. You can vote on cf.Objective() submissions via Trello and vote on Scotch on the Rocks submissions via their Engage app (which nicely has anonymous voting so you're really voting on the topic instead of the speaker!).

Functional Programming for the Web

Description: Functional Programming (FP) is the new "hotness" but it can be very daunting for developers with a "traditional" background in imperative and/or object-oriented languages. This talk will provide a fairly gentle introduction to what web applications look like in a Functional Programming world and highlight a number of techniques you can use in your current applications to help make them more testable, more scalable, and more robust. We'll look at a complete web application, written in Clojure using FW/1 (which will be at least partially familiar to many CFML developers). We'll also take a look at some emerging technologies for interactive web development and show some of these techniques applied to CFML.

Target audience: Web developers who are "functional-curious" and looking to expand their skills beyond the imperative and object-oriented worlds, or who want to learn techniques to improve testability, scalability, and robustness.

Assumed knowledge: General web development experience in an imperative and/or OOP language (such as CFML). No prior FP knowledge is required.

Objectives: Expose developers to Functional Programming techniques. Expose developers to a new and exciting language on the JVM (Clojure). Teach techniques that can improve testability, scalability, and robustness in traditional web applications.

Why me? I've been developing production applications in functional programming languages for about four years, and have a long history of interest in functional programming, dating back to thesis research work on the subject in the early 1980's.

Main points your audience will learn:

  • The basics of functional programming
  • The basics of Clojure
  • How to make your code more testable
  • How to eliminate thread safety issues in your code
  • A glimpse into some of the cool emerging technology in the functional web space (including a quick look at FRP - Functional Reactive Programming)

Even if you're not interested in my topic, go and vote for other topics you like, and I hope to see you at one (or both!) of these conferences next year!

Upgrading Railo 3 to Railo 4

posted: 23 Oct 2013

At World Singles, we're just going thru the process of upgrading from Railo 3 to Railo 4 (specifically from 3.3.4 to 4.1.1) and I thought I'd jot down a quick blog post about it. First off, I should explain that we use the WAR install on a vanilla Tomcat install, and mod_proxy_ajp to connect Apache to Tomcat. See my Railo for Dummies blog post from 2009 about setting up that sort of environment for background. We have three web contexts (web applications), each running their own configured WAR install of Railo, so we can package each web application up easily and move it around, including the Railo runtime. We can also upgrade each web application separately.

We'd already upgraded from Java 6 to Java 7 (download and unpack the JDK from Oracle into a new folder, update the symlink for the default java executable), and from Tomcat 6 to Tomcat 7 (download and unpack the Tomcat archive from Apache into a new folder, update the symlink for the current version, copy setenv.sh and context.xml from the old to the new - we'd customized those - and then add <Host..> entries to server.xml as necessary). Piece of cake so far.***

I expected the Railo upgrade to be more work than Tomcat. I was wrong. A pleasant surprise! I downloaded the new Railo 4.1.1 WAR file and unpacked it into a temporary folder (using jar xf /path/to/railo-4.1.1.009.war). Then I copied the WEB-INF folder over my existing Railo installations:

tar cf - WEB-INF | ( cd /path/to/application/webroot; tar xf - )

That's just my go to method for non-destructively copying a whole directory tree on top of an existing set of files. The only file that needed customization was web.xml in one web application context where we had some SES URL patterns that matched subfolders. That was just a matter of adding three <url-pattern> lines to the <servlet-mapping> section for the CFMLServlet. That's all it took: download, unpack, copy (and a small edit). Started up Tomcat and Railo happily deployed itself into each web application context, without overwriting any of my previous Railo 3.3.4 settings in the three admins. Nice!

Any code changes? Yes, just two: ColdBox has a MessageBox plugin that uses isEmpty() which is now a built-in function - changing the two unqualified calls to this.isEmpty() solved that - and a couple of strange places where I'd accidentally used float and int as function return types in cfscript - this worked in Railo 3 as if I'd written numeric but in Railo 4 it was type checked as a Java primitive type (interesting in itself!) so I just changed those to numeric and everything else just worked!

***Piece of cake except for Braintree which is one of our payment providers. We were using an older version of their library and once we moved to Java 7, the security certificate processing was more strict and calls to their sandbox (not their production system) failed. Updating to the latest Braintree JAR on Maven Central fixed that.

cf.Objective() 2014 - call for speakers!

posted: 21 Oct 2013

The cf.Objective() 2014 Call for Speakers is open until November 1st so you have just under two weeks to submit your topics. You can also vote for existing topic submission at that same link.

Right now we've only had two general CFML topics submitted (and seven ColdBox-related ones!) but there's a good number of JavaScript-related submissions - and remember that cf.Objective() has a dedicated JavaScript track in js.Objective(), as well as a mobile/front-end track so it's more than a CFML conference... but we still want to see a good spread of CFML topics!

And if you want to submit non-CFML web development topics that you think would appeal to a CFML / JS audience in terms of broadening their skills, you should do that too! Last year Scott Stroz did an excellent talk about Groovy on Grails, and I touched on some advanced CFML techniques inspired by other languages in my polyglot talk.

Note: when you submit a talk, please make sure to follow the guidelines outlined in this blog post about cf.Objective() 2014 submission format!

lein-try rocks - instant HTTP server!

posted: 17 Oct 2013

The lein-try plugin is one of the more stunningly useful "little pieces" of software that you can have available if you're developing in Clojure. Simply add the plugin to your user profile (in ~/.lein/profiles.clj) and then lein try some-dependency will fire up a REPL with the specified dependency on the classpath.

Today, I needed a simple HTTP server running for a short while, serving up static assets from a specific folder tree. Instead of messing with my local Apache setup, I used lein-try to fire up a temporary HTTP server:

> lein try ring/ring-core 1.2.0 ring/ring-jetty-adapter 1.2.0
...
user=> (use 'ring.adapter.jetty)
nil
user=> (use 'ring.middleware.resource)
nil
user=> (def app (wrap-resource (constantly {:headers {"Location" "index.html"} :status 301}) "."))
#'user/app
user=> (run-jetty app {:port 3333})
2013-10-17 18:03:14.792:INFO:oejs.Server:jetty-7.6.8.v20121106
2013-10-17 18:03:14.819:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:3333

That starts a Jetty instance on port 3333 with a very simple Ring-based web application:

  • If static assets are requested, they are served up (by wrap-resource) relative to the current folder ("."),
  • Else you are redirected to index.html.

The Strange Loop 2013

posted: 22 Sep 2013

This was my second time at The Strange Loop. When I attended in 2011, I said that it was one of the best conferences I had ever attended, and I was disappointed that family plans meant I couldn't attend in 2012. That meant my expectations were high. The main hotel for the event was the beautiful DoubleTree Union Station, an historic castle-like building that was once an ornate train station. The conference itself was a short walk away at the Peabody Opera House. Alex Miller, organizer of The Strange Loop, Clojure/West, and Lambda Jam (new this year), likes to use interesting venues, to make the conferences extra special.

I'm providing a brief summary here of what sessions I attended, followed by some general commentary about the event. As I said last time, if you can only attend one conference a year, this should be the one.

  • Jenny Finkel - Machine Learning for Relevance and Serendipity. The conference kicked off with a keynote from one of Prismatic's engineering team talking about how they use machine learning to discover news and articles that you will want to read. She did a great job of explaining the concepts and outlining the machinery, along with some of the interesting problems they encountered and solved.
  • Maxime Chevalier-Boisvert - Fast and Dynamic. Maxime took us on a tour of dynamic programming languages through history and showed how many of the innovations from earlier languages are now staples of modern dynamic languages. One slide presented JavaScript's take on n + 1 for various interesting values of n, showing the stranger side of dynamic typing - a "WAT?" moment.
  • Matthias Broecheler - Graph Computing at Scale. Matthias opened his talk with an interesting exercise of asking the audience two fairly simple questions, as a way of illustrating the sort of problems we're good at solving (associative network based knowledge) and not so good at solving (a simple bit of math and history). He pointed out the hard question for us was a simple one for SQL, but the easy question for us would be a four-way join in SQL. Then he introduced graph databases and showed how associative network based questions can be easily answered and started to go deeper into how to achieve high performance at scale with such databases. His company produces Titan, a high scale, distributed graph database.
  • Over lunch, two students from Colombia told us about the Rails Girls initiative, designed to encourage more young women into the field of technology. This was the first conference they had presented at and English was not their native language so it must have been very nerve-wracking to stand up in front of 1,100 people - mostly straight white males - and get their message across. I'll have a bit more to say about this topic at the end.
  • Sarah Dutkiewicz - The History of Women in Technology. Sarah kicked off the afternoon with a keynote tour through some of the great innovations in technology, brought to us by women. She started with Ada Lovelace and her work with Charles Babbage on the difference engine, then looked at the team of women who worked on the ENIAC, several of whom went on to work on UNIVAC 1. Admiral Grace Hopper's work on Flow-Matic - part of the UNIVAC 1 project - and subsequent work on COBOL was highlighted next. Barbara Liskov (the L in SOLID) was also covered in depth, along with several others. These are good role models that we can use to encourage more diversity in our field - and to whom we all owe a debt of gratitude for going against the flow and marking their mark.
  • Evan Czaplicki - Functional Reactive Programming in Elm. This talk's description had caught my eye a while before the conference, enough so that I downloaded Elm and experimented with it, building it from source on both my Mac desktop and my Windows laptop, during the prerelease cycle of what became the 0.9 and 0.9.0.2 versions. Elm grew out of Evan's desire to express graphics and animation in a purely functional style and has become an interesting language for building highly interactive browser-based applications. Elm is strongly typed and heavily inspired by Haskell, with an excellent abstraction for values that change over time (such as mouse position, keyboard input, and time itself). After a very brief background to Elm, Evan live coded the physics and interaction for a Mario platform game with a lot of humor (in just 40 lines of Elm!). He also showed how code updates could be hot-swapped into the game while it was running. A great presentation and very entertaining!
  • Keith Adams - Taking PHP Seriously. Like CFML, PHP gets a lot of flak for being a hot mess of a language. Keith showed us that, whilst the criticisms are pretty much all true, PHP can make good programmers very productive and enable some of the world's most popular web software. Modern PHP has traits (borrowed from Scala), closures, generators / yield (inspired by Python and developed by Facebook). Facebook's high performance "HipHop VM" runs all of their PHP code and is open source and available to all. Facebook have also developed a gradual type checking system for PHP, called Hack, which is about to be made available as open source. It was very interesting to hear about the pros and cons of this old warhorse of a language from the people who are pushing it the furthest on the web.
  • Chiu-Ki Chan - Bust the Android Fragmentation Myth. Chiu-Ki was formerly a mobile app developer at Google and now runs her own company building mobile apps. She walked us through numerous best practices for creating a write-once, run-anywhere Android application, with a focus on various declarative techniques for dealing with the many screen sizes, layouts and resolutions that are out there. It was interesting to see a Java + XML approach that reminded me very much of Apache Flex (formerly Adobe Flex). At the end, someone asked her whether similar techniques could be applied to iOS app development and she observed that until very recently, all iOS devices had the same aspect ratio and same screen density so, with auto-layout functionality in iOS 6, it really wasn't much of an issue over in Apple-land.
  • Alissa Pajer - Category Theory: An Abstraction for Everything. In 2011, the joke was that we got category theory for breakfast in the opening keynote. This year I took it on by choice in the late afternoon of the first day! Alissa's talk was very interesting, using Scala's type system as one of the illustrations of categories, functors, and morphisms to show how we can use abstractions to apply knowledge of one type of problem to other problems that we might not recognize as being similar, without category theory. Like monads, this stuff is hard to internalize, and it can take many, many presentations, papers, and a lot of reading around the subject, but the abstractions are very powerful and, ultimately, useful.
  • Jen Myers - Making Software Development Make Sense For Everyone. Closing out day one was a keynote by Jen Myers, primarily known as a designer and front end developer, who strives to make the software process more approachable and more understandable for people. Her talk was a call for us all to help remove some of the mysticism around our work and encourage more people to get involved - as well as to encourage people in the software industry to grow and mature in how we interact. As she pointed out, we don't really want our industry to be viewed through the lens of movies like "The Social Network" which makes developers look like assholes!.
  • Martin Odersky - The Trouble with Types. The creator of Scala started day two by walking us through some of the commonly perceived pros and cons of both static typing and dynamic typing. He talked about what constitutes good design - discovered, rather than invented - and then presented his latest work on type systems: DOT and the Dotty programming language. This collapses some of the complexities of parameterized types (from functional programming) down onto a more object-oriented type system, with types as abstract members of classes. Compared to Scala (which has both functional and object-oriented types), this provides a substantial simplification without losing any of the expressiveness, and could be folded into "Scala.Next" if they can make it compatible enough. This would help remove one of the major complaints against Scala: the complexity of its type system!
  • Mridula Jayaraman - How Developers Treat Ovarian Cancer. I missed Ola Bini's talk on this topic at a previous conference so it was great to hear one of his teammates provide a case study on this fascinating project. ThoughtWorks worked with the Clearity Foundation and Annai Systems - a genomics startup - to help gather and analyze research data, and to automate the process of providing treatment recommendations for women with ovarian cancer. She went over the architecture of the system and (huge!) scale of the data, as well as many of the problems they faced with how "dirty" and unstructured the data was. They used JRuby for parsing the various input data and Clojure for their DSLs, interacting with graph databases, the recommendation engine and the back end of the web application they built.
  • Crista Lopes - Exercises in Style. Noting that art students are taught various styles of art, along with analysis of those styles, and the rules and guidelines (or constraints) of those styles, Crista observed that we have no similar framework for teaching programming styles. The Wikipedia article on programming style barely goes beyond code layout - despite referencing Kernighan's "Elements of Programming Style"! She is writing a book called "Exercises in Programming Style", due in Spring 2014 that should showcase 33 styles of programming. She then showed us a concordance program (word frequencies) in Python, written in nine different styles. The code walkthrough got a little rushed at the end but it was interesting to see the same problem solved in so many different ways. It should be a good book and it will be educational for many developers who've only been exposed to one "house" style in the company where they work.
  • Martha Girdler - The Javascript Interpreter, Interpreted. Martha walked us through the basics of variable lookups and execution contexts in JavaScript, explaining variable hoisting, scope lookup (in the absence of block scope) and the foibles of "this". It was a short and somewhat basic preso that many attendees had hoped would be much longer and more in depth. I think it was the only disappointing session I attended, and only because of the lack of more material.
  • David Pollak - Getting Pushy. David is the creator of the Lift web framework in Scala that takes a very thorough approach to security and network fallibility around browser/server communication. He covered that experience to set the scene for the work he is now doing in the Clojure community, developing a lightweight push-based web framework called Plugh that leverages several well-known Clojure libraries to provide a seamless, front-to-back solution in Clojure(Script), without callbacks (thanks to core.async). Key to his work is the way he has enabled serialization of core.async "channels" so that they can be sent over the wire between the client and the server. He also showed how he has enabled live evaluation of ClojureScript from the client - with a demo of a spreadsheet-like web app that you program in ClojureScript (which is round-tripped to the server to be compiled to JavaScript, which is then evaluated on the client!).
  • Leo Meyerovich - Thinking DSLs for Massive Visualization. I had actually planned to attend Samantha John's presentation on Hopscotch, a visual programming system used to teach children to program, but it was completely full! Leo's talk was in the main theater so there was still room in the balcony and it was an excellent talk, covering program synthesis and parallel execution of JavaScript (through a browser plugin that offloads execution of JavaScript to a specialized VM that runs on the GPU). The data visualization engine his team has built has a declarative DSL for layout, and uses program synthesis to generate parallel JS for layout, regex for data extraction, and SQL for data analysis. The performance of the system was three orders of magnitude faster than a traditional approach!
  • Chris Granger - Finding a Way Out. Some of you may have been following Chris's work on LightTable, an IDE that provides live code execution "in place" to give instant feedback as you develop software. If you're doing JavaScript, Python, or Clojure(Script), it's worth checking out. This talk was more inspirational that product-related (although he did show off a proof of concept of some of the ideas, toward the end). In thinking about "How do we make programming better?" he said there are three fundamental problems with programming today: it is unobservable, indirect, and incidentally complex. As an example, consider person.walk(), a fairly typical object-oriented construct, where it's impossible to see what is going on with data behind the scenes (what side effects does it have? which classes implement walk()?). We translate from the problem domain to symbols and add abstractions and indirections. We have to deal with infrastructure and manage the passage of time and the complexities of concurrency. He challenged us that programming is primarily about transforming data and posited a programming workflow where we can see our data and interactively transform it, capturing the process from end to end so we can replay it forwards and backwards, making it directly observable and only as complex as the transformation workflow itself. It's an interesting vision, and some people are starting to work on languages and tools that help move us in that direction - including Chris with LightTable and Evan with Elm's live code editor - but we have a long way to go to get out of the "tar pit".
  • Douglas Hofstadter, David Stutz, a brass quintet, actors, and aerialists - Strange Loops. The two-part finale to the conference began with the author of "Gödel, Escher, and Bach" and "I am a Strange Loop" talking about the concepts in his books, challenging our idea of perception and self and consciousness. After a thought-provoking dose of philosophy, David Stutz and his troope took to the stage to act out a circus-themed musical piece inspired by Hofstadter's works. In addition to the live quintet, Stutz used Emacs and Clojure to provide visual, musical, and programmatic accompaniment. It was a truly "Strange" performance but somehow very fitting for a conference that has a history of pushing the edges of our thinking!

Does anything unusual jump out at you from the above session listing? Think about the average technical conference you attend. Who are the speakers? Alex Miller and the team behind The Strange Loop made a special effort this year to reach out beyond the "straight white male" speaker community and solicit submissions from further afield. I had selected most of my schedule, based on topic descriptions, before it dawned on me just how many of the speakers were women: over half of the sessions I attended! Since I didn't recognize the vast majority of speaker names on the schedule - so many of them were from outside the specific technical community I inhabit - I wasn't really paying any attention to the names when I was reading the descriptions. The content was excellent, covering the broad spectrum I was expecting, based on my experience in 2011, with a lot of challenging and fascinating material, so the conference was a terrific success in that respect. That so many women in technology were represented on stage was an unexpected but very pleasant surprise and it should provide an inspiration to other technology conferences to reach beyond their normal pool of speakers too. I hope more conferences will follow suit and try to address the lack of diversity we seem to take for granted!

I already mentioned the great venues - both the hotel and the conference location - but I also want to call out the party organized at the St Louis City Museum for part of the overall "wonder" of the experience that was The Strange Loop 2013. The City Museum defies description. It is a work of industrial art, full of tunnels and climbing structures, with a surprise around every corner. Three local breweries provided good beer, and there was a delicious range of somewhat unusual hot snacks available (bacon-wrapped pineapple is genius - that and the mini pretzel bacon cheeseburgers were my two favorites). It was quiet enough on the upper floors to talk tech or chill out, while Moon Hooch entertained loudly downstairs, and the outdoor climbing structures provided physical entertainment for the adventurous with a head for heights (not me: my vertigo kept me on the first two stories!).

In summary then, the "must attend" conference of the year, as before! Kudos to Alex Miller and his team!

cflive.net - a shout out!

posted: 21 Aug 2013

Just a quick post to point people to cflive.net which is an awesome free service provided by Russ Michaels (CFMLDeveloper.com / Blue Thunder Hosting) that allows you to quickly try out snippets of CFML code in a browser, and even run them in ColdFusion and Railo side-by-side!

In the past you would always have to have some "scratch" file lying around in one of your local websites to test out snippets and then you'd have to copy it to another location to test on another CFML engine - if you even had the other one installed! Russ's site allows you to simply type the code into a form, check some boxes for debug output and which engine(s) to run it on, and submit - done!

This also has the great benefit of allowing new folks to try out CFML without needing to install anything - an approach which has been used very successfully by a number of other languages to let you play with code without commitment!

Kudos to Russ for building this on his own time and offering it to everyone for free!

FW/1 0.2.1 (for Clojure) released

posted: 19 Aug 2013

Framework One for Clojure version 0.2.1 is available. The easiest way to get started is via Leiningen and the fw1 template:

lein new fw1 myapp

This creates a minimal web application in the myapp folder that can be started like this:

PORT=8123 lein run

Now you have FW/1 running on port 8111 (via Jetty).

What's new in 0.2.1? The big new feature is Django-style HTML templating (via the excellent Selmer templating library). You can see an example view template here: usermanager example list view. You can see an example controller here: usermanager example controller (only lines 1-36 are relevant - the rest is to support the alternative Enlive-based template version provided in the same examples folder.

On My Radar?

posted: 24 Jul 2013

Mark Mandel and Kai Koenig were recently inspired by the ThoughtWorks "Technology Radar" to create their own, which they featured in episode 31 of 2 Devs Down Under, their conversational podcast. Because they're both somewhere along the spectrum of CFML-to-ex-CFML developers and have worked with Flex etc, their opinions on various technologies are probably of more interest to other CFML developers than the original ThoughtWorks radar. This podcast episode is longer than usual - nearly two hours - and Mark and Kai would love to hear your responses in comments. I decided my response was a bit too long to post as a comment, so I am turning it into a blog post instead.

The first category they covered is "Techniques" and their top two items are things that are top of my list as well: devops (infrastructure as code) and automated deployment. I've been advocating automation of builds and deployments for a long time and I'm always looking for better ways to manage these tasks. At World Singles, we've been using Ant for our build process and we're reaching the limits of what we can do easily so we're looking at code-based solutions instead, and we're also looking at devops via Pallet (Clojure-based specification of servers and software configuration). On the flipside, they advise "hold" on hand built infrastructure and one-off deployments - and I completely agree with them on that.

Also in their "adopt" or "trial" sections for techniques are SPA (Single Page Applications) and modular development with JavaScript. As we move into a world of mobile web applications, MVC on the client side is inevitable and something we're going to need to live with. JavaScript is not a language well-suited to large scale development and the lack of modules or namespaces has led to a number of workaround techniques and clever libraries (covered later). We'll eventually get native modules in JavaScript but, like many other issues with JavaScript, we're hamstrung by older browsers so adoption will be painfully slow. I'd recommend looking at other compile-to-JS languages that have native support for modular development and can bury the JS issues in a cross-browser manner (my personal preference is ClojureScript, of course, and that will come up again later).

Finally in techniques, they have Agile in adopt and Waterfall in hold. Two decades ago I worked in a process/QA-focused company that advocated a "V" process to replace Waterfall in the enterprise, and for the last decade I would have advocated Agile instead of Waterfall, so I'm with Kai and Mark on that. I know Agile still has its detractors but I don't think Waterfall still has any supporters left?

Next, Kai and Mark move on to "Platform" and perhaps controversially put Apache, IIS and MySQL into the "hold" section. Given Oracle's track record, I can certainly understand their concerns with MySQL - and at work we've been bumping heads with its performance limitations and would agree that it is not easy to provide robustness (in terms of replication and failover). As someone who won't put Windows servers into production, I can only smile at IIS being in this section but I was surprised by Apache's inclusion. The web server to "adopt" they say is Nginx and I'm about to start assessing that so I won't argue overall. Also in their "adopt" / "trial" / "assess" sections are a broad spread of no-SQL databases - which I also agree with. Mark recommends PostgreSQL on the grounds that he's seeing a lot of recommendations for it. I've looked at it a couple of times and, to me, it seems to have all the complexity of Oracle, combined with some very quirky non-standard behavior - but, like Mark, I keep hearing good things about it. Personally, I'd rather move fully onto MongoDB at this point because of the flexibility it provides in terms of schemas and data storage, combined with simple (and solid) replication and sharding for robustness and scalability. The final item on Mark's "assess" list that I'd call out is Hazelcast which is a very impressive piece of technology: it is a library that provides distributed versions of several standard Java data structures. This makes it insanely easy to set up distributed caches using the same data structures you're already using in your application, so you hardly need to make any code changes to be able to leverage clustering. Definitely worth a look.

Next we move onto "Tools" and Mark, in particular, recommends a lot of things that I am not familiar enough with to agree or disagree. Mark recommends Ansible and Vagrant where I'd probably lean toward Pallet and VMFest but, given Ansible is Python-based, I suspect Ansible would be a lot more approachable for many developers. Kai puts the Brackets editor from Adobe in the "trial" section which is an interesting choice. As a lightweight editor for HTML / CSS / JS, it's probably got a lot going for it but I'm keeping my eye on LightTable which, like Brackets, is also based on CodeMirror but offers some very interesting live evaluation options for JavaScript, Python and Clojure (and ClojureScript). Like Brackets, LightTable is designed to be extensible but full plugin support is something we'll get in the upcoming 0.5 release which is when I think LightTable will become very, very exciting! Both Kai and Mark put Eclipse in the "hold" section (which I agree with - it's become pretty bloated and plugin version compatibility can be a problem, esp. when Adobe's ColdFusion Builder is based on such an old build of Eclipse). Strangely - to me - they both put IntelliJ in "adopt". I've tried IntelliJ several times and I really can't get on with it. I find it to be every bit as bloated and complex as Eclipse, but far less usable. I can sympathize far more with Kai's recommendation of Sublime Text although, again, I just can't get on with it. I find it to be fussy and counter-intuitive in many areas, although a couple of my team members love it. My weapon of choice for editing is Emacs but I'm not going to try to convince everyone to use it. If you're doing Clojure development, it's probably the best-supported option, and it is extremely powerful but at the same time, quite lightweight.

Along with Eclipse, Kai and Mark throw quite a few other tools under the bus: FTP for deployment, Ant, Maven, and Dreamweaver. If you're doing server-side development, I have to agree with all of these. I use Ant but really don't like it, I have to use Maven occasionally for Clojure contrib projects and don't like that either - do we really need to be programming in XML? I think Dreamweaver is probably still a great choice for front end design work but CSS and JS support has improved so much in so many lightweight, open source editors that I find it hard to get enthusiastic about Dreamweaver even in that realm.

Finally Mark and Kai move onto "Languages & Frameworks" and they have a lot of JS-related recommendations which... well, I just can't find it in myself to like JS. The more I work with it, the less I like it. I know it's ubiquitous but as far as I'm concerned, it deserves to be the assembler of the web and no more. There are an increasing number of compile-to-JS languages now that provide some compelling choices. If I was a Windows guy, I'd probably be pushing WebSharper and FunScript which both offer F#-to-JS compilation, built on top of TypeScript. A statically typed functional language is a good choice for targeting JavaScript and papering over its many flaws. For a more general functional language, ClojureScript offers Clojure-to-JS compilation and that will be my choice as we move into more complex JS territory at work I expect. Both Mark and Kai recommend Clojure, which I was pleased to see (of course). Mark also recommends JRuby and Kai recommends Python. I had both on my list of languages to learn but having spent some time with both of them (Ruby via "Programming Languages" on Coursera; Python via 10gen's MongoDB for Developers, and attending PyCon), I've taken Ruby off that list and plan to spend more time with Python, probably in a system scripting capacity.

Perhaps of more interest to our audience is their position on CFML: Mark puts CFML in the "hold" section and Kai puts Adobe ColdFusion in the "hold" section but puts Railo in the "adopt" section. They have quite a discussion about this and I think this is the part of their podcast that should generate the most comments...

This also matches with Mark being essentially "ex-CFML" whilst Kai is still "CFML". I'm not quite "ex-CFML" but I'm no longer really "CFML" either. I understand Mark's point of view - that no one in the world at large is going to start a project in CFML - but I'm somewhat fascinated by Kai's optimism and it makes me re-examine my own position on CFML. At World Singles we're using CFML for the View-Controller portion of our application and it still makes sense. We're using Railo but I have to admit that even Railo feels a bit bloated for the VC portion - because we're using such a small subset of CFML at this point. That said, CFML is a wonderful templating language, and script-based controllers are a decent way to glue any Model to your Views. I've previously said we wouldn't bother upgrading beyond Railo 3.3 yet we're in the process of standing up two new servers as upgrade replacements for two of our existing servers, and we've decided to deploy Java 7, Tomcat 7, and Railo 4 - and now will upgrade the third server (and QA and all our dev environments eventually) to the same. Which means we'll start using closures in CFML and it will continue to have a renewed lease on life for a while.

Would I start a new greenfield project in CFML? Until recently I would probably have said "no" but now I'm not so sure. Would I ever start a new greenfield project in Adobe ColdFusion? No, that makes no sense at all in this age of free open source languages and frameworks. But Railo 4? It's a possibility. With their continued evolution of the language and the system's overall facilities (such as command line execution), I might just consider them for future projects... and continue using a hybrid of CFML for the View-Controller / container portion of the application, with Clojure for the Model. That was my big surprise after listening to Mark and Kai for two hours.

Lambda Jam 2013

posted: 14 Jul 2013

The first annual Lambda Jam (US) conference was held at the extraordinarily beautiful Intercontinental hotel in downtown Chicago, a few blocks from the lake. Lambda Jam was unusual in a couple of ways:

  • First off, it specifically targeted a broad range of functional programming languages - and only functional ones;
  • Second, it aimed to be much more hands on than normal conferences by having regular "lecture" sessions only in the morning and turning the whole afternoon over to workshops and "jams".

Overall, I thought Lambda Jam was excellent! We got a broad range of languages well-represented, we got a good mix of intermediate to advanced material (with a couple of sessions bordering on introductory as a way to explain the "why" and/or "how" of some particular language). I got the impression the workshops were a bit variable but I got a lot out of both of mine and heard some very high praise for most of the others. The jams also seemed to be a lot of fun, with folks working in teams - and not always in their "home" language - to tackle some interesting problems that they took turns to present to the group. I'd definitely say that the hands on "experiment" was successful.

My primary goal for the conference was to learn some other functional languages so I somewhat deliberately avoided the Clojure content, signed up for workshops on F# and Erlang, and made an effort to meet / hang out with new people. This was, after all, a vacation for me, with flights covered by air miles and a Sunday night red eye chosen to cut down on hotel costs! I came back exhausted, having made a lot of new friends, many of them outside of my normal "crowd". I was extremely impressed with F# and quite intrigued by Erlang so it was also a "success" for me!

  • Data, Visibility, and Abstraction - Stuart Sierra
    • Stuart kicked us off with an interesting trip down memory lane as he explored languages he'd worked with and what he liked and disliked about them, and the path that led him to Clojure. He liked clean, clear data structure representations and manipulations; he liked visibility into code structure - and into errors when things went wrong; he was positively influenced by Perl; he found C++ had a real lack of visibility, especially when things went wrong. An interesting and somewhat unusual discourse. His talk was recorded so keep an eye out for it.
  • Simile-Free Monads - Aditya Siram
    • I keep going to monad talks because I know they're important and I want to understand them. Almost every talk I attend gives me a little bit more insight. This talk was intended to strip away a lot of the mystique and just present three or four bare monads in a real world context, using Haskell as the exposition language. In some ways this was both the most straightforward talk on monads I've ever attended and at the same time one of the most obtuse and incomprehensible. I think my main problem here was that I'm not familiar enough with Haskell to understand why you'd do things this way so it just looked like a complicated way to do something simple.
  • Let It Crash - Tristan Sloughter
    • A good introduction to the whys and wherefores of Erlang, it's history, and how it is used at Heroku for very high throughput, fault tolerant things like request routing and logging. I was very interested to learn that the heap and associated garbage collection in Erlang is per (lightweight) process - unlike the JVM where there is a single huge heap and GC process shared by all the processes / threads running there. It set the scene nicely for the Erlang workshop I had signed up for on day two.
  • Workshop: Try F# from Zero to Data Science - Rachel Reese
    • We used the Try F# web site to learn and explore the language. This was good insofar as we didn't need to install anything, but bad when we had network problems or when the site actually crashed on us for a short while in the middle of the workshop! Rachel structured the workshop to follow three of the online tutorials with some additional challenges for us to try at various points, and encouraged us to work in pairs, as well as keeping things nice and interactive. We got the basic syntax out of the way quickly and moved on to charting a number of data sets. I had a bit of a fail on the statistics section of the workshop but we quickly arrived at the coolest - and most impressive - part: Type Providers. F# is a strongly typed, statically typed language with solid type inference so it's very concise but also helps you avoid a lot of coding errors while you're exploring because the type system allows the editor - even on the web - to provide you with live insight into the data structures you're working with. Type Providers are dynamically created, strongly typed wrappers around (large) sets of data fetched from various places, such as third party websites, databases and so on. We worked with a couple of providers but mainly focused on the World Bank data set which provides all manner of raw statistics about most countries around the world over varying periods of history. This allows you to do some pretty amazing data manipulation in just a few lines of code:

      // load World Bank Type Provider: #r "Samples.WorldBank.dll" // get the initial data context: let data = Samples.WorldBank.GetDataContext() // get a sequence of: // pairs of: // country name // gas price for 2010 (or zero if it is missing): let countryGas = seq { for c in data.Countries -> c.Name, c.Indicators.``Pump price for gasoline (US$ per liter)``.GetValueAtOrZero(2010) }

      Once we have that data, we can easily find the country with the most expensive gas that year:

      let maxPrice = countryGas |> Seq.maxBy snd

      We get a pair of "Eritrea" and 2.54. We can also create a bar chart of the top ten most expensive countries:

      // sort by gas price descending (by negative gas price) // and take the ten most expensive: let top10 = countryGas |> Seq.sortBy ( snd >> (~-) ) |> Seq.take 10 // draw a chart: ( top10 |> Chart.Column ) .WithLegend()

      Apart from the statistics-induced angst, I really enjoyed the workshop and I really liked what I learned of F#. It's a very nice, clean language and if I was planning to work on .NET (or Mono!), it would be my language of choice. Huge kudos to Rachel for a fun, challenging and well-run workshop!

  • Keynote: Systems that Run Forever Self-Heal and Scale - Joe Armstrong
    • Wildly entertaining keynote from the creator of Erlang about the challenges behind creating highly available, highly scalable, complex systems of collaborating processes. Erlang, created back in the mid-80's, succeeds by running completely counter to most other languages in terms of how errors are handled: instead of coding defensively and trying to trap (and sometimes handle) every error you can think of, you just program the "happy path" and let your process fail fast when things go wrong. Because the Erlang virtual machine and process infrastructure is managing your graphs of linked processes, when a process fails, the system can quickly kill off and restart parts of the graph that experienced the failure.
  • Clojure Birds of a Feather
    • Despite avoiding Clojure during the day, I was drawn to this informal session in the evening because it was going to cover the newly released core.async library, inspired by channels and asynchronous blocks in the Go language. The real "wow" moment came from David Nolen as he showed a browser app that tracked keystrokes and mouse movements (as would be needed in a game), built using core.async and ClojureScript (compiled to JavaScript). The code was elegant and expressive - and needed no callbacks due to the way blocks can park and resume asynchronously!
  • Distributed Programming with Riak Core and Pipe - John Daily
    • Kicking off day two, I went to another Erlang talk. Unfortunately, since we'd already had the introduction and background in Tristan's talk, followed by Joe's deeper insight into the concepts behind Erlang, the first half of John's talk was a bit redundant and so he was just getting into the meat of the Riak Core library when his forty minutes ran out. I suspect Riak Core and Pipe would have been very interesting if John had just jumped in but he tried a bit too hard not to lose anyone in the material.
  • Semantics, Clarity, and Notation - Tracy Harms
    • This was an odd presentation. The session description sounded interesting albeit very conceptual but it was rather more navel-gazing than I had hoped. I don't think the choice of the J language (it's APL in ASCII - here's an example of J in action) helped Tracy's cause: J is certainly a very pure notation (I did APL back in the 80's so I appreciate the power and conciseness) but it appears like so much line noise that it really distracts from any talk that is intended to focus on clarity and meaning. In some ways, this talk represents the very worst in the FP world that puts a lot of people off: dense, academic and a very dry delivery, of something that has no obvious application to people's day to day work. And that's a real shame because I think the underlying message Tracy was trying to get across was a valuable one.
  • QuickCheck - Joseph Wayne Norton
    • With day two not going particularly well, I had lowered my expectations by the third session but was pleasantly surprised. I'm familiar with the concepts of QuickCheck but hadn't seen the Erlang version before. I didn't get much out of the session but it was a very well executed introduction to the principles and benefits of automated property-based testing - so it was exactly what it said on box, nicely delivered.
  • Workshop: Building Applications in Erlang - Garrett Smith
    • I'd made sure to install Erlang on my laptop, and got erlang-mode working in Emacs, and Garrett had confirmed on Twitter that was all I needed. Unfortunately, the workshop followed the E2 Project tutorial and I was using a Windows laptop and they don't really go well together so the first hour of the workshop was an exercise in frustration. Coupled with that, Garrett didn't really make things very interactive and said we could either type along or just watch so at that point I was pretty annoyed I'd spent $50 on this... but then I figured out how to get a reasonable workflow running on Windows (working around some shortcomings of "make" and "rebar", having to run "make shell" in a command window rather than rely on erlang-mode to run a shell, and using make:all([load]). manually). Once I'd conquered that, I was able to catch up and keep up with Garrett as he worked thru the tutorial and explained each piece of it. At the end of three hours, I had a database service running, and a telnet server linked to it, so I could connect in (via PuTTY!) and run GET key and PUT key value - all written in Erlang! Oh, and I had the application monitor up so I could randomly kill parts of the system and watch Erlang automatically restart processes! So, in the end, definitely worth $50, but I really would have liked it to be a lot more interactive.
  • Keynote: Programming for the Expression of Ideas - Gerald Sussman
    • Jerry is something else... You'll have to watch the video to get the full effect but the TL;DR version is that creating representations of models in code can shine a light on ambiguity and help you achieve clarity in the expression of concepts. As always, Sussman was provocative and insightful - but all that mathematical formula notation!! Ouch, my poor brain!
  • Functional Mobile Applications in F# - Adam Granicz
    • Day three and back to F#. Compiling to JavaScript is becoming pretty popular these days: CoffeeScript, TypeScript, ClojureScript. I learned that F# can also be compiled to JS, via FunScript or WebSharper. The latter is a (free) product offered by Adam's company but he soon overcame any marketing or commercial objections I might have to a potential product pitch. WebSharper provides automatic management of JS resource loading and type-safe integration with a number of JS libraries. Adam showed a couple of application examples that were F# all the way down but compiled to JS on the front end or .NET bytecode on the back end, with RPC calls as necessary between them. The approach is very clean, with a focus on composability. I'd already been sold on the idea of building mobile applications using JS/CSS rather than a native approach, but the simplicity and cleanliness of F# top-to-bottom was an eye-opener.
  • Protocols, Functors and Type Classes - Creighton Kirkendall
    • This was a fascinating talk about abstraction and extensibility, couched in a comparison of four languages - Clojure, Ocaml, Haskell and Scala. When you have a mismatch between a data format and a library, the OOP way is the wrap the data in a new object so the library can process it, but the FP way is to extend the library to support the data natively. Creighton showed how various functional languages provide a way to extend libraries to allow new types of data to be processed. In Clojure, we can use protocols, in other languages, other type-based solutions are available. It was very instructive to see the same overall approach in four languages and it really brought home the differences between OOP and FP. As an aside, I have more notes from this session than any other, over the three days, as I found the side-by-side language comparisons to be absolutely fascinating!
  • Journey to the Heart of For-Yield - Kelsey Innis
    • This was a wonderful presentation and quite unlike any of the others I attended: Kelsey started out with an assumption of an imperative approach to a basic problem and showed us an evolution of both expressiveness and concision along with complexity. We moved from a simple imperative loop to a simple for yield to nested loops to combinations of list and optional values. It was a very compelling argument for a functional approach. It was nice to see some of the new features in Scala 2.10, as well as seeing both "monads" and "applicative functors" slipped in quietly behind the scenes. Way to go, Kelsey!
  • Jam!
    • None of the day three workshops had really grabbed my attention so I planned to take part in the free programming "jam" session. Unfortunately, I was enjoying lunch a little too much and lost track of time so I was about half an hour late getting back to the hotel and missed too much of the background for the jam to feel like catching up. It looked like a lot of fun: everyone had broken up into small teams to solve a maze generation problem in various languages, with two algorithms on offer, and then several groups presented their solutions in the final section. As with Creighton's session, it was very interesting to see the same problem solved side-by-side in different languages.
  • Keynote: Everything I have Learned, I Learned from Someone Else - David Nolan
    • Closing out the conference, David showed us how much inspiration we as engineers can draw from research papers. David's probably most well-known for core.logic and his tireless work on ClojureScript. He talked about how core.logic came about, inspired by academic research, and what we can learn from the wealth of published research - especially when there opportunities to engineer real world software based on the solutions outlined in that research. It was a good way to finish off the three days!

Did Lambda Jam satisfy my goals? Yes, I learned quite a lot about Erlang and F# (through five sessions and two workshops), as well as a little more exposure to Haskell, Scala, and Scheme - and seeing J for the first time - and I also had fun socializing with people outside my usual community (particular kudos to the F# crowd who were awesome to hang out with on Tuesday!). Will I attend next year? Hell yeah! So a big thank you to Alex Miller for putting this together, along with The Strange Loop and Clojure/West!

Railo 4.2, Tomcat 7, Clojure - how simple could it

posted: 02 Jun 2013

Thanks to Shantanu Kumar, if you have Leiningen installed for Clojure development, creating a skeleton web application based on Railo 4.2.0 and Tomcat 7 that blends CFML and Clojure is as simple as running these commands:

  • lein new lein-servlet railo myapp
  • cd myapp
  • lein servlet run

At this point you have a mixed CFML/Clojure web application running on port 3000 and you'll be seeing the home page in your browser!

The first time you run the application, it will take a while to download all of the libraries, but once those are cached locally, it will start up pretty quickly.

Shantanu's Leiningen plugin doesn't use cfmljure so Clojure integration into CFML is fairly low-level but as a way to get a mixed CFML/Clojure environment up and running on the latest Railo release, this really can't be beat!

If you want to see these commands in action, here's a short screencast I recorded showing the whole process end-to-end (including my inability to type 'cd' correctly!). This is a 'first run' so you see the full download of all the Railo / Tomcat libraries but it will give you a flavor of the simplicity involved.

cf.Objective() 2013 - What I Learned

posted: 19 May 2013

It's Sunday afternoon after the best cf.Objective() ever and I'm looking over my notes to offer some thoughts on the last three days.

Before I get to the content, I first want to call out the location as being awesome! The brand new Radisson Blu had some of the friendliest and more helpful staff I've encountered at a hotel. The food for the conference was amazing: terrific hot breakfast every morning and a delicious lunch buffet too. Possibly the best conference food I've ever had. In the evenings, my wife and I dined in the Fire Lake restaurant at the hotel - the food was so good, we didn't want to go anywhere else! Great selection of local beer on tap too. The hotel itself has a very nice modern feel to it, with excellent facilities and big, well-equipped room. I hope everything works out behind the scenes so that this is a candidate location for next year.

A few weeks back, I blogged about the sessions I expected to attend and noted it was mostly going to be about JavaScript. In the end, I made a couple of changes to my planned schedule but still ended up going to a session in almost every single slot. This is rather unusual for me: at past CFML events I've often skipped a lot of sessions and just hung out chatting in the hallways. Last year, I manned the Railo booth and did not attend a single session (which was a little extreme) but normally I only attend one or two sessions a day. Here's out it played out this year...

Thursday

Despite my enthusiasm about the keynote, I got caught up in a post-breakfast conversation and by the time I got to the ballroom, the keynote was nearly over. Everyone I spoke to raved about how great it was and the TL;DR takeaway was: JavaScript is ubiquitous and you need to know it to build today's web apps.

Next up was my polyglot session where I showed prototype objects, callbacks and closures from JavaScript - and how to do that in CFML - then a little Groovy with code blocks - and how to do that in CFML - then a little Clojure with (infinite) lazy sequences and map, filter, reduce - and how to do that in CFML! My point was that now we have closures in ColdFusion 10 and Railo 4, we have access to these very powerful and expressive techniques we see in other languages, and we should leverage those concepts in CFML to create simpler, more maintainable - and more powerful - software.

Next was Ryan Anklam's "The Art Of JavaScript" presentation. He started out fairly gently showing some basic recommendations for safer code and then moved into some of the more subtle gotchas and traps for those of us new to JavaScript. I'd seen most of the points at some point in the past, spread across various blog posts and presentations I'd found online, but it all sunk in a little more this time and Ryan's presentation is an excellent collection of best practice "pro tips" that I'll bookmark and refer to often as I start to do more JavaScript.

After lunch, I skipped Adobe's general session and just hung out chatting with folks in the sponsor / vendor area. There seemed to be a steady stream of people leaving the general session and joining the throng in the hallway which didn't really bode well. Pretty much everyone I spoke to said that Adobe's presentation was aimed at IT managers, not developers, and there was a general sense of disappointment with the content. So, as expected, it was a marketing spiel and not a very exciting one at that, it seems.

Then I decided to go to Mark's "Top 10 Developer Features" in Railo. We're still on 3.3 at World Singles and this talk just made me more excited about upgrading to 4.1! Railo really are working hard to improve the language and make developers more productive.

My second session was well-attended, covering how Object-Relational Mapping breaks down because of a fundamental impedance mismatch between the object model and the relational model. I offerred that a document-based store, such as MongoDB, alleviates the mapping problems (and of course introduces other tradeoffs). I had a minor demo fail (and jokingly blamed it on Windows... when I later rebooted, the demo worked just fine without any other changes... no comment!). I was pleased to get so many questions from the audience and continued Q&A in the hallway after the talk for almost an hour and a half, missing the next session!

Friday

Kurt Wiersma's two hour deep five into AngularJS and Bootstrap was excellent! The high point of the conference for me. Kurt maintained a great pace and flow through the material and AngularJS itself is very slick. If you missed his talk, make sure you track down his slide deck after the conference! Highlights for me included dependency injection, two-way data binding, built-in support for testing / testability, and directives (UI components that are invoked like custom tags).

Scott Stroz entertained us immensely with a look at Groovy and Grails and what he likes about it, as well as how it's made him a better CFML developer (because now he has been exposed to more advanced techniques from another language). Rakshith from Adobe was in the front row and Scott ragged on him quite a bit when he was comparing feature after feature to ColdFusion and showing where Groovy was better. It wasn't helped by some people in the audience (yes, including me) pointing out that Railo already has some of these features from Groovy, that ColdFusion is missing!

After lunch, I attended Railo's general session and ended sat between Rakshith and a very sickly-sounding Dave Ferguson (there seemed to be a lot of illness in the attendees this year - including Elliott Sprehn losing his voice so badly he had to cancel his talk). Again, a barrage of great CFML language features (making me even more determined to upgrade!), as well as a sneak peek at a new monitoring tool (from one of Railo's investors) that will show cflock times / failures, mails sent, query information etc all down to the page template, tag, line number. There will be both a free version and a commercial version. Sean Shroeder from Blue River / Mura CMS took the stage to talk about the Open CFML Foundation which is working to spread the word about CFML and some of its open source projects outside the CFML community, as well as working on an "academy" for teaching new developers about CFML. It all looked very exciting and I think a lot of attendees will be taking a serious look at Railo after this.

I decided to attend Dave Ferguson's SQL skills / performance talk which covered some ground I already knew and a lot of ground that I wasn't aware of, including a lot of the internal machinery around query plans and how they are cached and reused. Great material!

Finally it was my Humongous MongoDB session where I showed how to set up a replica set live and how to create a sharded cluster live. I also covered the concepts of write concern and read preference, and touched on both map/reduce and the built-in aggregation framework as examples of dealing with complex queries on very large data sets. The talk ran long but almost everyone stayed to the end, with plenty of questions about MongoDB at scale in production.

Due to the fabulous food at the Fire Lake restaurant, I lost track of time and was late to the BOF I was supposed to be hosting. Luckily Kris Korsmo had stepped up a while back to co-host and was holding down the fort until I arrived. Great discussions about test-driven development, continuous integration, Git workflows, deployment strategies, automation, bug tracking and so on. I got the impression that the biggest obstacle for most CFML developers is some mentoring on how to get started down this path. One problem is that a lot of this material is extremely well-documented but CFML developers often don't seem comfortable reading outside their community and want a CF-specific version created (which I find very frustrating - stop being afraid of looking at other language websites!)

Saturday

Brad Wood kicked off the day with a talk about Backbone.js and Underscore for templating. After Kurt's AngularJS talk, I found this a bit scrappy and the code examples looked rather disorganized and hackish - but it was pointed out to me by several people that Backbone is "just" a library and doesn't set up a framework of best practices in the way that AngularJS does.

I took a break from sessions to meet with a couple of attendees to talk in more depth about MongoDB and I rejoined the sessions shortly into Tony Garcia's coverage of the D3 visualization library for JavaScript. It's a very impressive piece of technology and some of the examples really wowed the audience. It's always educational to see just what can be accomplished in the browser with JavaScript!

Brad Wood's second talk of the day with about the benefits of Agile software lifecycles. I think he did an excellent job contrasting traditional software development with Scrum and Kanban and explaining the principles behind high-quality, iterative software delivery. One of the best talks of the conference!

Closing out the conference was Ryan Anklam, covering AMD and RequireJS which was something I'd never heard of before but turned out to be a very interesting way to tackle large project development in JavaScript and how to manage reusability and dependency management. He also showed us a little of what's coming in this area in the next version of JavaScript (Harmony).

And then Jared was thanking everyone for attending, speaking, sponsoring and organizing, and it was all over until 2014!

If you were there and we got to hang out, it was great to see you! If you were there and we didn't get to hang out, sorry, it's always difficult to make contact with everyone. If you weren't there, well you missed out on a great conference and a lot of terrific content...

Humongous MongoDB - cf.Objective() 2013 - Slides a

posted: 18 May 2013

The slides and code for my third presentation at cf.Objective() 2013 are now online:

ORM, NoSQL and Vietnam - cf.Objective() 2013 - Sli

posted: 16 May 2013

The slides and code for my second presentation at cf.Objective() 2013 are now online:

Updated with the correct PDF link - sorry about that!

Learn You a What for Great Good - cf.Objective() 2

posted: 16 May 2013

The slides and code for my first presentation at cf.Objective() 2013 are now online - Polyglot Lessons to Improve Your CFML:

The other presentations will be posted after I've given them and the code will appear in that Github repository.

New Relic and CFML

posted: 14 May 2013

A while back I blogged about how we instrumented our Clojure code to show up in New Relic traces and we also did some stuff in CFML to get better data out of New Relic. Just now Joe Swenson asked on Twitter how to get CFML page names to show up in New Relic so I figured I'd blog a quick note about that.

You should already be starting up your servlet container with the -javaagent: option if you're using New Relic for monitoring your web app (and indeed New Relic has documentation about adding the Java agent to ColdFusion). That means you'll have the New Relic JAR on your classpath and so you can instantiate the New Relic agent API class in your CFML code. We do this at application startup:

application.NewRelic = createObject( "java", "com.newrelic.api.agent.NewRelic" );

Then at the start of each request, we do something like this:

if ( structKeyExists( application, "NewRelic" ) ) {
application.NewRelic.setTransactionName( "CFML", CGI.SCRIPT_NAME );
}

The first argument is a 'category' name and is currently ignored by the New Relic API (and you can pass null if you want). The second argument is how you want this web transaction reported in the New Relic traces. We actually just use a fake path to represent groups of requests since we have a lot of internal instrumentation (in Clojure) and that gives us better data about where time is being spent in the code.

clojure.java.jdbc 0.3.0 alpha 4

posted: 13 May 2013

A month ago I posted that java.jdbc 0.3.0 alpha 1 was available for testing and since then I've made a few more alpha releases as the API and code settles down so I figured it was time to blog about the recent changes.

  • Release 0.3.0-alpha4 on 2013-05-11
    • Fix connection leaks JDBC-54
    • Allow order-by to accept empty sequence (and return empty string)
  • Release 0.3.0-alpha3 on 2013-05-04
    • Fix macro / import interaction by fully qualifying Connection type.
  • Release 0.3.0-alpha2 on 2013-05-03
    • Address JDBC-51 by declaring get-connection returns java.sql.Connection
    • Add IResultSetReadColumn protocol extension point for custom read conversions JDBC-46
    • Add :multi? to execute! so it can be used for repeated operations JDBC-52
    • Reverted specialized handling of NULL values (reopens JDBC-40)
    • Rename :as-arrays to :as-arrays? since it is boolean
    • Add curried version of clojure.java.jdbc.sql/as-quoted-str
    • Officially deprecate resultset-seq

As you can see, quite a few things changed in alpha 2, including a parameter name change (a breaking change to something introduced in alpha 1). Alpha 3 fixed a problem that made alpha 2 unusable for some people (due to a macro expansion quirk). Alpha 4 actually has some fairly extensive code changes - around connection leaks - although there is only one actually API change: order-by can now accept an empty sequence which is very convenient when you're constructing your query operations dynamically, as we do at World Singles in several places.

The alpha 4 changes around connection handling is something I'd like to see get some fairly extensive testing out there in the real world - so I'd appreciate anyone who can find the time to exercise the new API in a heavy load environment!

What's coming in future alpha / beta releases? Before the first beta, I want to deprecate a few more things that still rely on the dynamic *db* variable (specifically create-table and drop-table) and add new API versions that accept the DB spec as an argument, or offer up a consistent way to handle DDL commands, perhaps by adding some more create-*-ddl functions? So there will be at least one more alpha, maybe two. The first beta will represent a stable API and "feature complete" - and a shift to bug fixing.

You can see currently open issues for java.jdbc on JIRA.

My cf.Objective() 2013 Presentations

posted: 12 May 2013

Other than noting back in January that all three(!) of my talk proposals were accepted, I haven't blogged about them since, so the only information about them is on the cf.Objective() web site. The session overviews give a fair sense of what you should get out of each presentation and roughly what they'll cover.

Since I have just now finished the three presentations and got all the code working, I thought I'd write up some thoughts about the talks, to help folks who are on the fence decide 'for' or 'against'.

  • Learn You a What for Great Good?, subtitled Polyglot Lessons to Improve Your CFML, this talk looks at some idioms and constructs in JavaScript, Groovy and Clojure (with a brief mention of Scala too), and shows how you can apply them to CFML. A common thread thru the examples is closures, added in ColdFusion 10 and Railo 4, and the code examples make heavy use of them, showing map, reduce, and filter functions operating on CFML arrays and structs to provide many of the benefits that collections have been providing to other languages for quite some time. From JavaScript, I also look at prototype-based objects, and show how to implement that in CFML.
  • ORM, NoSQL, and Vietnam plays on blog posts by Ted Neward and Jeff Atwood to put Object-Relational Mapping under the microscope and look at where the mapping breaks down and how it can "leak" into your code, making your life harder. After that I take a quick walk thru the general "No-SQL" space and then focus on document-based data stores as a good (better?) match for OOP and provide examples based on MongoDB and cfmongodb, with a quick look at how common SQL idioms play out in that world.
  • Humongous MongoDB looks at replica sets, sharding, read preference, write concern, map/reduce and the aggregation framework, to show how MongoDB can scale out to support true "Big Data". The talk will feature a live demo of setting up a replica set and using it from CFML, including coping robustly with failover, and a live demo of setting up a sharded cluster (and using it from CFML) to show how MongoDB handles extremely large data sets in a fairly simple, robust manner.

At the start of each of my talks, I have a "You Might Prefer..." slide listing the alternative talks you can attend if you don't fancy mine after you've seen the agenda slide - I won't be offended!

The slides (and all code) will be available after the conference. I'll post the slides to my presentations page and the code will go up on my Github repository. If any user groups would like me to do remote presentations of these talks later in the year (and record them and post them to Charlie Arehart's UGTV site), just contact me to figure out dates and times.