I've realized that I'm a bad programmer
TL;DR: Until recently I’ve always believed that Object Oriented Programing is the best and professional way of solving most problems, but I’m probably wrong. From now on I’ll change this behavior by first thinking if OOP is the right tool for the problem I’m facing.
It’s safe to say that I’ve been a programmer since 2012. It started by learning some markup here and there (HTML, LaTeX), then I tried a bit of R. It was only when I dropped out of my Economics undergrad program and (briefly) enrolled in the Computer Sciences (CS) program that I started to do some real programming.
As it was with many people my age, I started learning the basic CS concepts in C (I still have nightmares where I’m debugging my unreadable code in Code::Blocks using a bunch of
printfs). After a while I started learning Java, and then Python, R (for real this time), C++, Assembly, MatLab and many others.
With time I started noticing that the code I was producing was getting more complex. A natural consequence of more complex projects, I thought to myself. But recently, listening to the opinion of other programmers made me realize that maybe the cause of my ever increasing code complexity is that all this time I’ve been believing in a lie.
The OOP indoctrination machine
The first Programming Language (PL) that I learned with support for real Object-Oriented Programming (OOP) was Java. I still remember the example used by the teacher in the class to explain OOP concepts: cars. He talked about how
car is just a concept (class), and that you can have many instances of this concept such as an specific chevy impala (object), and how you can interact with this car (methods), you can change it’s properties (attributes) and you can interact with it’s console and pedals to change it’s state (setters, getters and interfaces), and the list goes on and on.
The fact is that almost every place that teaches programming preaches that OOP is the most professional, efficient and safe way to do it, and most people will go through their life drinking the OOP Kool-Aid.
Once I learned to program in this mindset I was hooked. The ideia of mapping real world concepts to code and encapsulating everything seems like a good idea at first, specially for those who don’t have a lot of programming experience. But what they never tell you while you’re learning this paradigm is how much complexity and fragility you’re adding to your code by doing it.
I’ve started working as an intern at Investment One Partners and my first task there was to finish implementing a system in which the analysts could share and visualize each other’s analysis and market data. It’s first version was already halfway finished by my boss using R and Shiny.
Given his short experience with programming I’d say that my boss is a very good programmer and has a good knack for systems development (no, I’m not writing this just to publicly kissing his ass), so when I took charge of the project it wasn’t too messy. The first thing I did was to modularize and organize the code, as to improve the development process. Then I went on to implement the missing screens and vois là: the first “production” version was finished in less than 3 months. But even though the project was working as intended some things bothered me:
- It’s performance was abysmal
- Almost 40% of the code was just functions that executed SQL Procs and Queries.
- There wasn’t any access control
- No task support: all asynchronous tasks were being executed by a polling script running in the same machine
- Expanding the system’s functionalities was becoming exponentially difficult
- It was implemented in R, for god’s sake
As the OOP minion that I am I thought to myself: All problems will go away if I rewrite the system using a REAL web framework, implemented in a REAL programming language that uses REAL OOP, so I made the following suggestion to my clients (the analysts): give me 4 months to rewrite the system; I’ll spend 1 month learning Django and React and the other 3 rewriting the system, this way I’ll solve all the system’s problems. They agreed, and this was almost 1 year ago. Even controlling for the planning fallacy, I grossly underestimated how long it would take to finish the rewrite.
By the month 7 of the rewrite I was completely convinced that doing this was a big mistake, but I didn’t understand why exactly. Was I a crappy programmer? Was the project just too complex? Was it normal for a project like this to take this amount of time and I just underestimated the time it would take to be finished?
Since then I’ve been beating myself over my (apparent) absurd lack of programming and planning skills.
The proverbial straw
Then, in one recent day, two things happened:
- I watched Object-Oriented Programming is Bad1 and What Programming is Never About (Informal Lecture)
Watching both videos and witnessing my boss kick my ass productivity-wise made one thing clear to me: OOP nudges me to overengineer software.
I won’t go over all the points made in both videos here, but as the Object-Oriented Programming is Bad video argues and I’ve experienced in my professional life, the OOP’s encapsulation promise simply doesn’t work. And by trying to abstract and encapsulate complexity in the preached way I end up creating a huge number of abstraction classes, which end up just creating complexity of their own.
Looking at all the projects in which I worked on I get this strong impression that every time I used an OOPL to solve a problem I ended up spending a lot of mental energy trying to fit the problem into the OO paradigm, when in reality I should have been questioning myself whether using the OO paradigm was the right tool for the problem in the first place.
This conclusion gets even clearer when I see that every time I was forced to tackle a problem using a non OOPL (such as MatLab and C) I ended up solving it in a much faster and simpler manner than I usually do.
Now I can see that all this time I was the hammer that interpret every problem as a nail, and seeing the What Programming is Never About (Informal Lecture) only confirms my suspicions. This video made me remember that programming is never about the code, it’s beauty or level of abstraction; programming is about moving data around to solve a problem. It’s not the case that such things as code organization and readability doesn’t matter, but they should never be the programmer’s first concerns, and I guess that I forgot this somewhere while I was diving deep into Design Patterns, code style guides and PEP’s.
Knowing these things about myself is both a blessing and a curse. It opens my eyes to other approaches (functional, pure imperative programming, logical etc) and stops me from thinking that the only “enterprise level” solutions are OOP. At the same time it will make finishing my company’s project a much harder endeavour since now I’ll be forced to see and work with my past mistakes on a daily basis (rerewriting is NOT an option).
I’m not saying that I’ll avoid OOPL like the plague (and even if I wanted it would be impossible). I’m only saying that, from now on, I’ll always make sure to first take some time to think if the OO paradigm is the right tool for the job at hand.
I know that my road ahead won’t be a walk in the park: by leaving OOPL as my only go-to tool I’m trading a set of problems for another one, but I have to say that it feels good to take the blindfold off.
The sad part is that just as I thought that I was becoming a really good programmer because I was getting really good at Python I had a wake up call and now that my horizons expanded I find myself as a rookie once again. At least climbing this ladder is kind of fun.
As for my company’s project, I guess that I’ll just have to keep on grinding to the V1 finish line. After that maybe I’ll implement it’s new features using a microservices architecture if its upsides are greater that its downsides. We’ll see.
I strongly suggest watching at least the first video to whomever programming is a relevant part of his life. ↩