Programming "From Scratch"

Recently, I have become interested in making programs from scratch in C. It provides an unbiased look at what goes on behind the scenes of the systems all of us use daily. Things that people take for granted like dynamic containers, classes, generics/templates, and package management are not present in C. In one of my recent projects, I challenged myself to create everything without using any external libraries. I was going to do it “from scratch”. But, in the project, I am using the C standard library, the Win32 API, X11, GLX, and OpenGL. I did not get these from random github pages, but they are libraries nonetheless. To me, it begs the question: what does it even mean to program from scratch? Where do you draw the line?

Perhaps it is a bit silly to insinuate that using the Win32 API to load a file on windows is not programming “from scratch”. Afterall, how else would you load a file? I do not have the desire to write my own operating system. Or, take someone programming a game in Python with Pygame. Even though I could say that they did not write Pygame, SDL2, and Python, almost everyone would consider that programming from scratch. All of this seems to be dancing around the broader idea of abstraction in programming. From my experience, abstraction seems to exist for two main reasons: standardizing systems and hiding detail. All of this is for the ultimate goal of systems that are easier for the programmer to work with. A library like SDL2 makes it so that the same code will create a window on Windows, Mac, and Linux, but you might lose control over specific details on each platform. In some sense, abstraction is fundamental to all of modern computing. A JavaScript programmer does not have to think about how the memory and indexing works for their object, and a C programmer does not have to think about how Windows or Linux reserves virtual address space. Someone making an assembly program does not have to think about the individual electronic components of a computer. I believe that the explosion of computing in the past 50 years was partially due to programmer’s ability to simplify development. For the most part, it is just faster to develop applications in JavaScript and Python than in C. Because of how fundamental this abstraction is to almost every program today, I do think it is silly to make some distinction of programming a system “from scratch”. We all just chose which systems are important enough to go one level deeper.

This brings up the, in my opinion, more important question: where do you draw the line? When do you write the system yourself? To me, I think that there are three main reasons that one would want to program something from scratch: education, control, and, for lack of a better word, annoyance. The first reason, education, is probably the only reason your average programmer would write something like a dynamic array from scratch. It is not because you have some misguided idea that you can make a better dynamic array than all the experienced programmers that wrote your favorite standard library. You would do it so that you understand what goes on behind the scenes in a dynamic array. By writing it from scratch, you have the experience to use the standard library one more effectively and efficiently. Another reason someone might want to write something from scratch is just for control. You most likely could not make a faster version of the standard library’s generic dynamic array, but you could make a more optimized version for your specific use case. For example, in my codebases, I generally use memory arenas instead of the standard malloc and free model. This means that it would be easier to make my own dynamic array from scratch rather than using something like stb_ds.h. The final main reason that you would write something from scratch would be annoyance. If the widely used library for something does not work well in your codebase, it could be worth programming everything from scratch. It really is nice that my whole codebase follows the same conventions for naming, memory allocation, etc. I think that this last point can partially explain the Rust community’s emphatic urge to rewrite everything in Rust. Obviously, I am not a Rust developer, but I do understand this perspective. Many old and widely used programs written in C and C++ should be rewritten. Whatever your perspective may be, I hope that I have shed light on the reasons that one would write a system from scratch.

One thing I do have to address is my biased perspective on this issue. Right now, I am only programming as a hobby, so many real world factors do not matter as much to me. I do not have to consider many real world factors that push millions of developers to employ extensive use of libraries in their code. Regardless, I hope that I have made you think more about what programming “from scratch” really means as well as the reasons people do program systems from scratch.