Dynamically Define For-Loop Increment In ColdFusion
In my Lopem Ipsum generator, I take a collection of paragraphs and I split them up into sections of random lengths. To do this, I iterate over the collection using a dynamically defined increment. In other words, the "step" value is randomly assigned on every for
-loop iteration. I don't think I've ever done this before; and it worked like a charm. So, I thought it was a mechanic worth sharing in ColdFusion.
Usually, when I'm using a for
-loop, the increment value is hard-coded in the loop signature. For example, if I wanted to loop over 10
with an increment of 2
, the 2
is hard-coded:
for ( var i = 0 ; i <= 10 ; i += 2 )
But, the segments of the for
-loop are all optional—they're just expressions that get evaluated at different parts of the loop life-cycle. And, if they're empty, they're essentially no-ops.
For example, this is a valid for
-loop which will run forever:
for ( ;; )
And, this is a valid for
-loop with no initializer:
for ( ; i < 100 ; i++ )
Which means, there's no reason that the increment expression (ex, i++
or i+=2
) has to be hard-coded. It can consume other dynamic values—values that can be defined within the loop body itself thanks to the magic of hosting!
To demonstrate, here's both ColdFusion and JavaScript code that iterates over the letter range a-z
using random steps:
<!--- ColdFusion mechanics. --->
<cfscript>
(() => {
var fromAscii = asc( "a" );
var toAscii = asc( "z" );
for ( var i = fromAscii ; i <= toAscii ; i += step /* VARIABLE */ ) {
echo( chr( i ) & " " );
// Randomly define the next for-loop increment.
// --
// Note: the step variable is hoisted to the top of the Function and is
// available for consumption in the for-loop mechanics. This is a feature of
// the language, not a bug. Hosting is aces!
var step = randRange( 1, 8 );
}
})();
</cfscript>
<!--- JavaScript mechanics. --->
<script type="text/javascript">
(() => {
var fromAscii = "a".charCodeAt();
var toAscii = "z".charCodeAt();
for ( var i = fromAscii ; i <= toAscii ; i += step /* VARIABLE */ ) {
console.log( String.fromCharCode( i ) );
var step = ( 1 + Math.floor( Math.random() * 8 ) );
}
})();
</script>
And, when we run this, we get a random set of letters generated by ColdFusion:
a d k m o t y
... and a random set of letters logged to the console by JavaScript:
a d e i k q r y
Obviously, this technique doesn't make sense for most for
-loops. But, it's great to have it as an option. And now that it's marinating in the back of my mind, I'm sure I'll come up with other use-cases for it.
Hoisting Is a Feature Not a Bug
The code above works because the var step
declaration is hoisted to the top of the Function and made available to the for
-loop. This is an amazing feature of many languages; and, is key to making code look nicer and read in a top-down manner.
It's also a good reason to use var
instead of let
or const
—both of which will break the JavaScript code example.
If anyone has ever tried to tell you that hoisting is dangerous, they have misguided you. Hoisting is awesome! It's the reason that you can invoke functions that are defined farther down on the page. Without hoisting, you'd have to read all code from the bottom-up.
Want to use code from this post? Check out the license.
Reader Comments
Today I got a twofer...I also learned that let and const will not hoist! Pretty sure I've scratched my head more than once wondering why my js code didn't hoist as expected in the past!
@Chris,
I know I'm in the tiny minority here; but, I think
var
is just groovy and works really well.@Ben Nadel,
I clearly don't understand the nuances well enough, but
var
isn't worth giving up for this one feature alone IMHO! And this comes from someone who has usedlet
andconst
plenty, but not because I had a deep understanding of them, but rather because I 'assumed' they were better options. Why else would they add them? 🤓@Chris,
If
let
andconst
work for you, no reason to change. I likevar
because it works for me and doesn't cause any problems. So, it's just one less thing to think about.Post A Comment — ❤️ I'd Love To Hear From You! ❤️
Post a Comment →