Who am I talking to?
“You” probably don’t really exist. Best case, I can’t prove that You exist outside of my mind. Worst case, I don’t exist either. Accepting either possibility makes writing for a blog a rather absurd task. What’s the point If the author can’t prove the existence of an independent world outside of their own mind?
Just for grins, I will conjecture that, at most, there exists one other person/agent with their own mind independent of my own. That’s You! (Does that make this a “Biopsist’s” guide? Note: I am not a medical professional. Ha! Puns…) It may very well be that either of us is simply a manifestation of the other’s imagination, in which case one of us is talking to themselves. These are the risks we/I face. Onward!
Crappy witticisms aside, this post is for programmers of any experience level. I especially hope that those new to the field, and those coming to the field from a non-traditional path will at the very least come away with a desire to reflect about the nature of a program’s purpose, its creation, its interaction with its universe, and one’s own approach to the craft.
In the space of this singular post, I aim to project programming through a lens of philosophical concepts, even if only superficially — just enough to plant the idea that it’s not merely about memorizing syntax and algorithms. For programming is a deeply personal act of creation with the power to alter one’s perceived reality. It can be treated either as an art form, or a cold and lifeless set of tasks. The choice is entirely up to *You.
*Assuming that You are, in fact, the other real agent of mind conjectured to exist at the top of this text. Only the truly conscious need continue any further.
Take this moment to ignore what You’ve learned and experienced with respect to collaboration, working on a team, pair programming, mentoring, group meetings, stand ups, pull requests, peer review, etc. For the duration of this essay, I’d like You to suspend any notion that there currently exists any other conscious beings other than Yourself (and perhaps me).
From now on, You can only be sure of Your own mind, and what You perceive to be the world around You. That is, the world and people around You may not actually exist. What’s left as “real” are Your mind and its perceptions.
This is the essence of the *philosophy of Solipsism. In a nutshell, only You / Your own mind are certain to exist. Your perceptions are real, but what they perceive may not be; they have no material basis in a world external to Your mind and Your mind alone. You can not know, or prove, that other people have a mind independent of Yours. It’s a pretty heady concept (*cough* cheesy joke *cough*).
Specifically, this describes “Epistemological Solipsism,” which may be considered a more forgiving flavor of the philosophy, as it allows for the possibility that an external world and external minds exist, but considers the matter unknowable/unsolvable. A harder-core version is known as “Methodological Solipsism,” where only one’s own thoughts are known to be certain. Nothing else is real. The mind itself is a part of an external world. We’ll stick with the former definition for our purposes. (Plus, it’s way less depressing.)
*the philosophical concept, not “Solipsism Syndrome”, a currently unofficially recognized but proposed psychiatric condition
Programmer as Solipsist
You, being the only real agent of mind certain to exist, carry the burden of building and maintaining reality. Fortunately, You are also a programmer, which drastically expands Your ability to manipulate and understand Your world. This skill is so powerful that it allows You to create additional worlds spanning an entire range of certainty: from a completely proven deterministic model to a stochastic system that is unknowable as the external world outside of Your mind.
You have a responsibility as a solipsistic entity to consider carefully the following aspects of Your own world:
- What You think You know
- What You know to be provably certain
- What You observe
- What You intend to accomplish
What You Think You Know
Survey Your assumptions. Whether setting out to create a new unit of code, or debugging some unexpected behavior, perhaps the single most important step You can take toward progress is to enumerate the things You hold as given/certain. A quick gut check for these things is if You find Yourself thinking/saying things like:
“Well, it can’t be [foo]”
“The [foo] should be fine”
“[Foo] has never been a problem before”
Where “[foo]” is a placeholder for some component of Your system: input data, external APIs, a validation function, or assertion about the environment.
Far too often, programmers of any experience level will brush off a simple and obvious potential point of failure in favor of something more complicated. This results in a rather inefficient and circuitous path of development. I’ve seen teams, and myself, spend entire weeks chasing down a phantom problem as a result of making an untested assumption about what the cause of a problem was. In every case, the true issue turned out to be something completely unrelated to the original supposition that was looked over simply because it was “too simple to be the problem.” Once found, many of these things are typically resolvable in under an hour, which sure beats an entire week or more.
The takeaway: Your world must be continuously reevaluated. Challenge Your own assumptions by proving them with evidence. Identify the thing that “can’t possibly be the problem” and verify it first. Move the assumption into the realm of the provably certain or falsifiable.
What You Know To Be Provably Certain
After reevaluating Your assumptions and ruling out various falsehoods, the next step is to enumerate Your factual knowledge about the system in question (new program, module, debugging session, etc.) This is part of the process of refining Your world. After all, Your world is the only one You can be certain of. Survey the facts.
Applied to programming, this involves testing, validating data, and the program’s behavior. Mechanically, this may involve writing unit tests to assert that individual components behave as expected. However, this is not adding provable knowledge to Your world; it merely exercises rationalistic machinations to assert things You have told it to assert.
So it comes back to Your knowledge. Writing tests isn’t a magic catch-all, it’s merely an extension of what You believe to be true about Your world, specifically the world in which Your program/software operates (which may or may not resemble the world as You, a conscious being, know it).
Tools of the Trade
There are a number of tools at Your disposal during the software/hardware development lifecycle that can provide both empirical and logical certainty about Your knowledge. Here are just a few examples:
- Algorithmic Analysis – Many developers are intimidated by this topic with its roots in computer science and mathematics. However, the basic idea is quite simple, and anyone can develop an intuition for the basics. Think of it this way: a computer does the stuff You tell it to do, and even though a computer is super fast and can do millions of things in fractions of a second, some instructions are better than others. Without thinking about it, You may inadvertently give Your computer “bad directions” causing it to operate very slowly or run out of memory. Lucky for You, a vast majority of common programming situations have been studied at length and solutions (“good directions”) have been identified for You. It’s really a matter of getting familiar with the many high-level patterns for writing performant programs; as well as identifying when to use them. I’ve programmed for two decades now and have only on very rare occasion had to resort to doing algebraic asymptotic analysis, and even then I did a hack-job at it, and it was just fine.
- Error Handling – Error handling is the practice of expecting something to go wrong during Your program’s execution, and attempting to recover from the failure in a graceful way, hopefully allowing the program to continue operating instead of crashing. Some additional tools that go hand-in-hand with error handling are:
- Logging – Not just for errors! Being able to record and report on what is happening during a program’s execution is an invaluable debugging tool as well as a knowledge-building insight method that will help You improve Your decision making.
- Input Validation – You shouldn’t trust any input Your program receives to be what You expect it to be! Ever. Adding validation routines will help to prevent unwanted/invalid data from entering Your program’s world and making it puke all over itself. Validation adds to Your provable knowledge of what is going on inside of the program. Simple example: The program expects a valid U.S. phone number. User types in their email address. What should happen? Adding some form of validation will help ensure unknown stuff doesn’t creep in.
- Capacity Planning / Environment Testing – Your program needs to run somewhere (be executed in some context). Planning for and measuring the computing/infrastructure resource needs of Your program is a way to add provable knowledge. And just as with algorithmic analysis, You need not be an “expert” to consider this when planning Your own program. It can be as simple as setting a benchmark for how long You expect the program to run under certain conditions, or determining what an acceptable wait time is for a UI widget. The idea is to consider different measurable/testable aspects of Your design, not to have to be an enterprise-level systems engineer. (If You are, though, congratulations — that took a lot of work!)
What You Observe
So far along Your journey to refine Your world, You have (in)validated Your assumptions, added to Your provable knowledge, and incorporated tools to verify this knowledge. And while all of that is very scientific-ish and procedural in nature, one other very important aspect of Your world must be addressed. This aspect is general observation and reasoning about what is happening around You. So, is this really different from measuring and testing?
I believe that yes, in fact, it is. Many programmers can become stuck in the professional development cycle, which may include things like unit testing, analysis, validation, etc, but performed in a very rote and automaton-like fashion. And while it is certainly beneficial and appropriate to proceduralize a development workflow in a work setting (for consistency, quality, training, etc.), it may do little to help You build upon Your intuition and observational induction abilities.
This section is a little fuzzier than the others. It may not be entirely clear what constitutes a “general intuitive observation.” But try this at some regular interval (weekly, daily): Remove Yourself mentally from the daily tasks You are assigned.
Now consider the concept/goal/purpose of the RESULT(s) of Your work. From this context, ask the following questions (first to Yourself). If You can’t describe the result(s) of Your work, I suggest that be the first question You try to answer; You might not be the only one lacking this clarity.
- What does this ‘thing’ do well?
- What does this ‘thing’ do not-so-well?
- Are there other ‘things’ around here that do the same thing / a similar thing?
- Are other ‘things’ better suited to do what this does?
- Does this ‘thing’ utilize/implement the best mechanism in order to do what it does?
- What exists outside My current knowledge that could relate to this ‘thing’?
You may be surprised with the answers You find. Even the act of seeking an answer can provide You with a wealth of useful knowledge, related or not to the original query.
What You Intend To Accomplish
Equally as important as Your mind-world knowledge is Your intent as a creator. Programming is a creative act and is undertaken with intention. As with other art forms, the intention need not be associated with value or material effect/consequence/manifestation.
Exercising self-reflective critical thought while attempting to program a system will lead to insight into Your mind-world, informing and ratifying knowledge. As new insights and facts become explicit it will become increasingly important to create, synthesize, and question things with purpose, to act with intention. Creation with intent helps (*or hinders) the ways in which the world is perceived.
*There’s always a dark side. It’s like science or something…don’t be evil.
Having intent behind Your development process will necessarily shape Your own understanding of the craft and the systems You create as well as determine the following aspects of Your work:
- the ability of *diverse individuals and systems to interact
- the means by which others and systems interact
- the ways in which You and others reason about Your work and its impact (technical, cultural, etc.)
*diversity of user interface conventions (influenced by factors such as: culture, geography, access to information, etc.)
Your intentions (or implementations thereof) define the world. (See also: this interesting article from the American Institute of Architects)
Take some time to reflect upon the ideas presented above.
Look out for Part 2 next week, when we’ll break down The Program’s place in the universe.
Tagged with: essay • improvement • philosophy