John Obelenus
Solving Problems & Saving Time through Software and Crushing Entropy
Whenever someone uses the acronym MVP, Minimum Viable Product, I feel that we should make them explain what they are actually talking about. There are lots of things folks call an MVP, that totally miss the point. Here are a few humorous ones I’ve encountered:
And then of course there is the engineer backlash against MVP concepts, which is totally justified:
Okay so we’re gonna do the mvp of this bridge. Just enough engineering to stand it up. Once we get a few thousand cars going over it a day we will hopefully get a seed round and go back and fix the tech debt
— Scott C. Reynolds - My Name is Already Fairly Long (@scottcreynolds) February 14, 2019
And then of course, this graphic, which kicked off a giant bike-shedding session:
Engineers were talking about how neither of these two sequences “are really an MVP”. I think they’re wrong. Here is why: the second sequence does not describe the “MVP of a car”. It describes the MVP of “how can I get people to buy a transportation product to go from A—>B”. You don’t even know if people will pay to go from A—>B, so don’t build a car. Build a skateboard, on the cheap, and see if you can market that as the solution that people will buy. Once you’ve proven they will pay for a solution to the problem then you can start building more expensive things.
For Scott, talking about building a bridge, the MVP of building a bridge is not a smaller bridge made out of duct tape. The MVP of a bridge is probably a row boat. Then a ferry. Then a bridge. If you look at history that is, quite literally, how many bridges came into being. In both Boston and New York the bridges across their respective rivers were only built after ferry services had operated for decades showing that if the cities wanted to build a bridge, it wouldn’t go to waste. Obviously the financing was different—but imagine being a politician who puts forward a public works project like a bridge with the associated tax to build it without proving its what people want?
Minimum viable products are not “the smaller version of the real thing.” They are not “what I can afford right now.” MVPs are the testing of a theory. Testing a theory should not be expensive. And you don’t even need a full blown application to test a theory. You can literally use excel if you have to; or something else, it doesn’t matter.
We engineers get confused thinking that people actually give a crap about the technology that goes into what they buy. They don’t. They buy solutions to their problems. If you are offering a service, and use excel to fulfill it, customers don’t care. They won’t wince. They won’t go to the next shiny application. If you solve their problem well, at a price they are willing to pay then you have tested the theory that someone will pay for that service. That is all an MVP really is.
Craigslist is a real-world example. What was the MVP for his website? An email newsletter. Not even close to the same thing. Not scalable. Not automated. But it proved that he could get eyeballs for classifieds on the internet.
I propose that we come up with different terms for the other things that people are using MVP.
Read more: MVP means lots of different things.
Everywhere I turn today there is something about agile. Lots of agile acronyms and names I’ve never heard before. People look at me like I’m supposed to know that one. And that other one, too. Who has time for all this agile?
I remember hearing about the agile manifesto a few years after it came out. It isn’t full of process declarations like some folks are telling me about the new WhizBang agile they’re doing. What happened?
Martin Fowler’s gave a talk this past year, that was mostly about his reaction to the last fifteen years. He calls it the “Agile Industrial Complex.” There are a million different practices that call themselves agile, some of which—according to him—ought to be called “faux agile”. Frankly he gets the right to make that call.
Fowler added that he finds himself, and those pushing some form of agile, complicit in all this. He stepped up to address it and fight for the spirit of agile, for the principles they stood for when they penned their manifesto.
Agile’s bottom line is actually about the business of management. Its first principle is: self-organizing teams. So, when a large organization decides to “adopt agile” and change over their titles and processes all the employees are now subject to a process foisted upon them. I would not call that“self-organizing”. Agile was precisely a reaction against that sort of management. It was making sure that those engineers who were doing the actual work were deeply involved in the conversations about what work was important, and how it ought to be solved, and what success actually looked like.
Agile was not intended to be another layer of management. It was not meant to be the next process that got management a higher quality Gantt chart. Furthermore, agile has very little at all to do with technology or software at all! There is even a quote from signatory, Chad Fowler (no relation), way back in 2002:
Agile methods are less about software construction and more about humans working together and communicating. No matter what field you’re in, there’s something to learn here.
Here is an mental exercise as proof—swap “software” throughout the manifesto text with any other noun you’d like. Go ahead, I’ll wait.
Agile has nothing to do with the career, calling, craft, or enter any adjective you’d prefer, of being a good Software Engineer. Agile is about the business of management. Furthermore it is about Engineers being directly involved in management. Anything less than that should not, according to the manifesto, be called “Agile”.
Python core development will never “be agile”. New architecture styles (e.g. distributed event platforms like Kafka, or distributed column stores like Scuba/Retriever) have nothing to do with agile. V8 engine core improvements have nothing to do with agile. The next version of ReactJS will not be built using agile techniques. The creation of distributed Map-Reduce at Google had nothing to do with agile. The firmware that ends up on your HDD chipset or BIOS or motherboard will never have anything to do with agile. Neither will your printer or USB drivers. Problems that are highly technical have nothing to do with agile. Software that inherently takes a long time to make because the problem is brand new at a scale we have not encountered before has nothing to do with agile.
If you follow any of those projects listed, or any other projects I could have possibly listed, just because they “aren’t agile” doesn’t make them “bad”. I don’t even know what that statement would mean—it is a category error. Just because it “isn’t agile” does not mean that they aren’t pivoting to more important problems to solve as things come up. It doesn’t mean that they’re not listening to their users. Meanwhile, these projects that are open source are, in fact, self-organizing teams. Teams made up of only Engineers. [Aside: if that doesn’t fit the definition of agile according to the manifesto I don’t know what does. But I doubt anyone on these projects would ever self-describe them as “agile”, so we also shouldn’t force the term onto them.]
Agile has a purpose, and I applaud it. But let’s not be religious; it’s not for everything. It is not a universal fix you apply. It isn’t a checkbox on a list that needs to be marked. Don’t turn to Agile as a savior. Only an organization interested in maturing can succeed at being self-organizing and involving Engineering in business decisions.
Read more: Lots of $%&#! Agile
I trust that every Engineer, in every one of their jobs, has had this moment: “Why didn’t anyone write down why this…” And there are a lot of ways that sentence can end. I’m focused on the first part. Engineers actually don’t like to write things down.
I was having a conversation with a CTO about documentation. He readily admitted that yea, there is less than he’d like. And then he admitted something that surprised me: people are bad writers, they just don’t do it well. If you don’t do something well, you avoid it.
In a very real way, programming is writing. You have two audiences, one is the compiler, and the second audience is the other humans that are going to have to deal with your creation. In all our proper education we focus on writing for the compiler. Yes, there is now a focus on “clean code”, style, and making your code expressive. But its always secondary—because if your code doesn’t run, no one cares if they can read it.
We’ve been given a stereotype of the nerdy computer programmer, unsociable, frustrated, incapable of interacting with anything except a computer. They live in basements, in the dark, banging on keyboards, working alone, creating amazingly important things. The solo hero. Its a false stereotype. It is harmful for others to believe this about us. It is harmful for us to believe this is the highest ideal for ourselves: “Everyone get out of my way, you cannot comprehend by power (and I certainly cannot communicate it to you)!”
I honestly believe if we Engineers were better writers our code quality would improve. Few engineers focus on improving their writing (Hey, I’m trying here)!
I’ve been thinking about the state of the industry as a whole. Why have we been unable thus far to mimic other construction and engineering industries; creating interoperable and re-usable building blocks. After all, that is how our computers themselves get built. Software vendors and platforms are nothing at all like going to a lumber yard, RadioShack, or Home Depot, where you can show up with specs and walk out with what you need knowing it will work.
Maybe, if programming is more similar to writing than we are willing to admit—the industry will never get there. After all, what interoperable and re-usable building blocks do writers have? None that I can think of. Maybe, just maybe, that is what distinguishes an Engineer from a programmer. Their ability to communicate in writing.
Read more: Why Don’t Engineers Write?
I overheard a story while on vacation recently. A guy who works in the healthcare space was talking with some folks about how a single large healthcare company in Pittsburgh spent $57 million dollars in a year on IT alone. I honestly don’t remember the name of the company, I did not recognize it.
He was astonished by this stat, and kept talking about. He was talking loudly, and I was right next to them. I leaned across to the group and said: “It sounds like you’re having an interesting conversation. But, that number doesn’t surprise me.” I introduced myself and listened to a bit more of his story and surprise.
He asked me why I wasn’t surprised. I explained that I am an Engineer, and first of all, we’re still learning how to build things. But when we decide to really build something—and we know what we’re building—we do a great job. I explained that, from my perspective is, too many people still view computers as magic. Especially in a corporate setting like Healthcare IT (I’m not just picking on healthcare though, it is all of them).
There are lots of buyers, and both IT and software companies are more than happy to charge a premium. I’m not saying the VP signing a check needs to know how network layer protocol is organized, or the difference in the latest chipsets and north bridges, or how quickly an L3 cache hit runs, or the failure rate of SSD blocks. They do need to learn how to use computers to their advantage, rather than having the computer and software run the show. The tail is absolutely wagging the dog.
Don’t get me wrong—I am actually far more in “Buy” territory when it comes to “Buy vs Build”—but I am amazed at the overlap in systems that do similar things, and you’ve bought 4 or 5 of them, because there is one indispensable thing each one does that none of the others do.
And as Joel Spolsky shared fourteen (14!) years ago, once you sell software over a specific dollar limit, you need budgetary line-items. Which means lots of meetings, salespeople, and overhead, just to get a sale.
Yea, there is a lot of waste here. Some of it is because we do a very bad job of exposing just what our software can and should do. I can’t tell you how many times I’ve had to click around a new software vendor’s site for 30 minutes before I get past the marketing jargon to see; “Oh, so thats what this does? I don’t need this after all.” And the only reason I know I don’t need it is because I am an engineer.
God help everyone who has to make sense of the world of IT without being an engineer. It will cost you $57 million dollars.
Read more: A 57 Million Dollar Story
I’ve had the good fortune to be able to volunteer some of my time to mentoring a few folks at Resilient Coders who are in the process of becoming Full Stack Developers (It is a fantastic organization, and if you’re in Boston you should take a moment and check them out). Working with people who are at the beginning of learning to code has been immensely refreshing.
First, I am old. And that means I really don’t remember when I “learned how to code”. I know that it happened. Over a long period of time. And I know that if I were able to look at work I did a decade ago I would be ashamed. That is a good thing in my view—it means I’m growing, I’m still walking forward on the road. (There were definitely times I took a “break” and sat down on the roadside for a while without growing.)
As my mind wandered onto my own learning-to-code journey, I wanted to write down my signposts that marked my periods of growth. Your mileage may vary—and I would love to hear your experiences in the comments.
This is the first critical step, and its something I talk about with those I’ve been helping. When you’re stuck, you start searching for answers. Rarely will you find something you can truly copy & paste into your editor and it just works. There comes a moment when you know: “Hey, this isn’t exactly what I need, but, it taught me something and now I know how to fix it.” That is a moment every engineer needs to have. We’re not built with it, even if you don’t remember when it happened to you.
It signals that they can fully learn by themselves. Without that ability its very hard to grow.
It’s one thing to hack something together and make it work. And then clean it up and refactor it after the fact into something you’re comfortable attaching your name to for general consumption. But it is something different to be thinking about abstraction, cleanliness, separation of concerns, and enter any-of-the-things-you-find-most-important before you’ve made it fully work.
It signals that they are comfortable in their environment, confident in their ability, and can break down a problem into its constituent parts.
When you have a job as an engineer at some point someone brings you either a written spec or has a requirements meeting. As you’re talking about all this new information, and before imagining what code you’ll need to write looks like, you’re thinking “What is X, really?” and “How does it relate to Y?” You start assigning concepts (like Dictionaries, Lists, Graphs, Trees, Enums, etc) to real world requirements.
It signals that they understand what we’re really doing here; attempting to contain and transform the real world into digital relationships. Their focus at this level is an understanding that making a poor choice here results in greater catastrophe down the road.
When we stare at a blank editor, unable to type—or we just start moving code around like peas on a dinner plate you do not want to eat—we’re not sure what is next. It is a magical feeling when you can just sit down, open the editor, and start typing and the program unfolds itself before you. You’ve already got the next 20 lines in your head ready to go as you’re finishing your function. As you tweak one part of the code, you instinctively fly over to another part to make a required corresponding change so that it all works together.
This is a second level of development in breaking down the problem into smaller parts—it signals that not only have you broken it down, but that you can also hold all the parts in your head, together, intimately aware of their relationship to one another.
There comes a time when we are looked to for optimizing performance. We go back over our code, measure it, trace it, and profile it, using various tools and come up with changes to make it faster, and better. We make the changes and whoever came over whining about a spinning pinwheel, or waiting for the browser to load something is happy again.
There comes a time when we start working on bigger systems; with more data, and with more users. Where you can’t just ask someone to delineate how many things your system is responsible for—because no one could know all of that. Where changing a behavior in one part of your system has drastic effects on another part. This is when the systems you’re working on greater resemble a living organism; because it is not merely a determinative system anymore, the actions of the users have a greater effect on what happens.
This is an area in my career I am happy to have entered. I am realizing that as these systems get bigger we have to start worrying about smaller and smaller things. When we are designing and coding systems I find that I am exploring how I can leverage the power of processes and threads, and choosing where the computing work is done. I find that I am choosing different techniques in order to not spend memory I do not need to, rather than what would come naturally. I’m doing this because I have a big system, with lots of data, and limited resources. A bottleneck, or even sluggish performance, in one area will have a greater effect on the system as a whole.
I can’t wait to see what the next signposts on the road are.
Read more: Signposts on the Road