Immutable Objects in ColdFusion

Tuesday, February 1, 2011


What are immutable objects?



If this concept seems strange, consider these ideas:
  2. Immutable objects are inherently thread safe. [BLOCH]
    • They can be shared freely.

What does this look like?



component name="ImmutableExpression" {


public ImmutableExpression function init(required String expression) {
   rawExpression = expression;

     evaluatedExpression = evaluate(expression);
   catch(Expression e){
     throw( type="InvalidExpressionException",
   return this;



A unit test for the constructor could look something like:

component extends=“mxunit.framework.TestCase” {

 function twoExpressionsShouldNotBeTheSame(){
      exp1 = new ImmutableExpression( “3^3” );
      exp2 = new ImmutableExpression( “4*2” );
      assertNotSame( exp1, exp2 );

* @expectedException InvalidExpressionException
 function badExpressionShouldBeKickedOut(){
   exp1 = new ImmutableExpression( “1*b” );


Let’s make this a little more interesting ...


exp1 = new ImmutableExpression( “3^3” );
  exp2 = new ImmutableExpression( “4*2” );
  exp3 = exp1.add(exp2) ;


The implementation is straight forward:

public ImmutableExpression function add (ImmutableExpression exp){




 myComponentType = “sandbox.mutability.ImmutableExpression”;
 private void function ensureInstanceType(){
    if ( getMetaData(this).fullName != myComponentType )
     throw ( type=“InheritanceViolationException”,

Wrap up


Functional Programming


ColdFusion Functional Programming Example:

Full source code:

Josh Bloch, Effective Java

Barbara Liskov, Program Development in Java

♫ Inspiration
Bill Evans

bill shelton


Raymond Camden said...

Mark - interesting post! Two small comments that are not really on topic. In your initial CFC you have:

public ImmutableExpression function init(required String expression) {

if( !structKeyExists(arguments,"expression") ) {

Why do you check for expression? Your method argument signature explicitly sets expression as required. Afaik, your IF there will never run.

Second: Why the toString here:

Since the argument is required to be a string, what purpose does the toString provide?

Raymond Camden said...

Sorry Bill - thought this was Marc.

bill shelton said...

Thanks for the comments, Ray.

You're absolutely correct on both points. I added "required" more as an afterthought. The original code was simply "init(expression)". And the toString() is redundant for the same reason. Good eye!


coldfusion said...

I had the same thoughts as Mr. Camden. That aside, what you want to say can be summarised as:
1. Strings are immutable (they will be discarded when reference changes but never overwritten)
2. Send in valid expressions as Strings as argument parameters,
3. do not allow manipulation (i.e. no Setters)

I think you made a mountain of a mole hill. I cannot see any great application of this. And I wasted time trying to understand the point you were making (besides the 3 points above).

You could have just blogged those 3 points!

bill shelton said...

Anonymous "coldfusion",

Your comments attempt to dismiss an important concept in software (see Liskov and Bloch references for starters). Perhaps, you should dig a little deeper ...


Raymond Camden said...

@coldfusion: Frankly I don't see the point of your comment. You are complaining that they explained something well? Did you really waste _that_ much time? Printed out this is probably a two page blog entry which is approx. 4 minutes of reading. While it may be an easy concept for you, others will appreciate the detail. I did.