• How to Be a Good Product Engineer

    Companies don’t really want frontend engineers or backend engineers or infrastructure engineers. If you work at an engineering as product organization, they want good product engineers solving user problems. As an industry, this is poorly understood and little is written to help people understand the principles of good product engineering.

    This is my attempt at explaining some of the core tenets of the best product engineers I’ve worked with and what I strive for.

    Engineer: “Does it work”, product engineer “Does it make sense.”

    You are not the user

    This is the main challenge of product engineering. Unless you are writing software that is specifically targeting a problem you have directly that you would buy for yourself, you are not the user. It is significantly harder to build products for other people because the further from the self, the less real it feels.

    To overcome this simple fact, you must make contact with reality. You can ride along sales calls to hear how your product is pitched and hear first-hand how prospective customers are describing their problems. You can answer support tickets to see how users struggle with the product.

    If you never make contact with reality, it’s easy to fool yourself.

    Develop domain knowledge and expertise about the user

    I’ve never met a good product engineer who doesn’t talk to users and doesn’t know the ins and outs of the domain their users are in.

    If you are working in a highly technical field (legal, tax, banking, etc.), it doesn’t mean you need to be a CPA or lawyer, but you’ll need to get to a foundational understanding. Without this, you won’t be able to understand the context in which your customers experience their problems and you could miss key insights.

    Ever read a mainstream news outlet story about engineering and think—gosh that’s not even close? Every domain has infinite detail and it’s obvious who ‘gets it’ and who doesn’t. People are smart and your product will look like marketing bullshit if you don’t have domain expertise.

    Conjecture is more important than data

    Data-driven decisions sound intuitively correct but trends are not explanations. Great product development requires conjecture. While luck is important to success, making good choices about a product does not. Reasoning about problems clearly starts with deeply understanding the situation and drawing conclusions. This is why building up domain expertise and talking to users is so important.

    Beware the downside of first-principles thinking, talk to users as a shortcut, and, crucially, make contact with reality often (try out your ideas iteratively).

    Cultivating product sense is having good taste

    Product sense is making good decisions about the user often. To do that needs a refined sense of taste. Good taste is an intuition about power.

    Cultivating taste is hard. If you are building products and are driven to build great products, chances are your taste is already pretty good (you can spot the taste gap) but refining it is difficult.

    I like the definition of taste from Creative Selection: taste is the refined sense of judgment and finding balance that produces a pleasing and integrated whole.

    I don’t know of a way to cultivate really good taste other than to make it less ethereal—you are after distinct knowledge about the user, their problem, and the solution. Objective knowledge begins as conjecture and is then corrected with criticism. Work in an environment that embraces good explanations and is error correcting.


  • Taravangian Intelligence Test

    On one very special day, Taravangian was the smartest person in the world. In a single effort, he scrawled a codex that laid forth a plan to save the world that would make him king of all things. Unfortunately, he’s not always intelligent enough to understand his own plan.

    Every morning Taravangian has his servants test his intelligence to see if he is fit to make progress on his plans. Most days he is of average intelligence and can do things. Some days he is dumb and must be stoped from making any decisions for fear of destroying his plans. On fewer days he is of above-average intelligence but he never repeated the single day of genius ever again.

    From The Stormlight Archive series by Brandon Sanderson.

    See also:


  • Puffery Doctrine

    It’s fairly common for companies to make sweeping claims in the course of day-to-day business. While this can be misleading, it is not particularly illegal. The “puffery doctrine” covers the line between unbridled optimism and misrepresentation.

    From Room for Optimism: The “Puffery” Defense under the Federal Securities Laws:

    Although there is some variation from circuit to circuit, as a general matter, under the “puffery” or “corporate optimism” doctrine, the courts have ruled that an alleged misrepresentation is not actionable where:

    • It is so vague that it is not subject to being either proved or disproved.
    • It is a nonspecific expression of optimism regarding future performance.
    • It is a future projection stated as an opinion and not as a guarantee, or which is indefinite as to time.

    See also:

    • This sort of makes sense that courts must take this stance otherwise they would need to be arbiters of truth which is maybe not possible
    • False precision is another form of “puffery”

  • One of One Software

    I would guess that a significant amount of software is written for one person and we should celebrate it more.

    Most software engineers tend to write for other people. They hope to create a popular open source library. They’re working on their startup idea. Maybe it’s a matter of industry norms i.e. pretending that the next engineer reading your code is an axe-wielding murderer.

    Why not write one of one software? Written just for you, to do exactly what you want, without consideration for someone else. What if we didn’t place such a high premium on popularity and scale?

    I imagine there are many other kinds of software that would be created that aren’t today. It would be more fulsome and go deeper into the problem instead of a shallower Pareto optimal of building for other people. It would be limited by the author’s time and ability so the shape of it might look very different—a greater emphasis on combining things that already exist and smaller in scope.

    I imagine the ceiling for one-of-one software is significantly higher. For one, there is no faster feedback loop than the one you have with yourself and so you could rapidly iterate. With sufficient skill coding becomes the most convenient option and software becomes a malleable material for making what you want.

    What are some examples of one-of-one software you’ve written?

    See also:

    • A simple example is my Emacs config which is a thousand lines of code that will only ever be executed on my CPU
    • I built org-ai and an emacs integration just for chatting with my notes

  • Format Code Like Prose

    Writing code is also writing for other people. We use many conventions in written communication to help with readability. Ever sit down to read someone else’s code and it’s giant wall of procedural statements for 100 lines straight? Imagine reading a paragraph that goes on for 100 lines.

    I like to format code like prose. Statements in a long function that complete an idea should be grouped together visually—think of it as a paragraph and add some newlines for the reader to take a breath. Write linearly so it’s easy to read from beginning to end (you don’t read a book by jumping around back and forth between pages). Organize hierarchically from most general to specific (e.g. the last line is generally expected to be the return value so use early returns for edge cases rather than the main case).


  • State Agencies Are Eventually Consistent

    It always seems to take awhile to get resolve an issue with a state agency. They might send you a letter that you owe them taxes. You might respond to said letter and pay the taxes. You might then receive another letter…for the same taxes you already paid.

    Why is that?

    The way to think about state agencies and—by proxy—your tax accounts, is that they are eventually consistent. Changes can happen to the balance of your account, but what you observe (e.g. a letter) might not accurately reflect the current balance of your account. It’s not just balances—pretty much any information that changes will take time to settle into the right places.

    Part of this is run-of-the-mill bureaucracy, but these are also large scale organizations and with distributed systems. (If you think about it, even moving papers around a building or two is a network which comes with network faults). Without eventual consistency, they would be unable to serve as many users and handle the complexity in which they serve them.


  • You Don't Know There Is a Compliance Problem Until After It's a Problem

    One of the many challenges of staying compliant is that the feedback loop can be incredibly slow. By the time you find out there is a problem, it might be months after it became a problem. For example, if there is a payroll report that was not filed in Q3, you might not receive a letter about the failure to file (and penalty) until Q1 of next year.

    One of the reasons for the slowness is the reliance on snail mail. It can take weeks to post the mail then more time to deliver it and yet more time for someone to check it.


  • Physical Mail Is Essential to Staying Compliant

    Sometimes the only way to know there is a problem is by receiving a letter in the mail from a state agency. This makes mail essential to staying compliant—you can’t fix the issue if you don’t know about the issue.

    Unfortunately, mail is difficult to manage for multi-state businesses. They need to consistently use a mailing address everywhere they register. They need to make sure they actually check the mail. They need to make sure the right mail gets to the right person to take action.


  • Favor Full Time Employees Over Part Time Contractors

    In the early days of a startup, hiring the early team is one of the biggest challenges. It can be tempting to hire contractors and part-time workers to get some help in the short term.

    This is not a good idea because they won’t have skin in the game. Part-time employees won’t have enough time to take over any important responsibilities leaving you to do them. You won’t control the schedule of independent contractors so it’s more difficult to plan and execute. Part-time workers and contractors can also leave suddenly which is disruptive and generates more work to replace them.

    Full time employees care more. They’ve hitched their career prospects to your startup. By taking added risk, they have more to lose if things don’t go well. This is an important advantage of early-stage startups—the most effective people care a lot.


  • How to Write Software Fast

    There is a noticeable difference between the speed of the most productive software engineers I’ve worked with and the slowest. What do they do that others don’t? Is it possible to learn how to be faster?

    Speed is easy to dismiss as unimportant for knowledge work (thinking is often the limiting factor), but that we can’t go faster or trying to wouldn’t be valuable.

    Reduce friction to thinking

    Software engineering is often a ‘shots on goal’ endeavor—the more attempts you can make in the same amount of time, the more progress you will make.

    It should be easy to write some code and run it. How much friction exists in your setup that makes it difficult to run code? Tiny pieces of automation and muscle memory play a factor (e.g. checkout branch, open a file, execute just the code you are working on, stubbing out data, etc.).

    Reps not years of experience

    Solving problems quickly benefits from having seen and solved many problems, but don’t conflate ‘seen many things’ as ‘number of years of experience’. You’ve probably worked with people that have decades of experience that are below average in productivity.

    The way to get experience is to build many things. I don’t know of any shortcuts to learning by doing other than to have side projects and really try to build them out.

    Be decisive

    When faced with a new problem, you can cut down on time by doing a quick breadth-first search (what solutions are available) then being decisive about a path to go down. So much time is lost by not being decisive.

    Execute quickly and leverage your tools

    Here’s where being in the top percentile of proficiency in your local development environment and programming language pays off. Code is very easy to change and you don’t need to be perfect until you hit production. Being really fast at expressing the solution will help you iterate through each sub problem quickly. The ability to think through code looks effortless from the outside because the distance between what’s in your head and what gets implemented is so small.

    A good heuristic for when you’ve reached this kind of proficiency is when others comment about feeling nauseous watching you code.

    See also: