How to write Pseudocode and why you should

post by Johannes C. Mayer (johannes-c-mayer) · 2024-05-02T15:53:44.014Z · LW · GW · 5 comments

Contents

  How to write Pseudocode
    Start with Types
    Comments
    Names
    Delay Detail
    Dig Into Details
  Related Techniques
    Whiteboard Program Trace
    Describe Properties
None
5 comments

TLDR: Writing pseudocode is extremely useful when designing algorithms. Most people do it wrong. Mainly because they don't intentionally try to keep the code as abstract as possible. Possibly this happens because in normal programming a common workflow is to focus on getting the implementation of one function right before moving on.


I like it when I tell somebody about an idea, and they ask me "How would you write this in Python?" To be able to explain your idea to the Python interpreter, you need to have a really good understanding of it. Also trying to explain your idea to the Python interpreter often forces you to improve your understanding.

However, in my experience, it is much better to start by writing high-level pseudocode, to iteratively build your understanding. Descending into the pit of implementation details should happen in concert with how your understanding grows.

The main advantage of this is that this makes it much faster. It's hard to put numbers on it but I am sure it makes you overall at least 2x faster, compared to only working with runnable code. It's Probably more like 5-100x though.

Writing pseudocode properly is a skill you need to learn. It's very different from writing a program that you can execute.

The most amazing thing about this process is that at a certain point, long before you have a concrete implementation, you will feel like all conceptual obstacles have fallen, and only grunt programming remains.

You need to be somewhat careful because it is possible to feel like this, even when there is still a problem. A potentially useful heuristic here is to take a couple of steps more towards the concrete implementation and see if everything you're doing now is just really straightforward.

How to write Pseudocode

One of the core skills in writing pseudocode is to constantly ask yourself whether you can get away with not implementing something.

Start with Types

Usually, I start by just writing down the type signatures of the functions and data structures involved. I find it useful to make functions pure wherever possible, as this automatically makes the type signatures more informative.

Comments

The second step is usually to write some very high-level comments about what a function does in natural language.

Then I start to write lower and lower level comments describing what things this function does, e.g. what other functions are called where.

Usually, these comments are much more verbose than comments in an executable program.

Names

When naming functions I try to have the name invoke the idea of a function, which makes function names often very long. Ideally, your function name is so descriptive that you don't need to bother writing any pseudocode for it.

Delay Detail

One mode of operation is to try to stay at as high a level as possible for as long as possible.

The intuition behind this is that if you were to immediately dig into the details of a concrete implementation, you will be a lot slower and once you run into a problem and need to change stuff, making that change is a lot harder.

Ideally, you figure out all of the structure your program has at a very high level and only once you're sure that this is the right structure do you move to lower levels. The change, where you would need to rewrite over 50% of the code of a 1000-line program, might correspond to only changing a couple of lines in high-level pseudocode.

Dig Into Details

Usually, people fail to write pseudocodes well because they don't manage to delay the details. But sometimes it makes sense to try to get into as much detail as possible, usually for only one very small, very concrete part of the program that you're trying to figure out.

The more concrete you get, the more likely it is that you will notice if there is something missing in your understanding.

So, periodically I want to lead such a spearhead attack to check whether you can keep pushing or grind to a halt. Either it provides evidence, that you have figured out everything that's necessary, or more likely, you will discover a new bottleneck that you weren't aware of before.

Related Techniques

So far I've talked as if the best thing you can do is to start writing pseudocode. But I think there are a couple of things that are good to do beforehand.

Whiteboard Program Trace

A Whiteboard Program Trace [LW · GW] is where you write down a data structure on a whiteboard and step-by-step walk through how a general algorithm would manipulate this data, i.e. you execute the algorithm for one specific input in a visual way, usually before you have understood all the details of the general algorithm.

Describe Properties

Instead of trying to find the implementation of a program, you can just try to find the logical properties that your program would have. This exercise can give you a lot of information about the program and is useful for later steps.

This framing is also useful for writing pseudocode. E.g. we can think about a function sorting a list without concerning ourselves with what exact sorting algorithm is used.

5 comments

Comments sorted by top scores.

comment by faul_sname · 2024-05-02T17:38:25.344Z · LW(p) · GW(p)

This seems related to one of my favorite automation tricks, which is that if you have some task that you currently do manually, and you want to write a script to accomplish that task, you can write a script of the form

echo "Step 1: Fetch the video. Name it video.mp4";
read; # wait for user input
echo "Step 2: Extract the audio. Name it audio.mp3"
read; # wait for user input
echo "Step 3: Break the audio up into overlapping 30 second chunks which start every 15 seconds. Name the chunks audio.XX:XX:XX.mp3"
read; # wait for user input
echo "Step 4: Run speech-to-text over each chunk. Name the result transcript.XX:XX:XX.srt"
read; # wait for user input
echo "Step 5: Combine the transcript chunks into one output file named transcript.srt"
read; # wait for user input

You can then run your script, manually executing each step before pressing "enter", to make sure that you haven't missed a step. As you automate steps, you can replace "print out what needs to be done and wait for the user to indicate t hat the step has completed" with "do the thing automatically".

Replies from: johannes-c-mayer
comment by Johannes C. Mayer (johannes-c-mayer) · 2024-05-02T18:10:28.635Z · LW(p) · GW(p)

I like this a lot. You are programming for the human brain now.

It also seems nice that can implement each step in this program in executable code, and then you don't need to perform that step manually. You might even write little helper programs to perform the tasks, which can then later be used if you decide to automate the script more.

It also seems useful for developing an algorithm. Often I might want to understand what my brain is doing and have an algorithm that emulates what my brain is doing.

Maybe this method can be used to write down a very high-level description of the steps that I think my brain is doing and then see whether me now following that procedure blindly leads to the correct result. If you get the correct result, you can then try to fill in more details, automating each individual step a bit more, and then checking if you still get the same result, and so on.

comment by Algon · 2024-05-03T15:51:09.631Z · LW(p) · GW(p)

An example of you writing psuedocode woud've helped a great deal, especially if it illustrated what you thought was a core skill. 

Replies from: johannes-c-mayer
comment by Johannes C. Mayer (johannes-c-mayer) · 2024-05-04T13:54:40.724Z · LW(p) · GW(p)

Yes, I totally agree. But I kind of got distracted with this post and wanted to get back to work as quickly as possible. But instead of making it a perpetual draft I pushed a bit further and got some MVP thing. I agree it's not that good, and adding concrete examples, and really making this more like a tutorial would be the first step I would take.

So I am wondering if doing something like this is still useful. Would it be worse if I had made it a perpetual draft or better?

Replies from: Algon
comment by Algon · 2024-05-04T14:48:25.288Z · LW(p) · GW(p)

Probably it would have been worse as a perpetual draft.