Programming Strategically

Thomas LaToza
6 min readSep 4, 2020

--

Programs for Programming

I just built a way to add recipes to my app. I clicked Add Recipe at the bottom. But the recipe isn’t added. I implemented it. But it just doesn’t work. It’s broken. Dear reader, I need help!!? I’m frustrated, and I’m stuck… How can I fix this????

If you still happen to be reading (what crazy and presumptuous author asks for help in the first paragraph of a blog post??), you might object, you have no idea what’s going on here. Tell me more: what language, what framework, how is the button supposed to work, how sure are you you’re using these APIs correctly?

Or perhaps you might suggest something like this:

Identify the erroneous program output
Verify that the erroneous output is erroneous
Set output to the line producing the erroneous output
Define a manual procedure verify given a line l
Verify l
If l is invalid, halt (defect discovered)
Otherwise
Set D to the dynamic control and data dependencies of l
For each dependency d in D, verify(d)
verify(output)
Photo by John T on Unsplash

Strategies exist as problem solving mechanics, connecting problems to solutions. Psychologists studying problem solving have long compared problem solving to navigating a maze: you start at the beginning, choose which path to follow, and backtrack when it doesn’t work.

Strategies are solutions for navigating the maze, helping chart a path out.

As an experienced developer, I can use my knowledge of how I expect things to work to make choices about which path to take. Looking at code, I can decide that, given that I know that this error really shouldn’t be happening in this case and something else must be really wrong, maybe I should go check if the server itself is down or my dependency has the wrong version.

But this reasoning all seems a little abstract. Psychologists and management scientists differentiate knowledge between tacit knowledge and explicit knowledge. Whenever you tie your shoes without thinking, that’s tacit knowledge. When you slowly explain the steps of how to do it to your five-year old, that’s explicit knowledge.

Photo by Pankaj Patel on Unsplash

So what about a strategy to debug a CSS issue in your web app? Or resolve a race condition in a C program? Or find the right hyperparameters to make your TensorFlow model work? If you’ve done each of these a thousand times, you might think, no big deal, what’s the problem? But as soon as you step out of your comfort zone, try a new framework or a new language, work in a new codebase, or find an issue that’s just weird, what seemed simple before may no longer be. In these cases, wouldn’t it be great to know just what tricks to apply when?

To learn a new strategy, we need a way to take everyday programming habits and make them explicit.

So what is a strategy? Well, a strategy asks you to make observations about the world, and based on what you find, do other things. Sometimes you might need to remember some things for later (which method fires that event again?). Or maybe there’s something you need to do until something works right or do for every instance.

Does any of this sound familiar?

A natural way to represent a strategy is as a program. But unlike the program running the browser in front of you, this program isn’t running on a microprocessor. It’s running in your brain.

So why not just write it as a program? Once it’s a program, it’s possible to build programming environments, for a strategy. Your environment might help you be systematic and go step by step through the strategy and to remember things you might forget:

Want to try this yourself? Try out a strategy to fix merge conflicts here. Or a debugging strategy here.

A strategy has parameters and variables. It’s not an answer, but a way to create answers. Good strategies work in many different situations. Strategies describe how to go out and get information and, depending on what is discovered, offer different paths forward.

Following an explicit strategy can make your work more organized, systematic, and predictable and help you be more successful. In prescribing what to do, it can also be more constraining.

Some strategies have their own proponents and have achieved fame. You’ve probably seen this strategy before:

STRATEGY testDrivenDevelopment(requirements)
# The first step in test-driven development is enumerating all of
# the user scenarios.You want to ensure that you enumerate
# specific requirements that are focused and small
# and can be described in a sentence or less. You should try to
# find all of the user scenarios which might exist.
# You should separate each scenario with a comma.

SET
'scenarios' to be short descriptions of the testable user
scenarios in requirements
FOR EACH 'scenario' IN 'scenarios'
Create a new test for scenario

# Check that the new test demonstrates that the scenario is not
# yet implemented by checking that it does not pass
UNTIL the new test does not pass
Fix the new test so that it does not pass

# Make it work
Implement the code to make the test pass
Run the tests
UNTIL all of the tests pass
Edit the code to address the test failure
Run the tests
# Make it right
# Look to see if there any issues that make the design less
# than ideal.
SET 'designIssue' TO be an unaddressed design issue if any or
nothing otherwise
UNTIL 'designIssue' is nothing
Edit the code to fix the design issue
Run the tests
SET 'designIssue' TO be an unaddressed design issue if any or
nothing otherwise
# Make it fast
# Look to see if there any performance issues that might cause
# it to be slow in some circumstances
SET 'perfIssue' TO be an unaddressed performance issue if any
or nothing otherwise
UNTIL 'perfIssue' is nothing
Edit the code to fix the performance issue
Run the tests
SET 'perfIssue' TO be an unaddressed performance issue if
any or nothing otherwise

(If not, go read this book!)

Strategies, written less formally, are everywhere. How can you work with flex-box containers?

Or you could try this instead

There’s often more than one strategy you might use to solve a problem. And, depending on which you choose, your work may be harder. Or easier.

So how do you solve problems? Given all these choices, which you pick? Do you tinker? Or read lots of docs? Find out, see how you compare to others, and help scientists learn more about programming strategies by answering a few questions.

This is part of a National Science Foundation sponsored project by researchers at George Mason University and the University of Washington to explore the nature of programming strategies.

You can read more here:

Thomas D. LaToza, Maryam Arab, Dastyni Loksa, and Amy J. Ko. (2020). Explicit programming strategies. Empirical Software Engineering (ESE), 25, 2416–2449.

--

--