Strawberries 11: The Power of Intention
Can we make our programming life immediately easier with this one simple trick? The answer may surprise you.
Express Intention
Our story: create a scene for our game where our daydreaming adventurer meets a tiny wandering knight.
Instead of coding these things out longhand, first:
Express our intention:
function createScene()
Scene = craft.scene()
createDaydreamingAdventurer()
createWanderingKnight()
end
Wow, we’re nearly done! We just have to write a couple of functions.
When we work this way, we tend to generate small functions (or methods) with meaningful names, containing code that’s focused on a single issue. This is a good thing.
Try to begin by expressing intention. Create small functions implementing our intention.
Failing That: Extract Intention
Sometimes, especially when I’m following something I found on the web, or copying and pasting, I wind up creating code that does one thing after another all in a row:
function setup()
scene = craft.scene()
Adventurer = scene:entity()
Adventurer.model = craft.model(asset.builtin.Blocky_Characters.Adventurer)
Adventurer.scale = vec3(1,1,1)/8
Adventurer.y = -1
Adventurer.eulerAngles = vec3(0,0,0)
Wanderer = scene:entity()
Wanderer.model = craft.model(asset.builtin.CastleKit.knightRed_obj)
Wanderer.scale = vec3(1,1,1)/8
Wanderer.y = -1
Wanderer.eulerAngles = vec3(0,0,0)
end
This works but won’t be easy to read. Make it express the intention, after the fact, by extracting functions or methods, one at a time:
function setup()
scene = craft.scene()
createAdventurer() -- <---
Wanderer = scene:entity()
Wanderer.model = craft.model(asset.builtin.CastleKit.knightRed_obj)
Wanderer.scale = vec3(1,1,1)/8
Wanderer.y = -1
Wanderer.eulerAngles = vec3(0,0,0)
end
function createAdventurer()
Adventurer = scene:entity()
Adventurer.model = craft.model(asset.builtin.Blocky_Characters.Adventurer)
Adventurer.scale = vec3(1,1,1)/8
Adventurer.y = -1
Adventurer.eulerAngles = vec3(0,0,0)
end
It just takes seconds to do this. Repeat once more to get this:
function setup()
scene = craft:scene()
createAdventurer()
createWanderer()
end
function createAdventurer()
Adventurer = scene:entity()
Adventurer.model = craft.model(asset.builtin.Blocky_Characters.Adventurer)
Adventurer.scale = vec3(1,1,1)/8
Adventurer.y = -1
Adventurer.eulerAngles = vec3(0,0,0)
end
function createWanderer()
Wanderer = scene:entity()
Wanderer.model = craft.model(asset.builtin.CastleKit.knightRed_obj)
Wanderer.scale = vec3(1,1,1)/8
Wanderer.y = -1
Wanderer.eulerAngles = vec3(0,0,0)
end
Now our code is as expressive as if we had done it by intention to begin with.
When a patch of code contains more than one idea, extract each idea into its own function, with its name expressing the intention of that section.
TL:DR: Go Faster With Intention
Ideally, we try to begin by expressing our intention in code, calling a series of sensible functions that accumulate to do the job. Then we write each function, perhaps by expressing more detailed intentions, or, finally, by writing the basic code needed.
When we write or discover code that contains sections of code with different intentions all in one function, quickly extract each section, giving it a meaningful name.
When we work this way, we produce code that is easier to write, easier to understand, easier to reuse, and easier to change. In the first case we immediately go faster. The second case, where we extract the functions after the fact, just takes moments and will pay off in speed the next time we pass this way.
For best speed, always express intention.