Tell A Story To Write Better Code

Written by Ben Wendt

Programming could be described as the process of giving a computer instructions. There are many ways to write programs that have within some tolerance the same function. Because of this arguments and philosophies arise as to what way code should be written. When starting out a lot of folks tend try to “golf” their code, make it as short as possible, while others may aim for best performance. I’m of the opinion that code should be written (given a certain functionality) as a document that communicates both the intent of the author and the functionality of the program.

My favorite technique for this is to have your code tell a story. My old boss Jack Neto advocated for this at an old job at a company that no longer exists, but I’m quite sure I had heard about it before then.

The idea is start with a function body that is essentially a script of your procedure. Fill it with nothing but function signatures of steps that will happen in that procedure. By reading this function, you’ll see exactly what the program does. You can iterate this so that the called functions are also little “scripts” of steps given by function calls, but eventually you get down to the level of granularity where the function bodies are short definitions of functionality.

The technique ends with a very readable and maintainable product, with the added bonus of making the writing process easier, testing easier, and it’s more fun. My favorite part about this technique is that you can spend a long time writing code, then go click run and generally just have a few minor things to fix up and it works.

Let’s look at some examples.

First I will preface with some versions of bad code to illustrate why this is a useful technique.

Imagine you asked a GPT to write a program to have your robot take your dog for a walk. It might write something like this:


def take_dog_for_walk(path, robot, dog):
    """Walk a dog and pick up poop."""
    # Traverse the path
    for waypoint in path:

        # go to the next waypoint
        while not robot.at_location(waypoint):

            # move along vector
            robot.step_in_direction((waypoint.x - position.x, waypoint.y - position.y))

            # use vision to detect poop
            if dog.pooping:
                while dog.pooping:
                    # a short delay
                    sleep 1

                # look at the poop and pick it up
                target = robot.locate_object(POOP, dog.position)
                robot.pick_up_object(target)

                # set boolean to true.
                robot.holding_poop = True

    # dispose of poop if necessary.
    if robot.holding_poop:
        robot.dispose_waste()

…Or something like that. It tends to write things very procedurally in one big function with lots of comments. Basically it’s the coding style that books have been written warning against, and many developers have always spent their careers fighting against.

Now lets rewrite it as a story.


def walk_dog(robot, dog, path):
    for waypoint in path:
        walk_dog_to_point(robot, dog, waypoint)
    dispose_poop(robot)

def walk_dog_to_point(robot, dog, waypoint):
    while not robot.at_location(waypoint):
        move_toward(robot, waypoint)
        wait_for_dog_if_needed(robot, dog)
        pickup_poop_if_needed(robot, dog)

This part of the code is super readable. All it does is tell the story of the walk. You barely have to understand python to understand this. This code is naturally decomposed, and has single responsibility.

Another great thing is if you want to use an LLM, you’ll now have a better outcome because something like co-pilot can often take the function signature and guess at the body of the function. You’ll of course have to verify that it’s right, but it’s a smaller piece and more logically coherent so that should be easier.

Let’s fill in the mock implementations of these functions based on the earlier silly code to fill in the details.

def move_toward(robot, waypoint):
    robot.step_in_direction((waypoint.x - position.x, waypoint.y - position.y))

def wait_for_dog_if_needed(robot, dog):
    if dog.pooping:
        while dog.pooping:
            sleep 1

def pickup_poop_if_needed(robot, dog):
    target = robot.locate_object(POOP, dog.position)
    if target:
        robot.pick_up_object(target)
        robot.holding_poop = True

def dispose_poop(robot)
    if robot.holding_poop():
        robot.dispose_waste()

Another added bonus is these smaller functions are naturally easier to unit test.

There’s a maxim in computer science “code is read more than it’s written”. One of my professors in university said to comment your code because often it will be you who doesn’t remember how it works.

In my experience if you write code as a document for reading as much as a list of instructions (or whatever) for the computer, it will be far more readable still. Formatting code as a story is the best way to communicate your intent with future readers. And who knows, maybe it will be you.