The average person's short-term memory capacity is commonly believed to be around seven items.
This idea was first proposed by psychologist George Miller in a 1956 paper titled, "The Magical Number Seven, Plus or Minus Two: Some Limits on Our Capacity for Processing Information." Miller argued that people can typically hold between five and nine items in their short-term memory. Subsequent studies have confirmed the phenomenon.
While the exact number of items that can be retained varies from study to study, the number seven is a useful benchmark. It will more than suffice for our purposes here.
Given this well-known human constraint, I present the Rule of Seven:
The Rule of Seven
Never try to juggle more than seven mental balls.
Imagine you're a juggler and each item you want to commit to memory is a ball.
- Balls must be added slowly, one at a time
- The slightest distraction can make you drop every ball
- Most people can only juggle seven balls at a time
- Even the best jugglers can only juggle nine balls
That last point is critical. It leads to the following corollary to the Rule of Seven:
To become a better programmer, don't try to increase the number of balls you can keep in the air; instead, reduce the number of balls needed to follow your software's logic.
Reducing Complexity by Removing Balls
So what concepts represent mental balls in programming?
Here's a partial list of items. The more you can reduce the number of items in effect at any given time, the simpler your software will be:
- Global variables
- Nested code blocks
- Call stack depth
- Side effects
- Handled events
- Queries (and other out-of-context items)
- Form timers
Let's discuss these briefly in further detail.
Remember, you can't keep track of seven items in each category; you can only keep track of seven items total.
The cost of using a global variable in a procedure is not one ball–it is one ball for every other reference to that global variable.
Nested Code Blocks
Every code block–or level of indenting–represents another ball. If your code is indented three levels, then you need to be aware that (for example):
- You are currently inside of a loop–what are the loop conditions?
- The loop is inside an Else block–what was the original If condition?
- The If...Else block is inside a With statement–what is the With'ed object?
Call Stack Depth
Each time you call a Function or Sub from inside another Function or Sub it adds another level to the "call stack." And another mental ball to juggle.
Any time your code relies on something outside of its control–e.g., user input, a database value, etc.–it introduces another mental ball to keep in the air.
If your code generates a side effect, you need to be aware of how that will impact subsequent code. When possible, you should strive to create idempotent Functions. Fewer side effects equals fewer balls to juggle. By the way, if you are changing a global variable in your code, that's a side effect.
The challenge with handling events is that you often have little control over how or when they get triggered. A user could click buttons in an order you didn't anticipate, close or open forms or reports in unexpected ways, etc. Every event that could trigger and affect your code is another mental ball to juggle.
Queries (and other out-of-context items)
For this bullet point, I'm referring to saved query definitions that you execute or reference in code. Because the SQL is not embedded in the code, you need to mentally load the contents of that query while working in VBA. Any time you have to switch contexts from code to something else, it's another ball to keep in the air.
Form timers are a simple way to write asynchronous code in Access in much the same way that dynamite is a simple way to dig a hole: it gets the job done with very little effort (or control) and there's a very good chance you'll end up blowing yourself up. They're a handy tool to have around for those special occasions where nothing else will work, but they should never be your first choice.
Effective Ball Count
I don't want to give the impression that you should not use code blocks or that you should not handle any events.
Think of the "effective ball count" as the number of mental balls you need to be juggling at any given time. There are two primary ways to reduce the "effective ball count:"
- Reduce complexity
- Isolate complexity
A Few Ways to Reduce Complexity
- Reduce nesting levels via guard clauses.
- Avoid the use of global variables unless warranted.
- Avoid context switching.
A Few Ways to Isolate Complexity
- Don't mix value retrieval (e.g., via user input or database lookup) with calculations in the same procedure.
- Use class modules to encapsulate complex code.
- Handle recurring challenges with reusable code.