Today I am going to introduce something I will call an “Action Pattern”. A quick google search indicates that this idea already exists, as either an “Action Pattern”, or a “Command Pattern”, but my specific take will dramatically simplify what is going on.
Backstory: Rediscovering Goto!
A few months ago, I went on a deep dive to rediscover the lost art of gotos. I discovered that while structured programming commonly rejects gotos, there are good cases where they make sense. Fortunately, there are simple ways to, in effect emulate goto, without any fancy trappings, in any modern language.
To understand how to imitate goto, we must talk about pancakes. Pancakes are both yummy and easy to make, and we smear sugar on top to make them taste good. Well today, instead of making some of these good ol’ flapjacks, we are going to introduce you to flat-stacks.
At its heart, a goto is simply headfirst and blindly discarding your call stack.
The secret to a good goto, is to avoid building up your call stack in the first place, going, in effect, “stackless”
I have found this is the best way to imitate gotos in modern languages. Simply keep your call stack as flat as possible, and you are essentially imitating a goto. This is much simpler than try/catch statements, which throw a “goto exception”, to break the flow of contol(goto and error handling are fundamentally connected).
Gotos are great for finite state machine replacement (think of menus on kitchen and laundry room appliances). Gotos also have the benefit of actually simplifying flow of control, such that it makes it easy to analyze in diagrams. In fact, state analysis and not flow of control, is why most people avoid gotos, as you no longer can predict so easily how state will evolve when you chain the parts of your program together through arbitrary flows and cycles. Meanwhile, the graph of flow of control is actually simplified with gotos.
Why use this at all?
While many may push “no-code” solutions, I am offering the exact opposite alternative: “no-computer, yes code”, solutions.
This means you can use analysis of algorithms and "Big Oh” to help you measure how fast you can complete tasks like doing the dishes. No computer solutions have the added benefit of teaching you to appreciate the computer, and follow disciplined practices in real life.
So someone familiar with “no computer” solutions, will be much more judicious and discerning about what they decide to type into the machine.
What does this “Action” pattern look like?
Pretend we are writing the video game “snake”
// snake actions
function action(act){
console.log(`You performed '${act}'`);
if(act == "left"){
// handle turning left
}
if(act == "right"){
// handle turning right
}
if(act == "forward"){
// go forward
}
}
let a = goLeft = ()=>action('left');
let b = goRight = ()=>action('right');
let c = goForward = ()=>action('forward');
let queue = [a, a, c, a, c, b, c];
setInterval(()=> {
(queue.shift())(); refresh(); }, 1000);
The important question is, why use this pattern at all? Why not just write different functions for every action?
To finish the example you just need to determine what state you need to track, and how it gets updated and/or presented. We will cover this in a future article.
Benefits of this action pattern
This action pattern allows you to easily organize code without using objects, and perform common bookkeeping or updating tasks on every action. In our example, we queued up a simulation, and simply logged each action to the console. But you could easily do more complex tasks like recording what actions were perfomed, sending the actions over a wire, and getting updates back, and many more possibilities.
Conclusion
We demonstrated a simple pattern for writing user interfaces. Unlike many framework based patterns like Redux, this simplified pattern requires no dependencies.
The more modern javascript becomes, the more powerful the base language can be, without any frameworks or libraries. Many complex tools and libraries can be avoided, simply by understanding async/await/promises, lambdas, or template string literals.
This will undoubtedly be a topic we go over in depth in the future. For now, I would recommend Chris De Leon founder of Home Team Game Dev cocoding snake in 5 minutes, to get a better idea of how one might hack together the other parts for this example.
Thanks for reading, and I would really recommend checking out his content and Chris’s business model as well.