Several years ago a teacher asked me to help with a problem one of her students was having. The student had decided to combine all of the semester’s projects into one big program. It was getting a stack overflow and no one had been able to figure out why. By using the debugging capability in Visual Studio (which is amazing) I was able to follow the flow of the program from method to method to method and figure out what was happening. Experienced programmers will tell you that recursion was involved and be right. This one was a little more complicated than that. A method called a method which called a method which called the first method. Looking at any method or two in isolation would not turn up the problem.
This is not a type of problem that one runs into in an early computer science course. The tasks we assign are more simple than that. They are targeted to narrow goals. In industry though large complex projects are the norm.
Years ago, when I was doing operating system development, memory management was less sophisticated than where it has come to today. One of the things we had to do was to manually specify overlays. What than meant was that a programmer had to tell the operating system what parts of code had to be in memory at the same time. Not everything would fit you see and the operating system was not “smart” enough to work things out by itself. So a programmer would diagram all of their subroutines and functions and group them together by which ones needed which other ones at the same time.
For example the open file and close file routines might not have been needed at the same time as the file read and write routines. So the programmer would specify that when the open or close was needed the OS could swap out the read and write routines and bring the others in. In a complex system this sort of diagram and overlay instructions could get several layers deep and look more complicated than a large company organization chart. It was not fun to set up.
This did have a good side to it though. It really forced a developer to understand the organization of their program. Which methods were dependent on which other methods and so on. It actually let one do some performance tuning as well by specifying that some methods shouldn’t be swapped out except rarely. Doing a chart like this would probably have helped spot the stack overflow problem I started this post with. Without the debugging that let me step through from routine to routine I would probably have had to resort to this sort of thing. I’m not sure that would have been a bad thing though.
The truth is that as software development gets easier – for example not having to think about memory management and how program methods are overlaid in memory – we give up something in understanding the complexity of what we are doing. It’s a mixed blessing for sure. I don’t really want to go back to overlay charts and manual specifications. At the same time I worry that we don’t understand complex programs as well as we might.
It is always tempting to assume that if all the pieces work well in isolation that the complex structure they are a part of will work just fine. That is not a safe way to bet though. We need to think of the system as a whole and how each piece interacts with each other piece. Perhaps I am biased as I have a degree in Systems but I don’t think we teach enough of that sort of thinking these days. Not just in computer science ether but that is one place it shows up to bite people when they start developing code in large projects.
Computational thinking is a part of this but I think systems thinking is larger than that. We need to start thinking about systems thinking at younger ages.