The Product-Technical Spectrum
The role of product in software engineering has always been tense. In many companies, the two are separated into different positions: the product manager and the engineering manager. Yet this distinction disappears at the level of the engineer. Since many engineers are promoted into one of those two managerial roles, it stands to reason that a more nascent form also exists among engineers.
Recently, Triplebyte’s Medium post noted that for YCombinator startups,
Companies are more interested in engineers who are motivated by building a great product, and less interested in engineers with pure technical interests.
and coincidentally, one of the more well-known developers I know recently confessed that he is primarily interested in product, not code.
Confession: Sometimes I find it really hard to relate to our industry. I care about WHAT we're making, not the language/framework/compiler.— Tim Holman (@twholman) December 8, 2015
Tim fits nicely into TripleByte’s definition of a “Product Programmer”
Product Programmer: Candidate performs well on technical interviews and will have the respect of other engineers. They’re not motivated by solving technical problems, however. They want to think about the product, talk to customers and have an input into how product decisions are made.
Perhaps it is motivation that separates the future product or engineering manager. But what does it mean to be motivated by product? How is it different from being motivated by pure technical interests? Should companies prefer product programmers?
Product programmers may be preferred, but they are not perfect. The inverse of a product programmer is the “technical programmer”, which TripleByte defines as
Technical Programmer: Candidate is the inverse of the Product Programmer. They interview well and communicate clearly. But they aren’t motivated to think about the user experience or product decisions. They want to sink their teeth into hard technical problems.
Clearly there is a spectrum. Most developers are motivated by a combination of product and technical challenges, and both sides bring their own positives and negatives to the table. Let’s explore them.
Pure Product Programmer
The pure product programmer treats code as a tool to build the product. She chooses familiar languages and frameworks to arrive at the minimally-viable product, even if they may not be the best tool for the job. She moves fast, adding, modifying, and even removing features to satisfy clients, but never slows down to refactor the codebase. She ships early and ships often, fixing bugs and crashes after they are reported by customers.
A pure product programmer is at home when building a prototype, especially if it never sees the light of day at scale. You’ll find her at hackathons, startup studios, and digital agencies.
Pure Technical Programmer
The pure technical programmer treats code as a system to meet the specifications. She chooses the appropriate languages and frameworks to accomplish the known requirements, even if she may not be the most proficient in them. She uses proper abstractions to simplify the code, and refactors often to ensure the architecture matches well with the current product. She releases when the codebase has reached 100% test coverage and she would be proud if it was open-sourced on the same day.
A pure technical programmer is at home when writing code to meet a well-defined set of specifications. You’ll find her at technical conferences, engineering firms, and defense contractors.
In other words, a pure product programmer would ship a perfect product with disastrous code and a pure technical programmer would never release their product with perfect code. No wonder why startups prefer product programmers — the market judges product, not code.
The vast majority of programmers are motivated by both product and technical challenges.
A product will have mix of product and technical challenges, and most programmers will be motivated by a mix of both. They may find image processing algorithms extremely exciting to write, yet believe that adding the same feature would be inconsequential to the product. On the other hand, they may also believe that adding support for “blocking” users is critical to satisfying user happiness, but loathe writing the code to make it possible.
Even though every product is a mix of challenges, it’s still important to make a distinction between what motivates programmers, because working as a team requires respecting these individual motivators as fundamental differences. To compromise on the choice of framework or feature requires acknowledging that the other side has a valid point too.
Traits of the Spectrum
Since most programmers are driven by both product and technical challenges, it will help to analyze the spectrum along different traits. Programmers may be on different sides of the spectrum depending on the task, trait, or time of day. It should be no surprise that motivation may come from different places.
When looking at the tasks they are trying to solve, a technical programmer may reframe technical challenges as product problems to convince product managers that their work is worthwhile. Similarly, a product programmer may eschew difficult engineering problems and adjust the feature to fit their simpler solution that still adequately meets the customer need.
For most startups, the balance here is tilted toward product and the concept of “failing fast.” A random recommendation algorithm may still satisfy a user’s demand for recommendations, and a more robust product can be a built when competitors have similar offerings. A few companies strongly differentiate based on their technical prowess, especially in restricted problem domains, like algorithmic trading. Technical programmers excel in this space.
Products have deadlines. Either features are cut or deadlines are pushed to meet these deadlines. As Joel Spolsky says,
Shipping is a feature. A really important feature. Your product must have it. A very broad generalization may be made here: product programmers will reduce code quality to ship on time, while technical programmers will push deadlines. Before every release, programmers code in the gray area of “could this code be better?” and “did we build the right thing?”
Every engineer should be interested in cutting features before a deadline, because it reduces the scope of the product and the code. Product may be unhappy about reducing the feature set, while technical developers may be wary of now-unnecessary architectural abstractions. But both should agree that shipping is a good thing.
Shipping validates each of their perspectives. A product programmer can ship a great feature and say they have kept the users happy, while technical programmers can prove the robustness of their architecture. On a pessimistic note, without shipping, products don’t fail and code doesn’t crash. If a user never encounters a bug, is the app still buggy? If a feature never works, did it ever exist in the first place?
Languages and Frameworks
Product programmers choose familiar, mainstream languages and frameworks over unfamiliar ones. These will have StackOverflow answers and a wealth of libraries to build upon, even if the language is not perfectly suited for the task at hand. A great example of this is WordPress, which probably powers every possible type of website, some better than others.
Although it is tempting to imagine technical programmers sitting in a dark corner, reinventing the wheel in ever-more-esoteric languages, being technical does not make them bad engineers. Sometimes, using Erlang is the right choice. Remember, you can still dig yourself into a hole with Python. What is more likely is being caught up in engineering fads, which currently seem to be containerization and microservices. If you have more microservices than users, you may not have an engineering problem, but you definitely have a product problem.
Another common debate in an engineering team is whether or not to use a new library. Using a new library is often easier than writing the same functionality yourself, but the code is often of unknown quality, not having passed the same review process as internal code. A product programmer may use too many libraries, making the app harder to debug, but a technical programmer may savor writing every library themselves.
Tests are good. They reduce the likelihood of regressions while building confidence in the codebase. While test-driven development and 100% code coverage may be eschewed by product programmers, technical programmers shouldn’t be writing tests before the product is even understood.
But as Jamie Zawinski says in Coders at Work,
“…what I’m going to cut out is the stuff that’s not absolutely critical. And unit tests are not critical. If there’s no unit test the customer isn’t going to complain about that.”
But perhaps this argument should be left to others.
Culling technical debt is critical to software development, since code is a living history of past ideas, good and bad. The culling process is usually refactoring, and technical programmers often love doing it because the previous implementation can be used as a reference, and thus little “vagueness” about what the product is. Of course, as many engineering teams demonstrate, you can get very far without ever refactoring because it’s not client-facing, and code that works usually continues to work.
For product programmers though, time spent refactoring is time not spent working on user-facing features. The usual compromise is that refactoring is done when it is helpful when working on a feature.
What is the Role of a Product Programmer?
From the TripleByte post:
There’s more demand for product-focused programmers than there is for programmers focused on hard technical problems. The “Product Programmer” and “Technical Programmer” profiles are identical, except one is motivated by product design, and the other by solving hard programming problems.
Startups clearly prefer product programmers over technical programmers. On the other side, companies that employ blind allocation are selecting for technical programmers. Unsurprisingly, most programmers are a bit of both. Whether or not startups are actually interviewing for a programmer with product and technical motivations is another issue. More often than not, it seems that the discovery of product motivation in interviews is limited to “are you interested in this product?” rather than investigating the feedback the interviewee adds to product decisions. Technical interviews discover technical programmers, even if YC startups prefer product programmers.
Unsurprisingly, the growth of a startup often starts with product-focused programmers iterating on a rough prototype, with more technically-oriented programmers brought on later to improve code quality and develop a scalable architecture. Perhaps the best programmers are those who are not only motivated and dedicated to both product and technical excellence, but know how to balance the project management triangle. Maybe that’s why they end up in management.