I had some pretty bad writer's block since I made my last post on Listed where I detailed what I would write about next. I realized that there was something I needed to write about before I could really write about any of those topics, but it took me several days to figure out what it was. I wanted to write about one of the topics I had put down for the "fundamental concepts" series, but, except for the one on Documentation, I couldn't just write about them, I needed some kind of post before that laid the foundation for why they're worth writing and reading about.
After a few days of thinking, I started putting together some thoughts to try to get started on a post. I got it partially written, but I realized it still wasn't what I wanted. Something finally clicked though, and I figured out what I needed to write about: program modeling.
The reason why program modeling is the topic I had to write about next is that if I want to write about things like files or linked lists, I have to somehow convey the idea that I'm writing about these topics so that others can connect the dots and see how everything ties together. I personally am a very visual person, and I see code and systems as being connected, and I link every new thing I encounter to things I already know; this, coupled with the fact that I am the one building my site and know the messages I'm trying to convey, means that I will of course see each post I write in the way I intended, that everything builds off of prior material (with the exception of my first few posts, which I wrote before I had a good idea of where I was going with the site). I can't assume that everyone else who reads my site will know that I'm intentionally building it up in this fashion. By creating a post that goes over different ways of building representations and models of systems and programs, and which stresses the importance of understanding the fundamental concepts, I feel I can now write about those concepts without issue.
Now that all of that is out of the way, let's get on to what I wrote about.
When trying to figure out how a program works, you usually build a model of it internally in your head in a way that makes sense to you and you alone. That being said, there are ways to model programs externally (ie in ways that can be easily shared with others). Knowing some of the ways that programs can be modeled, as well as some of the approaches to actually creating a model, is thus the topic of this new post.
I wrote about three representations of systems and programs:
- Flowcharts (or process flows)
- Written text (sentences or paragraphs)
Flowcharts are obviously the most visual representation of a system. Their chief advantage is that they highlight application logic, and easily hide implementation details with a few words at each step. They're well-suited for describing systems with complex logic, or where the logic is at least as important as the actual steps being performed.
Written text is easily understandable by everyone, and its largest advantage is that it's easy to go into as much detail as needed, skipping over implementation details when they would otherwise bog things down, or going into great detail when describing complex components. There's never really a reason to not have a written representation of a system.
Pseudocode is best used when conveying intricate details of an algorithm in an easy-to-reproduce manner. You wouldn't generally want to write a pseudocode version of an entire program, and pseudocode on its own is not enough, there needs to be at least a brief explanation of what is going on. However, when used correctly, pseudocode can greatly enhance documentation.
I wrote about the following approaches to modeling:
- Bottom-up modeling
- Top-down modeling
- Meeting in the middle
Bottom-up modeling consists of starting with the basics and building new components up from existing components, implementing application-specific logic only when all application-specific components are built. It's great for testing as you go, because at all stages you'll have a complete program (at no point should there be any undefined functions or objects). It's not so great though if you're wanting to quickly get the shell of a program done, because that takes a while to form with a bottom-up approach. It also can be overwhelming at times, since you're starting with the "implementation details" instead of hand-waving them until later.
Top-down modeling is the opposite, starting with application-specific logic and, as I said, hand-waving the implementation details until farther down the line (generally the last thing done, actually). It's a great approach for getting a good idea of what the system is and how it will function, but at the same time, because the final implementation details are put off until last, it's possible that the realities of implementing the system make the design infeasible.
"Meeting in the middle" is an approach that combines the previous two: as application-specific components are designed and created, low-level implementation-specific components are also created; application functionality is built "down" while supporting pieces are built "up". The application is thus designed and developed a component at a time, where each component is fully functioning and in its final form once it's created. The main drawback of this approach is that you essentially need to have the whole thing planned out from the start, since it's hard to build something a component at a time if you don't know what those components are and how they'll relate to each other.
You can read the post in its entirety here: https://thinkingincode.ninja/posts/program-modeling
Thanks for reading!