Front-End: Declarative vs Objective-Orientated

26 Mar 2020

I've always been far more of a programmer than a designer. I don't think I've ever personally liked anything I've designed on the web. It's been good enough, sometimes, and other times not so much. But I find myself squarely on the side of the designers on this one.

First off, CSS is a programming language. Full stop. If you don't think so, you're part of the problem. What designers have been able to do with this declarative programming on the front-end is nothing short of amazing. I've written CSS files with hundreds, and even a thousand, lines, that does the same work these masters can do in a tenth as many lines. People like Andy Bell, Heydon Pickering, and many others.

The React folks of the world have, quite naturally, come to the conclusion that object-oriented encapsulated components are the one true, best, and only way to build designs on the front-end. For logic—that may be true, but for design I think this is patently false. Once you believe this you start writing things like this: "Margin considered harmful" and making things infinitely more complicated, just to keep the precious components.

CSS rules are not meant to be encapsulated. Why not? Because it is a declarative language. SQL works the same way. There are absolutely exceptions to the rule where you do want that, but you don't optimize for exceptions. You allow them to happen. Which CSS does on its own perfectly well. There are certainly things we can do that make it easier on the developer and leverage CSS (looking at you Svelte). CSS-in-JS is optimizing for exceptions and breaking CSS in order to have encapsulation.

Rather than refusing to use only margin (or only padding, or only X) in your CSS components, why don't you get the CSS out of JS entirely. Learn from the masters about how to use CSS properly.

CSS is not an object orientated language. So let's not try and shove it into that box. Not only does it result in poor developer experience that you need to twist yourself into knots, it results in a massive proliferation of rules that both increase the payload size of our applications, and slows down the browser performance.

Read more: Front-End: Declarative vs Objective-Orientated

Reading Isn't Enough

13 Mar 2020

This is a trap that I fall into. I like reading, I've got a list of books I want to read. I learn from reading. But Engineer, even Software Engineering, is something you only really learn by doing.

You can read all the documentation. You can read an entire codebase. And you will understand a good portion of it. But you won't really know it, how it works, or it's limitations.

I often start new projects or features by trying to read as much as I can. I try to find a path through the jungle and see the end before I start. Depending on what the work is that can be quick...or not.

Sometimes I don't get my hands dirty early enough, in a classic turn of phrase from Joel Spolsky, to launch the damn editor. Because this is a field where you learn by doing, not by reading.

Read more: Reading Isn't Enough

Code As Communication

20 Feb 2020

I'm fond of saying that code has no value until it is running in production. I still believe that is a correct and important statement. But I want to qualify that statement to say that code has no performative value until it is running in production. No one's job is complete, its not "done" until its running in prod.

But there is another value in written code: communication. There comes a time when you have written the one pagers. You've written more detailed documentation and plans on what you're going to do. And you've had the meetings to discuss all of these ideas. But sometimes you still don't have traction with the folks involved. People seem to still not be on the same page. To use an aviation metaphor—you're trying to take off and there is a lot of drag slowing you down from reaching takeoff velocity.

Start writing code. Don't even try and run it. Create a draft pull request. Keep writing code and increase your code coverage on the topic. There is communication value in non-running code. It can get people past whatever the mental blocks are.

Read more: Code As Communication

Engineering Speed is a Symptom

1 Feb 2020

I think the speed of a team is the result of a function, it is the symptom of a working environment. It doesn’t happen by simply standing up and demanding that people work faster. Engineering teams deliver quickly when they have confidence. I don’t mean individual self-confidence, or a level on Maslow’s hierarchy of needs. And I certainly don’t mean the overconfidence of someone’s ego. That function is transferable experience of production systems, that results in engineering speed. A working environment is one that produces this transferable experience in engineers.

This is what my experience as a Technical Lead has taught me. Each individual has their own baseline, and their own limits. Not everyone shows up to work together starting in the same mental place. And not every company needs the same pace—a seed startup and a publicly traded company need different pieces at different speeds. There are always impediments and roadblocks that slow anyone down. Confidence comes from experience, and the experiences required, I think, are very specific. You know people have the right kind of experience its transferable. That means they come into a new scenario confident—and deliver on that confidence. But first I want to talk about what I believe are red-herrings.

Here are two things everyone thinks you absolutely need in order to go fast. There is no doubt these things help, but they are not required—that is a myth. Whether you have these or not you still need confidence that comes from experience. Neither of these give you experience or confidence.

Tests & CI/CD systems

Test coverage is a hotly debated topic. How much should coverage should you have? What does it mean when you have X% coverage? How do you know it is enough, or not enough? How long is too long for your test suite to run before it starts slowing your people and processes down? Unit tests prove one thing, that a highly specific input for an isolated piece of code results in a highly specific output. There is zero doubt that is useful in certain times and places.

But as the bugs grow the number of test cases grows. As the codebase grows the test cases and the number of bugs grow. That doesn’t sound fast, or that it scales, to me. I’ve seen teams that have a lot of tests and these teams still move slowly, because they aren’t confident in what their system is doing and therefore are unsure how to keep moving forward.

Having a CI/CD system doesn’t necessarily give you confidence either. It is definitely helpful that the deployment of code is according to a consistent process, if only that it saves a human time and removes some possibilities of human error. It is a tool, just because you use a tool doesn’t mean you’re a confident craftsman.

Staging environments that match production

Once a system reaches sufficient complexity no other environment can ever match the real live environment. It doesn’t matter if you’ve set it up exactly the same way. It doesn’t have the same traffic, and it doesn’t have the same random collisions of events that are the ones that cause problems in production. I don’t understand why people think they cannot live without a fully-matching-prod staging environment for day-to-day operations. There is no doubt it is useful for certain things at certain times. But staging environments do not bring that much difference from working on your laptop. That is a learning curve that happens pretty quickly during engineering, and then it plateaus. Forever. Therefore staging doesn’t bring confidence.

These three things are so common I am sure people cannot imagine living without them. Someone who has had these tools ought to be able to live without them. Why? Because their level of confidence isn’t given to them by these tools. At times these tools can help them gain confidence, but it is never the fundamental piece. These tools give you false confidence. You can spot the difference between false confidence: teams still move slowly, and are worried about making changes.

We need to understand the reality of our systems

There is nothing that is at all like your production system. Nothing approaches behaving like it. The only way to gain the experience that will make you confident is by living in your production system. Unit tests bear almost zero resemblance to production. Poking around with features based on old data on staging is not living in prod either.

Living in prod means watching users use your system. Whether that is standing over the shoulder of users (if you can be so lucky), or having enough observability to determine what is really happening. Standard monitoring that tells you your P95 is ~200ms is not enough. Outliers matter, because the outliers are real users having real problems that are going to complain about your product on twitter. They are going to stop using it, and stop paying for it one day.

Living in prod means knowing what your system is actually designed to do, and knowing how it works. I’ve been shying away from high-level abstractions and large dependencies more and more these days. Especially ones I don’t control or deeply understand. The more you understand about the fundamentals of your system the more confidence you’ll have. Who knows when the next left-pad exploit is going to hit your system—make sure you’re depending on things you need, and understand.

Defensive code that runs in prod is more important than unit tests. As a tech lead I find that I am writing more code to do tasks I’ve done before. Why? I am writing code that is noisy and fast to debug in production because I have a team to support. My job is not to write as much code as I can. Now my job is about communicating and being an example. Communicating examples of failure in production is extremely valuable information for my team. Especially when I may not be the one supporting a particular piece of code in the future.

The big reason that trunk-based development and continuously shipping small changes are rising in popularity is because when you make small changes you ought to know exactly what should change in your system. And you better be watching your system after you ship to make sure that it changed, and it is the only thing that changed. Observing what you ship brings confidence. Your CI/CD system is pretty useless when you work on long-lived branches and ship a lot of changes at once. Your tool is sitting idle most of the time. That does not instill confidence.

Confidence is not about intelligence. It is about experience. Usually people get experience through pure time on the ground. But that takes a long time, and plateaus quickly unless that person gets involved in every different part of the org and code. If you put that person in a new place how much of their experience is transferable? Almost none of it, and they quickly lose any confidence they’ve built up.

Read more: Engineering Speed is a Symptom

My Own (New) Management Reflections

14 Jan 2020

I'm nearing the six month mark in my $latestGig, and my role has turned into a product and people management role. I was hoping this would happen, but not before I got to fully build something myself. Such is life, ruining a well formulated plan.

I've done the customer-facing part of Product Management before as a consultant. But this time around I have learned that Product management is as much about getting alignment and agreement within your org about what to build as it is with users. There is less convincing required, but more prodding for the answer to: "And how does this effect you and your department's plans?" Of course this one runs both ways. Announced changes require getting involved to make sure that your services are still receiving everything they need, especially with new rollouts.

I haven't had a chance to manage people yet, and I'm excited for the new challenge. In the short few weeks I'm focused on communicating our team goals for the quarter, establishing expectations, and staying out in front of the team both in terms of toil and getting them all the definition and details they'll need to keep working without delay.

Over the last few years I've been less and less interested in what happens inside the black box that is the computer. I've become far more interested in how much a well-running team can really achieve. I'm interested in what structures you can engineer that are going to change the landscape for your team, department, and customers.

Read more: My Own (New) Management Reflections