Thursday, February 23, 2023

Expectations

The secret to not going crazy or burning out while working on a large development project is to control expectations.

Software development always takes time. But these days it is usually extremely rushed, which is bad. An endless game of hurry-up-and-wait.

If you are stuck as a developer in the middle of this game, and you are entirely reactive, you will take a lot of nasty bumps and bruises; it will not be pleasant.

So there are a bunch of things we want to do to make our own experiences better.

First is that we want to disconnect the development from the domain's hurry-up-and-wait behaviors. A good development shop is smooth. It picks a reasonable pace and just keeps working at that pace. It makes life far more pleasant and bearable. You think better under less stress.

But that is not how the users and stakeholders generally operate. They lurch from drama to drama, diving into any development issues in between, when they have the time, thus causing constant changes in priorities, focus, and work. Disconnect from that.

You can’t disconnect if they don’t trust you. In fact, if they don’t trust you what happens is that when they are focused in your direction they will tend to micromanage everything, causing even more problems. You don’t want that, so you really want them to trust you instead.

Trust is a 2-way street. They won’t trust you if you bullshit or lie to them. So don’t, even when it seems embarrassing. Be really honest and straightforward.

If they are asking for something that will go wrong, tell them it will go wrong. If they insist on doing it anyways, remind them that it will go wrong, but then do it as they asked. If you can, prepare a rollback or a plan B or something. When it does go wrong, don’t say “I told you so”. Don't belabor the point, don’t even make a big deal out of it. If you had an alternative, suggest that, and lightly try to convince them that it will help them recover.

It may take a few dozen times through a bunch of messes, but if you are honest, doing the things that they wanted, and are there to help them when it doesn’t work out as planned, gradually they will start trusting you. Which is what you need.

Once they trust you, you can spend a little bit of effort explaining non-functional requirements like technical debt, and how it is important to clean up. A clean shop is an efficient shop. You probably still won’t get very much time for that during any of the crunches, but in between, you can redirect most effort over to making things better. This is where you figure out how to keep working in a smooth manner, even though the users are wobbling.

In time, if things are going well you can start looking ahead and even proactively anticipate the incoming work and overall direction. If you are paying attention to why they are getting bounced around, you probably understand a lot of the friction and angst that they are facing, You can work that into your plans, to make their lives better too. Obviously, if you manage to do that, they will be very appreciative.

When they trust you, you are able to set their expectations to reasonable levels. In doing that, you should be able to get them to understand how to match the resources to the work. With that in place, you can make sure things go smoothly, that the development is as pleasant as it can be, and that the quality is as good as the resources will allow. Basically, work is no longer hell.

It’s worth pointing out that you really can’t build new things sanely in a totally reactive state. Construction always involves some amount of proactive behavior, otherwise, you’ll just end up redoing at least an exponentially larger amount of work, or the quality will totally bottom out. You don’t want to do poor or unnecessary work and you will never have the time or resources to match exponential growth. So while some reactivity is often necessary and can even be good sometimes, overdoing it is a recipe for disaster.

Thursday, February 16, 2023

Velimus Insitum Spectare Futurum

The strongest programmers I know all visualize the code that they are about to write, before sitting down and writing it. They see it first.

I doubt that their visualizations are similar, but they can see in their imaginations the various parts of the machinery that they are about to create, and they can walk through it in their heads as it runs.

There are lots of different ways to visualize code. You can see it as data flowing everywhere, or mechanic contraptions all interacting with each other. You might see it from the user’s point of view, or imagine the CPU instructions flying by underneath.

Programmers that can see the code they are writing are able to clean up those visualizations in their heads first, before committing them to their editors. It’s sort of like working out the plot of a novel before sitting down to write it.

This usually means that the code is a lot cleaner and better organized. You can see it in their output.

On the other side, you can definitely see when a coder is flailing at their work or going at it blindly. So, you can tell from the work someone has done, how well they understand the work they were doing. The confusion or lack of it comes through strongly.

Visualizing is a form of implicit planning. If you see it, you know how big it is, what the pieces are, and roughly how long it will take you to get done.

It’s a critical skill necessary to mastering programming. It seems to come more naturally to some people, but for everyone, it improves with a lot of practice. So, rather obviously, if you want to get better at it, you need to do more of it.

Thursday, February 9, 2023

Finding Friction

If you have to do something again, it should be fairly simple and straightforward to get it done. It’s not a one-off, it is reoccurring, at least twice now.

It’s not surprising that doing something the first time can be onerous. But if it is something that repeats, even if the frequency is low and the time between doing it is months, it should not be held back by a lot of friction.

So, figure out why it is not simple. Are there too many steps? Can some of these be combined?

Figure out why it is not straightforward. What are the blockers? Why are they blocking stuff?

For repeating actions, you should always be able to put together a checklist of the things that are necessary. That doesn’t include dependencies or paralleling it, or how they interact. Just the entire list of every little thing that needs to get done. To really find friction though, you need to get every little thing in there, so matter how tiny, even if it is trivial like sending emails or changing a file.

That list is where you start when removing friction. Are there things there that are unnecessary? Get rid of them. Are there things there that can be done less frequently? Reduce them. Are there things that are missing that make the endeavor riskier than it needs to be? Add them in.

Focus on the core of what needs to get done, then throw away everything unnecessary. Break the list into two different categories, one for the actual stuff, and the other for any tracking of that stuff. Is the tracking redundant? Is the tracking itself really getting used for tracking? Throw away as much as possible. Minimize the tracking, track only important or key items. Any and all tracking is both expensive and easily gamed, so it should only be carefully included, not arbitrarily tossed around.

Once you’ve pared down the essential list, and the tracking list, you have a good idea of what you have to do, how long it will take, and the expense of actually tracking it.

From this revised list you can know that it is as small as you can make it, but also you can probably use a computer to automate a lot of it, nearly as it is laid out. Automation will need to consider the dependencies, but often that isn’t very tricky unless you are trying to optimize it to be concurrent.

One of the core goals for any type of endeavor should always be to remove as much friction as possible. Doing that and minimizing Yak Shaving will give you a stable capacity to get things done. Being able to do things faster and easier is the first step in trying to do them better.

Thursday, February 2, 2023

Finding Intrinsic Complexity

Complexity should scale.

If it does, then simple things are easy and complex things are hard.

If, when it is simple, there is some degree of extra complexity that is making it hard, then it is likely artificial complexity that can and should be removed somehow.

Reducing complexity is tricky. You can reduce it by hiding it, but while that pulls it out of focus and encapsulates it elsewhere, it does not reduce the overall complexity.

You can reduce complexity by normalizing. That works really well, but if you take it too far, while the complexity is gone, it is harder for humans to understand it. We seem to have our own necessary baseline for intrinsic complexity.

If there are ‘gaps’ and ‘overlaps’, they add artificial complexity, but for ‘gaps’ they seem to be indirect complexity. It’s not what is there, but instead what is missing, so a negative form of complexity.

Some artificial complexity is redundant. You can remove it without change to the surroundings. That is the easiest form of complexity to remove.

If you are going to optimize the complexity of something, you would start with simple examples and reduce them as much as possible. Then gradually scale it up to the extremes, while ensuring that the associated complexity scales in a similar manner.