In my opinion, software development is a deeply philosophical undertaking.
I’m not really sure how most software developers will feel about that idea. I suspect many will find it ridiculous, or worse, uninteresting. If that’s you, I understand, but I hope you’ll indulge me for a little while. If you’re willing, know that my goal here isn’t navel-gazing for the sake of it. This article is my attempt at making a practical argument for thinking philosophically about software. I think there’s real value in it.
I should also note that the ideas I’m laying out are still a work in progress for me. For most of my career, I’ve been a developer focused on solving real-world business problems. This left little time for philosophizing. But now that I’m an instructor, one of the joys of my job is time to think deeply about software and software development with the idea that the better my understanding, the better I will be able to teach my students.
Ok, that’s enough preamble...
What Do I Mean By “Thinking Philosophically”?
What do I mean by “thinking philosophically?” I mean thinking about big concepts. Asking fundamental (and maybe weird) questions. Focusing on the process of thinking through a problem rather than being concerned with conclusions. It’s not analytical. It’s not absolute. It’s not concrete. It’s not even objective. It’s personal. It’s meaningful. It’s what you talk about with other programmers over a beer.
To me, there’s a real connection between how we think about software systems and how we think about the broader reality around us. If I create an instance of a Chair class, for example, does that new chair object exist? Does it have more or less reality than the chair I’m sitting in as I write this? I can’t feel it or see it, and it certainly doesn’t stick around for as long as my comfy recliner, but does that make it less real?
I may not be able to move a chair object across the floor, but I can still interact with it. I could slap a UI on my chair object and rotate it, change its size or color, or do any number of things. In a slightly more indirect way, I can interact with it by writing code that calls methods or sets properties on the chair object. I can pass it around as an argument to functions, or serialize it and send it racing along a cable across the ocean floor. If I can do all this, does that mean the chair object is real? As real as my recliner?
So you just read that, and maybe now you’d like the last few seconds of your life back. Maybe you’re thinking I promised you something practical and not just gratuitous navel-gazing.
But I contend that once in a while there’s real value in asking these sorts of armchair (recliner?) philosophical questions. Like philosophy, so much of software development is about abstract concepts. For most of us, these concepts are difficult to internalize when we’re first learning. I think these sorts of deep questions can be an avenue to improving our understanding.
The point is not to definitively decide if a chair object is real, the point is to come at the concept of Classes and Objects from another angle. I like to think of it as sneaking up on my own mind. If I’m lucky, I won’t see myself coming.
Classes, Objects, and the Theory of Forms
Let’s dig deeper into the Classes and Objects example. When we’re trying to understand this concept, we watch videos, listen to lectures, read articles, seek out concrete examples, and eventually write our own code. We repeat the mantra, “classes are used to create objects”.
So where can philosophy fit into this process? Well, the relationship between classes and objects is reminiscent of Plato’s Theory of Forms, which is the notion that for every type of physical thing there exists a perfect “Form” that acts as a blueprint for constructing an instance of that physical thing.
For Plato these “Forms” exist in a perfect, static, timeless land of ideas, and manifest themselves in the clunky, temporal, material world of things. In much the same way, Classes exist in our source code, saved into files on our hard drives, and manifest themselves as Objects in the sometimes-messy, running software that drives much of the world around us.
Is it necessary to think of Classes as Platonic Forms in order to understand them? Of course not. Is it useful? For some people, I think so. Also, frankly, I think it’s fun to think about. And when something’s fun, we tend to do more of it. For me, that means I spend more time refining my mental model of Classes and Objects.
Thinking Philosophically As A Way To Learn
Part of my role as an instructor is to be considerate of the ways in which people learn. Some are concrete and need to start with examples before they can grasp more general concepts. Some are abstract and prefer starting with metaphor before drilling into the strict syntax required to actually get the code to compile. When teaching a diverse group, the trick is to find a variety of ways of exploring concepts, and of tying those concepts to real code in the real world.
The approach of thinking philosophically about code would NOT be the best way to introduce a new idea. It probably wouldn’t be effective on day two or three either. But, I think for some students, it can help with thinking past the conceptual roadblocks that sometimes prevent further understanding. It can be a way to sneak up on them with a different perspective.
That’s all I have. Like I said before, it’s all a work in progress. But in parting, I’ll leave you with some other questions to ponder. You can decide if they are deep or foolish. Helpful or a waste of time.
Is it the class that has methods or the object? Does the word “method” have different meanings in different contexts?
What’s the difference between an object in the running program and our conception of it? Does it even really exist in the computer, or is it only ever in our head?
What’s the difference between a class and an object? Is it same as the difference between these words on the screen and the thoughts they produce in your mind?